• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavformat/gxfenc.c

Go to the documentation of this file.
00001 /*
00002  * GXF muxer.
00003  * Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>
00004  *
00005  * This file is part of FFmpeg.
00006  *
00007  * FFmpeg is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  *
00012  * FFmpeg is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with FFmpeg; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00020  */
00021 
00022 #include "avformat.h"
00023 #include "gxf.h"
00024 #include "riff.h"
00025 #include "audiointerleave.h"
00026 
00027 #define GXF_AUDIO_PACKET_SIZE 65536
00028 
00029 typedef struct GXFStreamContext {
00030     AudioInterleaveContext aic;
00031     uint32_t track_type;
00032     uint32_t sample_size;
00033     uint32_t sample_rate;
00034     uint16_t media_type;
00035     uint16_t media_info;
00036     int frame_rate_index;
00037     int lines_index;
00038     int fields;
00039     int iframes;
00040     int pframes;
00041     int bframes;
00042     int p_per_gop;
00043     int b_per_i_or_p; 
00044     int first_gop_closed;
00045     unsigned order;   
00046 } GXFStreamContext;
00047 
00048 typedef struct GXFContext {
00049     uint32_t nb_fields;
00050     uint16_t audio_tracks;
00051     uint16_t mpeg_tracks;
00052     int64_t creation_time;
00053     uint32_t umf_start_offset;
00054     uint32_t umf_track_offset;
00055     uint32_t umf_media_offset;
00056     uint32_t umf_length;
00057     uint16_t umf_track_size;
00058     uint16_t umf_media_size;
00059     AVRational time_base;
00060     int flags;
00061     GXFStreamContext timecode_track;
00062     unsigned *flt_entries;    
00063     unsigned flt_entries_nb;
00064     uint64_t *map_offsets;    
00065     unsigned map_offsets_nb;
00066     unsigned packet_count;
00067 } GXFContext;
00068 
00069 static const struct {
00070     int height, index;
00071 } gxf_lines_tab[] = {
00072     { 480,  1 }, /* NTSC */
00073     { 512,  1 }, /* NTSC + VBI */
00074     { 576,  2 }, /* PAL */
00075     { 608,  2 }, /* PAL + VBI */
00076     { 1080, 4 },
00077     { 720,  6 },
00078 };
00079 
00080 static const AVCodecTag gxf_media_types[] = {
00081     { CODEC_ID_MJPEG     ,   3 }, /* NTSC */
00082     { CODEC_ID_MJPEG     ,   4 }, /* PAL */
00083     { CODEC_ID_PCM_S24LE ,   9 },
00084     { CODEC_ID_PCM_S16LE ,  10 },
00085     { CODEC_ID_MPEG2VIDEO,  11 }, /* NTSC */
00086     { CODEC_ID_MPEG2VIDEO,  12 }, /* PAL */
00087     { CODEC_ID_DVVIDEO   ,  13 }, /* NTSC */
00088     { CODEC_ID_DVVIDEO   ,  14 }, /* PAL */
00089     { CODEC_ID_DVVIDEO   ,  15 }, /* 50M NTSC */
00090     { CODEC_ID_DVVIDEO   ,  16 }, /* 50M PAL */
00091     { CODEC_ID_AC3       ,  17 },
00092     //{ CODEC_ID_NONE,  ,   18 }, /* Non compressed 24 bit audio */
00093     { CODEC_ID_MPEG2VIDEO,  20 }, /* MPEG HD */
00094     { CODEC_ID_MPEG1VIDEO,  22 }, /* NTSC */
00095     { CODEC_ID_MPEG1VIDEO,  23 }, /* PAL */
00096     { CODEC_ID_NONE,         0 },
00097 };
00098 
00099 #define SERVER_PATH "EXT:/PDR/default/"
00100 #define ES_NAME_PATTERN "EXT:/PDR/default/ES."
00101 
00102 static int gxf_find_lines_index(AVStream *st)
00103 {
00104     GXFStreamContext *sc = st->priv_data;
00105     int i;
00106 
00107     for (i = 0; i < 6; ++i) {
00108         if (st->codec->height == gxf_lines_tab[i].height) {
00109             sc->lines_index = gxf_lines_tab[i].index;
00110             return 0;
00111         }
00112     }
00113     return -1;
00114 }
00115 
00116 static void gxf_write_padding(ByteIOContext *pb, int64_t to_pad)
00117 {
00118     for (; to_pad > 0; to_pad--) {
00119         put_byte(pb, 0);
00120     }
00121 }
00122 
00123 static int64_t updatePacketSize(ByteIOContext *pb, int64_t pos)
00124 {
00125     int64_t curpos;
00126     int size;
00127 
00128     size = url_ftell(pb) - pos;
00129     if (size % 4) {
00130         gxf_write_padding(pb, 4 - size % 4);
00131         size = url_ftell(pb) - pos;
00132     }
00133     curpos = url_ftell(pb);
00134     url_fseek(pb, pos + 6, SEEK_SET);
00135     put_be32(pb, size);
00136     url_fseek(pb, curpos, SEEK_SET);
00137     return curpos - pos;
00138 }
00139 
00140 static int64_t updateSize(ByteIOContext *pb, int64_t pos)
00141 {
00142     int64_t curpos;
00143 
00144     curpos = url_ftell(pb);
00145     url_fseek(pb, pos, SEEK_SET);
00146     put_be16(pb, curpos - pos - 2);
00147     url_fseek(pb, curpos, SEEK_SET);
00148     return curpos - pos;
00149 }
00150 
00151 static void gxf_write_packet_header(ByteIOContext *pb, GXFPktType type)
00152 {
00153     put_be32(pb, 0); /* packet leader for synchro */
00154     put_byte(pb, 1);
00155     put_byte(pb, type); /* map packet */
00156     put_be32(pb, 0); /* size */
00157     put_be32(pb, 0); /* reserved */
00158     put_byte(pb, 0xE1); /* trailer 1 */
00159     put_byte(pb, 0xE2); /* trailer 2 */
00160 }
00161 
00162 static int gxf_write_mpeg_auxiliary(ByteIOContext *pb, AVStream *st)
00163 {
00164     GXFStreamContext *sc = st->priv_data;
00165     char buffer[1024];
00166     int size, starting_line;
00167 
00168     if (sc->iframes) {
00169         sc->p_per_gop = sc->pframes / sc->iframes;
00170         if (sc->pframes % sc->iframes)
00171             sc->p_per_gop++;
00172         if (sc->pframes) {
00173             sc->b_per_i_or_p = sc->bframes / sc->pframes;
00174             if (sc->bframes % sc->pframes)
00175                 sc->b_per_i_or_p++;
00176         }
00177         if (sc->p_per_gop > 9)
00178             sc->p_per_gop = 9; /* ensure value won't take more than one char */
00179         if (sc->b_per_i_or_p > 9)
00180             sc->b_per_i_or_p = 9; /* ensure value won't take more than one char */
00181     }
00182     if (st->codec->height == 512 || st->codec->height == 608)
00183         starting_line = 7; // VBI
00184     else if (st->codec->height == 480)
00185         starting_line = 20;
00186     else
00187         starting_line = 23; // default PAL
00188 
00189     size = snprintf(buffer, 1024, "Ver 1\nBr %.6f\nIpg 1\nPpi %d\nBpiop %d\n"
00190                     "Pix 0\nCf %d\nCg %d\nSl %d\nnl16 %d\nVi 1\nf1 1\n",
00191                     (float)st->codec->bit_rate, sc->p_per_gop, sc->b_per_i_or_p,
00192                     st->codec->pix_fmt == PIX_FMT_YUV422P ? 2 : 1, sc->first_gop_closed == 1,
00193                     starting_line, st->codec->height / 16);
00194     put_byte(pb, TRACK_MPG_AUX);
00195     put_byte(pb, size + 1);
00196     put_buffer(pb, (uint8_t *)buffer, size + 1);
00197     return size + 3;
00198 }
00199 
00200 static int gxf_write_timecode_auxiliary(ByteIOContext *pb, GXFStreamContext *sc)
00201 {
00202     put_byte(pb, 0); /* fields */
00203     put_byte(pb, 0);  /* seconds */
00204     put_byte(pb, 0); /* minutes */
00205     put_byte(pb, 0); /* flags + hours */
00206     /* reserved */
00207     put_be32(pb, 0);
00208     return 8;
00209 }
00210 
00211 static int gxf_write_track_description(AVFormatContext *s, GXFStreamContext *sc, int index)
00212 {
00213     ByteIOContext *pb = s->pb;
00214     int64_t pos;
00215     int mpeg = sc->track_type == 4 || sc->track_type == 9;
00216 
00217     /* track description section */
00218     put_byte(pb, sc->media_type + 0x80);
00219     put_byte(pb, index + 0xC0);
00220 
00221     pos = url_ftell(pb);
00222     put_be16(pb, 0); /* size */
00223 
00224     /* media file name */
00225     put_byte(pb, TRACK_NAME);
00226     put_byte(pb, strlen(ES_NAME_PATTERN) + 3);
00227     put_tag(pb, ES_NAME_PATTERN);
00228     put_be16(pb, sc->media_info);
00229     put_byte(pb, 0);
00230 
00231     if (!mpeg) {
00232         /* auxiliary information */
00233         put_byte(pb, TRACK_AUX);
00234         put_byte(pb, 8);
00235         if (sc->track_type == 3)
00236             gxf_write_timecode_auxiliary(pb, sc);
00237         else
00238             put_le64(pb, 0);
00239     }
00240 
00241     /* file system version */
00242     put_byte(pb, TRACK_VER);
00243     put_byte(pb, 4);
00244     put_be32(pb, 0);
00245 
00246     if (mpeg)
00247         gxf_write_mpeg_auxiliary(pb, s->streams[index]);
00248 
00249     /* frame rate */
00250     put_byte(pb, TRACK_FPS);
00251     put_byte(pb, 4);
00252     put_be32(pb, sc->frame_rate_index);
00253 
00254     /* lines per frame */
00255     put_byte(pb, TRACK_LINES);
00256     put_byte(pb, 4);
00257     put_be32(pb, sc->lines_index);
00258 
00259     /* fields per frame */
00260     put_byte(pb, TRACK_FPF);
00261     put_byte(pb, 4);
00262     put_be32(pb, sc->fields);
00263 
00264     return updateSize(pb, pos);
00265 }
00266 
00267 static int gxf_write_material_data_section(AVFormatContext *s)
00268 {
00269     GXFContext *gxf = s->priv_data;
00270     ByteIOContext *pb = s->pb;
00271     int64_t pos;
00272     const char *filename = strrchr(s->filename, '/');
00273 
00274     pos = url_ftell(pb);
00275     put_be16(pb, 0); /* size */
00276 
00277     /* name */
00278     if (filename)
00279         filename++;
00280     else
00281         filename = s->filename;
00282     put_byte(pb, MAT_NAME);
00283     put_byte(pb, strlen(SERVER_PATH) + strlen(filename) + 1);
00284     put_tag(pb, SERVER_PATH);
00285     put_tag(pb, filename);
00286     put_byte(pb, 0);
00287 
00288     /* first field */
00289     put_byte(pb, MAT_FIRST_FIELD);
00290     put_byte(pb, 4);
00291     put_be32(pb, 0);
00292 
00293     /* last field */
00294     put_byte(pb, MAT_LAST_FIELD);
00295     put_byte(pb, 4);
00296     put_be32(pb, gxf->nb_fields);
00297 
00298     /* reserved */
00299     put_byte(pb, MAT_MARK_IN);
00300     put_byte(pb, 4);
00301     put_be32(pb, 0);
00302 
00303     put_byte(pb, MAT_MARK_OUT);
00304     put_byte(pb, 4);
00305     put_be32(pb, gxf->nb_fields);
00306 
00307     /* estimated size */
00308     put_byte(pb, MAT_SIZE);
00309     put_byte(pb, 4);
00310     put_be32(pb, url_fsize(pb) / 1024);
00311 
00312     return updateSize(pb, pos);
00313 }
00314 
00315 static int gxf_write_track_description_section(AVFormatContext *s)
00316 {
00317     GXFContext *gxf = s->priv_data;
00318     ByteIOContext *pb = s->pb;
00319     int64_t pos;
00320     int i;
00321 
00322     pos = url_ftell(pb);
00323     put_be16(pb, 0); /* size */
00324     for (i = 0; i < s->nb_streams; ++i)
00325         gxf_write_track_description(s, s->streams[i]->priv_data, i);
00326 
00327     gxf_write_track_description(s, &gxf->timecode_track, s->nb_streams);
00328 
00329     return updateSize(pb, pos);
00330 }
00331 
00332 static int gxf_write_map_packet(AVFormatContext *s, int rewrite)
00333 {
00334     GXFContext *gxf = s->priv_data;
00335     ByteIOContext *pb = s->pb;
00336     int64_t pos = url_ftell(pb);
00337 
00338     if (!rewrite) {
00339         if (!(gxf->map_offsets_nb % 30)) {
00340             gxf->map_offsets = av_realloc(gxf->map_offsets,
00341                                           (gxf->map_offsets_nb+30)*sizeof(*gxf->map_offsets));
00342             if (!gxf->map_offsets) {
00343                 av_log(s, AV_LOG_ERROR, "could not realloc map offsets\n");
00344                 return -1;
00345             }
00346         }
00347         gxf->map_offsets[gxf->map_offsets_nb++] = pos; // do not increment here
00348     }
00349 
00350     gxf_write_packet_header(pb, PKT_MAP);
00351 
00352     /* preamble */
00353     put_byte(pb, 0xE0); /* version */
00354     put_byte(pb, 0xFF); /* reserved */
00355 
00356     gxf_write_material_data_section(s);
00357     gxf_write_track_description_section(s);
00358 
00359     return updatePacketSize(pb, pos);
00360 }
00361 
00362 static int gxf_write_flt_packet(AVFormatContext *s)
00363 {
00364     GXFContext *gxf = s->priv_data;
00365     ByteIOContext *pb = s->pb;
00366     int64_t pos = url_ftell(pb);
00367     int fields_per_flt = (gxf->nb_fields+1) / 1000 + 1;
00368     int flt_entries = gxf->nb_fields / fields_per_flt - 1;
00369     int i = 0;
00370 
00371     gxf_write_packet_header(pb, PKT_FLT);
00372 
00373     put_le32(pb, fields_per_flt); /* number of fields */
00374     put_le32(pb, flt_entries); /* number of active flt entries */
00375 
00376     if (gxf->flt_entries) {
00377         for (i = 0; i < flt_entries; i++)
00378             put_le32(pb, gxf->flt_entries[(i*fields_per_flt)>>1]);
00379     }
00380 
00381     for (; i < 1000; i++)
00382         put_le32(pb, 0);
00383 
00384     return updatePacketSize(pb, pos);
00385 }
00386 
00387 static int gxf_write_umf_material_description(AVFormatContext *s)
00388 {
00389     GXFContext *gxf = s->priv_data;
00390     ByteIOContext *pb = s->pb;
00391     int timecode_base = gxf->time_base.den == 60000 ? 60 : 50;
00392 
00393     // XXX drop frame
00394     uint32_t timecode =
00395         gxf->nb_fields / (timecode_base * 3600) % 24 << 24 | // hours
00396         gxf->nb_fields / (timecode_base * 60) % 60   << 16 | // minutes
00397         gxf->nb_fields /  timecode_base % 60         <<  8 | // seconds
00398         gxf->nb_fields %  timecode_base;                     // fields
00399 
00400     put_le32(pb, gxf->flags);
00401     put_le32(pb, gxf->nb_fields); /* length of the longest track */
00402     put_le32(pb, gxf->nb_fields); /* length of the shortest track */
00403     put_le32(pb, 0); /* mark in */
00404     put_le32(pb, gxf->nb_fields); /* mark out */
00405     put_le32(pb, 0); /* timecode mark in */
00406     put_le32(pb, timecode); /* timecode mark out */
00407     put_le64(pb, s->timestamp); /* modification time */
00408     put_le64(pb, s->timestamp); /* creation time */
00409     put_le16(pb, 0); /* reserved */
00410     put_le16(pb, 0); /* reserved */
00411     put_le16(pb, gxf->audio_tracks);
00412     put_le16(pb, 1); /* timecode track count */
00413     put_le16(pb, 0); /* reserved */
00414     put_le16(pb, gxf->mpeg_tracks);
00415     return 48;
00416 }
00417 
00418 static int gxf_write_umf_payload(AVFormatContext *s)
00419 {
00420     GXFContext *gxf = s->priv_data;
00421     ByteIOContext *pb = s->pb;
00422 
00423     put_le32(pb, gxf->umf_length); /* total length of the umf data */
00424     put_le32(pb, 3); /* version */
00425     put_le32(pb, s->nb_streams+1);
00426     put_le32(pb, gxf->umf_track_offset); /* umf track section offset */
00427     put_le32(pb, gxf->umf_track_size);
00428     put_le32(pb, s->nb_streams+1);
00429     put_le32(pb, gxf->umf_media_offset);
00430     put_le32(pb, gxf->umf_media_size);
00431     put_le32(pb, gxf->umf_length); /* user data offset */
00432     put_le32(pb, 0); /* user data size */
00433     put_le32(pb, 0); /* reserved */
00434     put_le32(pb, 0); /* reserved */
00435     return 48;
00436 }
00437 
00438 static int gxf_write_umf_track_description(AVFormatContext *s)
00439 {
00440     ByteIOContext *pb = s->pb;
00441     GXFContext *gxf = s->priv_data;
00442     int64_t pos = url_ftell(pb);
00443     int i;
00444 
00445     gxf->umf_track_offset = pos - gxf->umf_start_offset;
00446     for (i = 0; i < s->nb_streams; ++i) {
00447         GXFStreamContext *sc = s->streams[i]->priv_data;
00448         put_le16(pb, sc->media_info);
00449         put_le16(pb, 1);
00450     }
00451 
00452     put_le16(pb, gxf->timecode_track.media_info);
00453     put_le16(pb, 1);
00454 
00455     return url_ftell(pb) - pos;
00456 }
00457 
00458 static int gxf_write_umf_media_mpeg(ByteIOContext *pb, AVStream *st)
00459 {
00460     GXFStreamContext *sc = st->priv_data;
00461 
00462     if (st->codec->pix_fmt == PIX_FMT_YUV422P)
00463         put_le32(pb, 2);
00464     else
00465         put_le32(pb, 1); /* default to 420 */
00466     put_le32(pb, sc->first_gop_closed == 1); /* closed = 1, open = 0, unknown = 255 */
00467     put_le32(pb, 3); /* top = 1, bottom = 2, frame = 3, unknown = 0 */
00468     put_le32(pb, 1); /* I picture per GOP */
00469     put_le32(pb, sc->p_per_gop);
00470     put_le32(pb, sc->b_per_i_or_p);
00471     if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO)
00472         put_le32(pb, 2);
00473     else if (st->codec->codec_id == CODEC_ID_MPEG1VIDEO)
00474         put_le32(pb, 1);
00475     else
00476         put_le32(pb, 0);
00477     put_le32(pb, 0); /* reserved */
00478     return 32;
00479 }
00480 
00481 static int gxf_write_umf_media_timecode(ByteIOContext *pb, GXFStreamContext *sc)
00482 {
00483     put_le32(pb, 1); /* non drop frame */
00484     put_le32(pb, 0); /* reserved */
00485     put_le32(pb, 0); /* reserved */
00486     put_le32(pb, 0); /* reserved */
00487     put_le32(pb, 0); /* reserved */
00488     put_le32(pb, 0); /* reserved */
00489     put_le32(pb, 0); /* reserved */
00490     put_le32(pb, 0); /* reserved */
00491     return 32;
00492 }
00493 
00494 static int gxf_write_umf_media_dv(ByteIOContext *pb, GXFStreamContext *sc)
00495 {
00496     int i;
00497 
00498     for (i = 0; i < 8; i++) {
00499         put_be32(pb, 0);
00500     }
00501     return 32;
00502 }
00503 
00504 static int gxf_write_umf_media_audio(ByteIOContext *pb, GXFStreamContext *sc)
00505 {
00506     put_le64(pb, av_dbl2int(1)); /* sound level to begin to */
00507     put_le64(pb, av_dbl2int(1)); /* sound level to begin to */
00508     put_le32(pb, 0); /* number of fields over which to ramp up sound level */
00509     put_le32(pb, 0); /* number of fields over which to ramp down sound level */
00510     put_le32(pb, 0); /* reserved */
00511     put_le32(pb, 0); /* reserved */
00512     return 32;
00513 }
00514 
00515 #if 0
00516 static int gxf_write_umf_media_mjpeg(ByteIOContext *pb, GXFStreamContext *sc)
00517 {
00518     put_be64(pb, 0); /* FIXME FLOAT max chroma quant level */
00519     put_be64(pb, 0); /* FIXME FLOAT max luma quant level */
00520     put_be64(pb, 0); /* FIXME FLOAT min chroma quant level */
00521     put_be64(pb, 0); /* FIXME FLOAT min luma quant level */
00522     return 32;
00523 }
00524 #endif
00525 
00526 static int gxf_write_umf_media_description(AVFormatContext *s)
00527 {
00528     GXFContext *gxf = s->priv_data;
00529     ByteIOContext *pb = s->pb;
00530     int64_t pos;
00531     int i, j;
00532 
00533     pos = url_ftell(pb);
00534     gxf->umf_media_offset = pos - gxf->umf_start_offset;
00535     for (i = 0; i <= s->nb_streams; ++i) {
00536         GXFStreamContext *sc;
00537         int64_t startpos, curpos;
00538 
00539         if (i == s->nb_streams)
00540             sc = &gxf->timecode_track;
00541         else
00542             sc = s->streams[i]->priv_data;
00543 
00544         startpos = url_ftell(pb);
00545         put_le16(pb, 0); /* length */
00546         put_le16(pb, sc->media_info);
00547         put_le16(pb, 0); /* reserved */
00548         put_le16(pb, 0); /* reserved */
00549         put_le32(pb, gxf->nb_fields);
00550         put_le32(pb, 0); /* attributes rw, ro */
00551         put_le32(pb, 0); /* mark in */
00552         put_le32(pb, gxf->nb_fields); /* mark out */
00553         put_buffer(pb, ES_NAME_PATTERN, sizeof(ES_NAME_PATTERN));
00554         put_be16(pb, sc->media_info);
00555         for (j = sizeof(ES_NAME_PATTERN)+2; j < 88; j++)
00556             put_byte(pb, 0);
00557         put_le32(pb, sc->track_type);
00558         put_le32(pb, sc->sample_rate);
00559         put_le32(pb, sc->sample_size);
00560         put_le32(pb, 0); /* reserved */
00561 
00562         if (sc == &gxf->timecode_track)
00563             gxf_write_umf_media_timecode(pb, sc); /* 8 0bytes */
00564         else {
00565             AVStream *st = s->streams[i];
00566             switch (st->codec->codec_id) {
00567             case CODEC_ID_MPEG2VIDEO:
00568                 gxf_write_umf_media_mpeg(pb, st);
00569                 break;
00570             case CODEC_ID_PCM_S16LE:
00571                 gxf_write_umf_media_audio(pb, sc);
00572                 break;
00573             case CODEC_ID_DVVIDEO:
00574                 gxf_write_umf_media_dv(pb, sc);
00575                 break;
00576             }
00577         }
00578 
00579         curpos = url_ftell(pb);
00580         url_fseek(pb, startpos, SEEK_SET);
00581         put_le16(pb, curpos - startpos);
00582         url_fseek(pb, curpos, SEEK_SET);
00583     }
00584     return url_ftell(pb) - pos;
00585 }
00586 
00587 static int gxf_write_umf_packet(AVFormatContext *s)
00588 {
00589     GXFContext *gxf = s->priv_data;
00590     ByteIOContext *pb = s->pb;
00591     int64_t pos = url_ftell(pb);
00592 
00593     gxf_write_packet_header(pb, PKT_UMF);
00594 
00595     /* preamble */
00596     put_byte(pb, 3); /* first and last (only) packet */
00597     put_be32(pb, gxf->umf_length); /* data length */
00598 
00599     gxf->umf_start_offset = url_ftell(pb);
00600     gxf_write_umf_payload(s);
00601     gxf_write_umf_material_description(s);
00602     gxf->umf_track_size = gxf_write_umf_track_description(s);
00603     gxf->umf_media_size = gxf_write_umf_media_description(s);
00604     gxf->umf_length = url_ftell(pb) - gxf->umf_start_offset;
00605     return updatePacketSize(pb, pos);
00606 }
00607 
00608 static const int GXF_samples_per_frame[] = { 32768, 0 };
00609 
00610 static void gxf_init_timecode_track(GXFStreamContext *sc, GXFStreamContext *vsc)
00611 {
00612     if (!vsc)
00613         return;
00614 
00615     sc->media_type = vsc->sample_rate == 60 ? 7 : 8;
00616     sc->sample_rate = vsc->sample_rate;
00617     sc->media_info = ('T'<<8) | '0';
00618     sc->track_type = 3;
00619     sc->frame_rate_index = vsc->frame_rate_index;
00620     sc->lines_index = vsc->lines_index;
00621     sc->sample_size = 16;
00622     sc->fields = vsc->fields;
00623 }
00624 
00625 static int gxf_write_header(AVFormatContext *s)
00626 {
00627     ByteIOContext *pb = s->pb;
00628     GXFContext *gxf = s->priv_data;
00629     GXFStreamContext *vsc = NULL;
00630     uint8_t tracks[255] = {0};
00631     int i, media_info = 0;
00632 
00633     if (url_is_streamed(pb)) {
00634         av_log(s, AV_LOG_ERROR, "gxf muxer does not support streamed output, patch welcome");
00635         return -1;
00636     }
00637 
00638     gxf->flags |= 0x00080000; /* material is simple clip */
00639     for (i = 0; i < s->nb_streams; ++i) {
00640         AVStream *st = s->streams[i];
00641         GXFStreamContext *sc = av_mallocz(sizeof(*sc));
00642         if (!sc)
00643             return AVERROR(ENOMEM);
00644         st->priv_data = sc;
00645 
00646         sc->media_type = ff_codec_get_tag(gxf_media_types, st->codec->codec_id);
00647         if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
00648             if (st->codec->codec_id != CODEC_ID_PCM_S16LE) {
00649                 av_log(s, AV_LOG_ERROR, "only 16 BIT PCM LE allowed for now\n");
00650                 return -1;
00651             }
00652             if (st->codec->sample_rate != 48000) {
00653                 av_log(s, AV_LOG_ERROR, "only 48000hz sampling rate is allowed\n");
00654                 return -1;
00655             }
00656             if (st->codec->channels != 1) {
00657                 av_log(s, AV_LOG_ERROR, "only mono tracks are allowed\n");
00658                 return -1;
00659             }
00660             sc->track_type = 2;
00661             sc->sample_rate = st->codec->sample_rate;
00662             av_set_pts_info(st, 64, 1, sc->sample_rate);
00663             sc->sample_size = 16;
00664             sc->frame_rate_index = -2;
00665             sc->lines_index = -2;
00666             sc->fields = -2;
00667             gxf->audio_tracks++;
00668             gxf->flags |= 0x04000000; /* audio is 16 bit pcm */
00669             media_info = 'A';
00670         } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
00671             if (i != 0) {
00672                 av_log(s, AV_LOG_ERROR, "video stream must be the first track\n");
00673                 return -1;
00674             }
00675             /* FIXME check from time_base ? */
00676             if (st->codec->height == 480 || st->codec->height == 512) { /* NTSC or NTSC+VBI */
00677                 sc->frame_rate_index = 5;
00678                 sc->sample_rate = 60;
00679                 gxf->flags |= 0x00000080;
00680                 gxf->time_base = (AVRational){ 1001, 60000 };
00681             } else { /* assume PAL */
00682                 sc->frame_rate_index = 6;
00683                 sc->media_type++;
00684                 sc->sample_rate = 50;
00685                 gxf->flags |= 0x00000040;
00686                 gxf->time_base = (AVRational){ 1, 50 };
00687             }
00688             av_set_pts_info(st, 64, gxf->time_base.num, gxf->time_base.den);
00689             if (gxf_find_lines_index(st) < 0)
00690                 sc->lines_index = -1;
00691             sc->sample_size = st->codec->bit_rate;
00692             sc->fields = 2; /* interlaced */
00693 
00694             vsc = sc;
00695 
00696             switch (st->codec->codec_id) {
00697             case CODEC_ID_MJPEG:
00698                 sc->track_type = 1;
00699                 gxf->flags |= 0x00004000;
00700                 media_info = 'J';
00701                 break;
00702             case CODEC_ID_MPEG1VIDEO:
00703                 sc->track_type = 9;
00704                 gxf->mpeg_tracks++;
00705                 media_info = 'L';
00706                 break;
00707             case CODEC_ID_MPEG2VIDEO:
00708                 sc->first_gop_closed = -1;
00709                 sc->track_type = 4;
00710                 gxf->mpeg_tracks++;
00711                 gxf->flags |= 0x00008000;
00712                 media_info = 'M';
00713                 break;
00714             case CODEC_ID_DVVIDEO:
00715                 if (st->codec->pix_fmt == PIX_FMT_YUV422P) {
00716                     sc->media_type += 2;
00717                     sc->track_type = 6;
00718                     gxf->flags |= 0x00002000;
00719                     media_info = 'E';
00720                 } else {
00721                     sc->track_type = 5;
00722                     gxf->flags |= 0x00001000;
00723                     media_info = 'D';
00724                 }
00725                 break;
00726             default:
00727                 av_log(s, AV_LOG_ERROR, "video codec not supported\n");
00728                 return -1;
00729             }
00730         }
00731         /* FIXME first 10 audio tracks are 0 to 9 next 22 are A to V */
00732         sc->media_info = media_info<<8 | ('0'+tracks[media_info]++);
00733         sc->order = s->nb_streams - st->index;
00734     }
00735 
00736     if (ff_audio_interleave_init(s, GXF_samples_per_frame, (AVRational){ 1, 48000 }) < 0)
00737         return -1;
00738 
00739     gxf_init_timecode_track(&gxf->timecode_track, vsc);
00740     gxf->flags |= 0x200000; // time code track is non-drop frame
00741 
00742     gxf_write_map_packet(s, 0);
00743     gxf_write_flt_packet(s);
00744     gxf_write_umf_packet(s);
00745 
00746     gxf->packet_count = 3;
00747 
00748     put_flush_packet(pb);
00749     return 0;
00750 }
00751 
00752 static int gxf_write_eos_packet(ByteIOContext *pb)
00753 {
00754     int64_t pos = url_ftell(pb);
00755 
00756     gxf_write_packet_header(pb, PKT_EOS);
00757     return updatePacketSize(pb, pos);
00758 }
00759 
00760 static int gxf_write_trailer(AVFormatContext *s)
00761 {
00762     GXFContext *gxf = s->priv_data;
00763     ByteIOContext *pb = s->pb;
00764     int64_t end;
00765     int i;
00766 
00767     ff_audio_interleave_close(s);
00768 
00769     gxf_write_eos_packet(pb);
00770     end = url_ftell(pb);
00771     url_fseek(pb, 0, SEEK_SET);
00772     /* overwrite map, flt and umf packets with new values */
00773     gxf_write_map_packet(s, 1);
00774     gxf_write_flt_packet(s);
00775     gxf_write_umf_packet(s);
00776     put_flush_packet(pb);
00777     /* update duration in all map packets */
00778     for (i = 1; i < gxf->map_offsets_nb; i++) {
00779         url_fseek(pb, gxf->map_offsets[i], SEEK_SET);
00780         gxf_write_map_packet(s, 1);
00781         put_flush_packet(pb);
00782     }
00783 
00784     url_fseek(pb, end, SEEK_SET);
00785 
00786     av_freep(&gxf->flt_entries);
00787     av_freep(&gxf->map_offsets);
00788 
00789     return 0;
00790 }
00791 
00792 static int gxf_parse_mpeg_frame(GXFStreamContext *sc, const uint8_t *buf, int size)
00793 {
00794     uint32_t c=-1;
00795     int i;
00796     for(i=0; i<size-4 && c!=0x100; i++){
00797         c = (c<<8) + buf[i];
00798         if(c == 0x1B8 && sc->first_gop_closed == -1) /* GOP start code */
00799             sc->first_gop_closed= (buf[i+4]>>6)&1;
00800     }
00801     return (buf[i+1]>>3)&7;
00802 }
00803 
00804 static int gxf_write_media_preamble(AVFormatContext *s, AVPacket *pkt, int size)
00805 {
00806     GXFContext *gxf = s->priv_data;
00807     ByteIOContext *pb = s->pb;
00808     AVStream *st = s->streams[pkt->stream_index];
00809     GXFStreamContext *sc = st->priv_data;
00810     unsigned field_nb;
00811     /* If the video is frame-encoded, the frame numbers shall be represented by
00812      * even field numbers.
00813      * see SMPTE360M-2004  6.4.2.1.3 Media field number */
00814     if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
00815         field_nb = gxf->nb_fields;
00816     } else {
00817         field_nb = av_rescale_rnd(pkt->dts, gxf->time_base.den,
00818                                   (int64_t)48000*gxf->time_base.num, AV_ROUND_UP);
00819     }
00820 
00821     put_byte(pb, sc->media_type);
00822     put_byte(pb, st->index);
00823     put_be32(pb, field_nb);
00824     if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
00825         put_be16(pb, 0);
00826         put_be16(pb, size / 2);
00827     } else if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO) {
00828         int frame_type = gxf_parse_mpeg_frame(sc, pkt->data, pkt->size);
00829         if (frame_type == FF_I_TYPE) {
00830             put_byte(pb, 0x0d);
00831             sc->iframes++;
00832         } else if (frame_type == FF_B_TYPE) {
00833             put_byte(pb, 0x0f);
00834             sc->bframes++;
00835         } else {
00836             put_byte(pb, 0x0e);
00837             sc->pframes++;
00838         }
00839         put_be24(pb, size);
00840     } else if (st->codec->codec_id == CODEC_ID_DVVIDEO) {
00841         put_byte(pb, size / 4096);
00842         put_be24(pb, 0);
00843     } else
00844         put_be32(pb, size);
00845     put_be32(pb, field_nb);
00846     put_byte(pb, 1); /* flags */
00847     put_byte(pb, 0); /* reserved */
00848     return 16;
00849 }
00850 
00851 static int gxf_write_packet(AVFormatContext *s, AVPacket *pkt)
00852 {
00853     GXFContext *gxf = s->priv_data;
00854     ByteIOContext *pb = s->pb;
00855     AVStream *st = s->streams[pkt->stream_index];
00856     int64_t pos = url_ftell(pb);
00857     int padding = 0;
00858 
00859     gxf_write_packet_header(pb, PKT_MEDIA);
00860     if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO && pkt->size % 4) /* MPEG-2 frames must be padded */
00861         padding = 4 - pkt->size % 4;
00862     else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
00863         padding = GXF_AUDIO_PACKET_SIZE - pkt->size;
00864     gxf_write_media_preamble(s, pkt, pkt->size + padding);
00865     put_buffer(pb, pkt->data, pkt->size);
00866     gxf_write_padding(pb, padding);
00867 
00868     if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
00869         if (!(gxf->flt_entries_nb % 500)) {
00870             gxf->flt_entries = av_realloc(gxf->flt_entries,
00871                                           (gxf->flt_entries_nb+500)*sizeof(*gxf->flt_entries));
00872             if (!gxf->flt_entries) {
00873                 av_log(s, AV_LOG_ERROR, "could not reallocate flt entries\n");
00874                 return -1;
00875             }
00876         }
00877         gxf->flt_entries[gxf->flt_entries_nb++] = url_ftell(pb) / 1024;
00878         gxf->nb_fields += 2; // count fields
00879     }
00880 
00881     updatePacketSize(pb, pos);
00882 
00883     gxf->packet_count++;
00884     if (gxf->packet_count == 100) {
00885         gxf_write_map_packet(s, 0);
00886         gxf->packet_count = 0;
00887     }
00888 
00889     put_flush_packet(pb);
00890 
00891     return 0;
00892 }
00893 
00894 static int gxf_compare_field_nb(AVFormatContext *s, AVPacket *next, AVPacket *cur)
00895 {
00896     GXFContext *gxf = s->priv_data;
00897     AVPacket *pkt[2] = { cur, next };
00898     int i, field_nb[2];
00899     GXFStreamContext *sc[2];
00900 
00901     for (i = 0; i < 2; i++) {
00902         AVStream *st = s->streams[pkt[i]->stream_index];
00903         sc[i] = st->priv_data;
00904         if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
00905             field_nb[i] = av_rescale_rnd(pkt[i]->dts, gxf->time_base.den,
00906                                          (int64_t)48000*gxf->time_base.num, AV_ROUND_UP);
00907             field_nb[i] &= ~1; // compare against even field number because audio must be before video
00908         } else
00909             field_nb[i] = pkt[i]->dts; // dts are field based
00910     }
00911 
00912     return field_nb[1] > field_nb[0] ||
00913         (field_nb[1] == field_nb[0] && sc[1]->order > sc[0]->order);
00914 }
00915 
00916 static int gxf_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush)
00917 {
00918     if (pkt && s->streams[pkt->stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
00919         pkt->duration = 2; // enforce 2 fields
00920     return ff_audio_rechunk_interleave(s, out, pkt, flush,
00921                                av_interleave_packet_per_dts, gxf_compare_field_nb);
00922 }
00923 
00924 AVOutputFormat gxf_muxer = {
00925     "gxf",
00926     NULL_IF_CONFIG_SMALL("GXF format"),
00927     NULL,
00928     "gxf",
00929     sizeof(GXFContext),
00930     CODEC_ID_PCM_S16LE,
00931     CODEC_ID_MPEG2VIDEO,
00932     gxf_write_header,
00933     gxf_write_packet,
00934     gxf_write_trailer,
00935     0,
00936     NULL,
00937     gxf_interleave_packet,
00938 };

Generated on Fri Sep 16 2011 17:17:48 for FFmpeg by  doxygen 1.7.1