00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00029 #include <unistd.h>
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032 #include <signal.h>
00033 #include <fcntl.h>
00034 #include <sys/uio.h>
00035 #include <errno.h>
00036 #include <sys/types.h>
00037 #include <sys/socket.h>
00038 #include <sys/stat.h>
00039
00040
00041 #include <time.h>
00042 #include <string.h>
00043
00044 #include <netinet/in.h>
00045 #include <sys/mman.h>
00046 #include <sys/ioctl.h>
00047
00048 #include <asm/elphel/c313a.h>
00049 #include <asm/elphel/ext353.h>
00050 #include <asm/byteorder.h>
00051
00052
00053 #include <ogg/ogg.h>
00054 #include "ogmstreams.h"
00055
00056 #include "camogm_ogm.h"
00057 #include "camogm.h"
00059 int camogm_init_ogm(void) {
00060 return 0;
00061 }
00062 void camogm_free_ogm(void) {
00063 }
00064
00065
00066 int camogm_start_ogm(void) {
00067 char vendor[]= "ElphelOgm v 0.1";
00068 int pos;
00069 stream_header sh;
00070 char hdbuf[sizeof(sh)+1];
00071 ogg_packet ogg_header;
00072 sprintf(state->path,"%s%010ld_%06ld.ogm",state->path_prefix,state->frame_params.timestamp_sec,state->frame_params.timestamp_usec);
00073 if (!((state->vf=fopen(state->path,"w+"))) ){
00074 D0(fprintf (debug_file, "Error opening %s for writing\n", state->path));
00075 return -CAMOGM_FRAME_FILE_ERR;
00076 }
00077 ogg_stream_init(&(state->os), state->serialno);
00078 state->packetno = 0;
00079 memset(&sh, 0, sizeof(stream_header));
00080 memcpy(sh.streamtype,"video",5);
00081 memcpy(sh.subtype, "MJPG", 4);
00082 put_uint32(&sh.size, sizeof(sh));
00083
00084 put_uint64(&sh.time_unit, state->time_unit);
00085
00086 put_uint64(&sh.samples_per_unit, (ogg_int64_t) state->timescale);
00087 put_uint32(&sh.default_len, 1);
00088 put_uint32(&sh.buffersize, state->width*state->height);
00089
00090 put_uint16(&sh.bits_per_sample, 0);
00091 put_uint32(&sh.sh.video.width, state->width);
00092 put_uint32(&sh.sh.video.height, state->height);
00093 memcpy(&hdbuf[1], &sh, sizeof(sh));
00094 hdbuf[0]=1;
00096 ogg_header.packet = hdbuf;
00097 ogg_header.bytes = sizeof(sh)+1;
00098 ogg_header.b_o_s = 1;
00099 ogg_header.e_o_s = 0;
00100 ogg_header.packetno = state->packetno++;;
00101 ogg_header.granulepos =0;
00102 ogg_stream_packetin(&(state->os), &ogg_header);
00103
00104
00105 while(ogg_stream_flush(&(state->os), &(state->og))) {
00106 int i, j;
00107 if ((((i = fwrite(state->og.header, 1, state->og.header_len, state->vf))) != state->og.header_len) ||
00108 (state->og.body_len && (((i = fwrite(state->og.body, 1, state->og.body_len, state->vf))) != state->og.body_len))) {
00109 j=errno;
00110 D2(fprintf(debug_file,"\n%d %ld %ld\n",i,state->og.header_len,state->og.body_len));
00111 return -CAMOGM_FRAME_FILE_ERR;
00112 }
00113 }
00114
00117 memset(hdbuf, 0, sizeof(hdbuf));
00118 hdbuf[0]=PACKET_TYPE_COMMENT;
00119 memcpy(&hdbuf[1], "vorbis",6);
00120 pos=7;
00121 put_uint32(&hdbuf[pos], strlen(vendor));
00122 pos += 4;
00123 strcpy(&hdbuf[pos], vendor);
00124 pos += strlen(vendor);
00125 put_uint32(&hdbuf[pos], 0);
00126 pos += 4;
00127 hdbuf[pos++] = 1;
00129 ogg_header.packet = hdbuf;
00130 ogg_header.bytes = pos;
00131 ogg_header.b_o_s = 0;
00132 ogg_header.e_o_s = 0;
00133 ogg_header.packetno = state->packetno++;;
00134 ogg_header.granulepos = 0;
00135 ogg_stream_packetin(&(state->os), &ogg_header);
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00149 state->granulepos= (ogg_int64_t) ( (((double) state->frame_params.timestamp_usec)+
00150 (((double) 1000000) * ((double)state->frame_params.timestamp_sec))) *
00151 ((double) 10) /
00152 ((double) state->time_unit) *
00153 ((double) state->timescale));
00154
00155
00156
00157
00159 state->granulepos=0;
00160
00162 return 0;
00163 }
00164
00165 int camogm_frame_ogm(void){
00166 int indx;
00167 elph_ogg_packet elp_packet;
00168 elp_packet.bytes= 0;
00169 for (indx=0; indx<state->chunk_index; indx++) elp_packet.bytes+=state->packetchunks[indx].bytes;
00170 elp_packet.packet=state->packetchunks;
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 elp_packet.b_o_s = 0;
00188 elp_packet.e_o_s = 0;
00189 elp_packet.packetno = state->packetno++;;
00190
00191
00192 elp_packet.granulepos=state->granulepos;
00194 state->granulepos+= (ogg_int64_t) state->timescale;
00195
00196
00197 ogg_stream_packetin_elph(&(state->os), &elp_packet);
00198
00199 while(ogg_stream_pageout(&(state->os), &(state->og))) {
00200 int i,j;
00201 if ((((i = fwrite(state->og.header, 1, state->og.header_len, state->vf))) != state->og.header_len) ||
00202 (state->og.body_len && (((i = fwrite(state->og.body, 1, state->og.body_len, state->vf))) != state->og.body_len))) {
00203 j=errno;
00204 D0(fprintf(debug_file,"\n%d %ld %ld\n",i,state->og.header_len,state->og.body_len));
00205 return -CAMOGM_FRAME_FILE_ERR;
00206 }
00207 }
00208 return 0;
00209 }
00210
00211
00213
00214 int camogm_end_ogm(void){
00216 ogg_packet ogg_header;
00217
00218 ogg_header.packet = NULL;
00219 ogg_header.bytes = 0;
00220 ogg_header.b_o_s = 0;
00221 ogg_header.e_o_s = 1;
00222 ogg_header.packetno = state->packetno++;
00223 ogg_header.granulepos = ++(state->granulepos);
00224 ogg_stream_packetin(&(state->os), &ogg_header);
00225 while(ogg_stream_flush(&(state->os), &(state->og))) {
00226 int i, j;
00227 if ((((i = fwrite(state->og.header, 1, state->og.header_len, state->vf))) != state->og.header_len) ||
00228 (state->og.body_len && (((i = fwrite(state->og.body, 1, state->og.body_len, state->vf))) != state->og.body_len))) {
00229 j=errno;
00230 D0(fprintf(debug_file,"\n%d %ld %ld\n",i,state->og.header_len,state->og.body_len));
00231 return -CAMOGM_FRAME_FILE_ERR;
00232 }
00233 }
00234 return 0;
00235 }
00236
00237
00238