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