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.1.1.1  2008/11/27 20:04:01  elphel
00022 *!
00023 *!
00024 *!  Revision 1.2  2007/11/19 03:23:21  elphel
00025 *!  7.1.5.5 Added support for *.mov files in camogm.
00026 *!
00027 *!  Revision 1.1  2007/11/16 08:49:58  elphel
00028 *!  Initial release of camogm - program to record video/image to the camera hard drive (or other storage)
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 //#include <ctype.h>
00043 //#include <getopt.h>
00044 #include <time.h>
00045 #include <string.h>
00046 
00047 #include <netinet/in.h> /*little <-> big endian ?*/
00048 #include <sys/mman.h>           /* mmap */
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> // has to be before ogmstreams.h
00057 #include "ogmstreams.h" // move it to <>?
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 //   put_uint64(&sh.time_unit, (ogg_int64_t) 10*state->frame_period);
00087    put_uint64(&sh.time_unit, state->time_unit);
00088 //   put_uint64(&sh.samples_per_unit, 1);
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 //   put_uint16(&sh.bits_per_sample, 24); //?
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 //   while(ogg_stream_pageout(&(state->os), &(state->og))) {
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    while(ogg_stream_pageout(&(state->os), &(state->og))) {
00141       int i, j;
00142       if ((((i = fwrite(state->og.header, 1, state->og.header_len, state->vf))) != state->og.header_len) ||
00143            (state->og.body_len && (((i = fwrite(state->og.body, 1, state->og.body_len, state->vf))) != state->og.body_len))) {
00144           j=errno;
00145           D(fprintf(debug_file,"\n%d %ld %ld\n",i,state->og.header_len,state->og.body_len));
00146           return -CAMOGM_FRAME_FILE_ERR;
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 //   state->frame_period=(state->this_frame_params.timestamp_usec - state->frame_params.timestamp_usec)+
00158 //               1000000*(state->this_frame_params.timestamp_sec  - state->frame_params.timestamp_sec);
00159 //  put_uint64(&sh.time_unit, (ogg_int64_t)((double)10000000.0 / (double)fps));
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 //D(fprintf (debug_file,"elp_packet.bytes=0x%lx: elp_packet.packet=%p\n",elp_packet.bytes, elp_packet.packet));
00175 /*D(fprintf (debug_file,"0:0x%lx: %p\n" \
00176                              "1:0x%lx: %p\n" \
00177                              "2:0x%lx: %p\n" \
00178                              "3:0x%lx: %p\n" \
00179                              "4:0x%lx: %p\n" \
00180                              "5:0x%lx: %p\n" \
00181                              "6:0x%lx: %p\n", \
00182                               elp_packet.packet[0].bytes,  elp_packet.packet[0].chunk,
00183                               elp_packet.packet[1].bytes,  elp_packet.packet[1].chunk,
00184                               elp_packet.packet[2].bytes,  elp_packet.packet[2].chunk,
00185                               elp_packet.packet[3].bytes,  elp_packet.packet[3].chunk,
00186                               elp_packet.packet[4].bytes,  elp_packet.packet[4].chunk,
00187                               elp_packet.packet[5].bytes,  elp_packet.packet[5].chunk,
00188                               elp_packet.packet[6].bytes,  elp_packet.packet[6].chunk));
00189 */
00190    elp_packet.b_o_s = 0;
00191    elp_packet.e_o_s = 0;
00192    elp_packet.packetno = state->packetno++;;
00193 //   tts[0]=state->frame_params.timestamp_usec;
00194 //   tts[1]=state->frame_params.timestamp_sec;
00195    elp_packet.granulepos=state->granulepos;
00197    state->granulepos+= (ogg_int64_t) state->timescale;
00198 
00199 //D3(fprintf (debug_file,"_121_"));
00200    ogg_stream_packetin_elph(&(state->os), &elp_packet);
00201 //D3(fprintf (debug_file,"_13_"));
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 

Generated on Fri Nov 28 00:06:21 2008 for elphel by  doxygen 1.5.1