apps/camogm/camogm_ogm.c

Go to the documentation of this file.
00001 /*!***************************************************************************
00002 *! FILE NAME  : camogm_ogm.c
00003 *! DESCRIPTION: Provides writing to ogm files for camogm
00004 *! Copyright (C) 2007 Elphel, Inc.
00005 *! -----------------------------------------------------------------------------**
00006 *!  This program is free software: you can redistribute it and/or modify
00007 *!  it under the terms of the GNU General Public License as published by
00008 *!  the Free Software Foundation, either version 3 of the License, or
00009 *!  (at your option) any later version.
00010 *!
00011 *!  This program is distributed in the hope that it will be useful,
00012 *!  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 *!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 *!  GNU General Public License for more details.
00015 *!
00016 *!  You should have received a copy of the GNU General Public License
00017 *!  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00018 *! -----------------------------------------------------------------------------**
00019 *!
00020 *!  $Log: camogm_ogm.c,v $
00021 *!  Revision 1.2  2007/11/19 03:23:21  elphel
00022 *!  7.1.5.5 Added support for *.mov files in camogm.
00023 *!
00024 *!  Revision 1.1  2007/11/16 08:49:58  elphel
00025 *!  Initial release of camogm - program to record video/image to the camera hard drive (or other storage)
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 //#include <ctype.h>
00040 //#include <getopt.h>
00041 #include <time.h>
00042 #include <string.h>
00043 
00044 #include <netinet/in.h> /*little <-> big endian ?*/
00045 #include <sys/mman.h>           /* mmap */
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> // has to be before ogmstreams.h
00054 #include "ogmstreams.h" // move it to <>?
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 //   put_uint64(&sh.time_unit, (ogg_int64_t) 10*state->frame_period);
00084    put_uint64(&sh.time_unit, state->time_unit);
00085 //   put_uint64(&sh.samples_per_unit, 1);
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 //   put_uint16(&sh.bits_per_sample, 24); //?
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 //   while(ogg_stream_pageout(&(state->os), &(state->og))) {
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    while(ogg_stream_pageout(&(state->os), &(state->og))) {
00138       int i, j;
00139       if ((((i = fwrite(state->og.header, 1, state->og.header_len, state->vf))) != state->og.header_len) ||
00140            (state->og.body_len && (((i = fwrite(state->og.body, 1, state->og.body_len, state->vf))) != state->og.body_len))) {
00141           j=errno;
00142           D(fprintf(debug_file,"\n%d %ld %ld\n",i,state->og.header_len,state->og.body_len));
00143           return -CAMOGM_FRAME_FILE_ERR;
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 //   state->frame_period=(state->this_frame_params.timestamp_usec - state->frame_params.timestamp_usec)+
00155 //               1000000*(state->this_frame_params.timestamp_sec  - state->frame_params.timestamp_sec);
00156 //  put_uint64(&sh.time_unit, (ogg_int64_t)((double)10000000.0 / (double)fps));
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 //D(fprintf (debug_file,"elp_packet.bytes=0x%lx: elp_packet.packet=%p\n",elp_packet.bytes, elp_packet.packet));
00172 /*D(fprintf (debug_file,"0:0x%lx: %p\n" \
00173                              "1:0x%lx: %p\n" \
00174                              "2:0x%lx: %p\n" \
00175                              "3:0x%lx: %p\n" \
00176                              "4:0x%lx: %p\n" \
00177                              "5:0x%lx: %p\n" \
00178                              "6:0x%lx: %p\n", \
00179                               elp_packet.packet[0].bytes,  elp_packet.packet[0].chunk,
00180                               elp_packet.packet[1].bytes,  elp_packet.packet[1].chunk,
00181                               elp_packet.packet[2].bytes,  elp_packet.packet[2].chunk,
00182                               elp_packet.packet[3].bytes,  elp_packet.packet[3].chunk,
00183                               elp_packet.packet[4].bytes,  elp_packet.packet[4].chunk,
00184                               elp_packet.packet[5].bytes,  elp_packet.packet[5].chunk,
00185                               elp_packet.packet[6].bytes,  elp_packet.packet[6].chunk));
00186 */
00187    elp_packet.b_o_s = 0;
00188    elp_packet.e_o_s = 0;
00189    elp_packet.packetno = state->packetno++;;
00190 //   tts[0]=state->frame_params.timestamp_usec;
00191 //   tts[1]=state->frame_params.timestamp_sec;
00192    elp_packet.granulepos=state->granulepos;
00194    state->granulepos+= (ogg_int64_t) state->timescale;
00195 
00196 //D3(fprintf (debug_file,"_121_"));
00197    ogg_stream_packetin_elph(&(state->os), &elp_packet);
00198 //D3(fprintf (debug_file,"_13_"));
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 

Generated on Thu Aug 7 16:18:58 2008 for elphel by  doxygen 1.5.1