Libav 0.7.1
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 Libav.
00006  *
00007  * Libav 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  * Libav 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 Libav; 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(AVIOContext *pb, int64_t to_pad)
00117 {
00118     for (; to_pad > 0; to_pad--) {
00119         avio_w8(pb, 0);
00120     }
00121 }
00122 
00123 static int64_t updatePacketSize(AVIOContext *pb, int64_t pos)
00124 {
00125     int64_t curpos;
00126     int size;
00127 
00128     size = avio_tell(pb) - pos;
00129     if (size % 4) {
00130         gxf_write_padding(pb, 4 - size % 4);
00131         size = avio_tell(pb) - pos;
00132     }
00133     curpos = avio_tell(pb);
00134     avio_seek(pb, pos + 6, SEEK_SET);
00135     avio_wb32(pb, size);
00136     avio_seek(pb, curpos, SEEK_SET);
00137     return curpos - pos;
00138 }
00139 
00140 static int64_t updateSize(AVIOContext *pb, int64_t pos)
00141 {
00142     int64_t curpos;
00143 
00144     curpos = avio_tell(pb);
00145     avio_seek(pb, pos, SEEK_SET);
00146     avio_wb16(pb, curpos - pos - 2);
00147     avio_seek(pb, curpos, SEEK_SET);
00148     return curpos - pos;
00149 }
00150 
00151 static void gxf_write_packet_header(AVIOContext *pb, GXFPktType type)
00152 {
00153     avio_wb32(pb, 0);  /* packet leader for synchro */
00154     avio_w8(pb, 1);
00155     avio_w8(pb, type); /* map packet */
00156     avio_wb32(pb, 0);  /* size */
00157     avio_wb32(pb, 0);  /* reserved */
00158     avio_w8(pb, 0xE1); /* trailer 1 */
00159     avio_w8(pb, 0xE2); /* trailer 2 */
00160 }
00161 
00162 static int gxf_write_mpeg_auxiliary(AVIOContext *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 + 15) / 16);
00194     avio_w8(pb, TRACK_MPG_AUX);
00195     avio_w8(pb, size + 1);
00196     avio_write(pb, (uint8_t *)buffer, size + 1);
00197     return size + 3;
00198 }
00199 
00200 static int gxf_write_timecode_auxiliary(AVIOContext *pb, GXFStreamContext *sc)
00201 {
00202     avio_w8(pb, 0); /* fields */
00203     avio_w8(pb, 0); /* seconds */
00204     avio_w8(pb, 0); /* minutes */
00205     avio_w8(pb, 0); /* flags + hours */
00206     /* reserved */
00207     avio_wb32(pb, 0);
00208     return 8;
00209 }
00210 
00211 static int gxf_write_track_description(AVFormatContext *s, GXFStreamContext *sc, int index)
00212 {
00213     AVIOContext *pb = s->pb;
00214     int64_t pos;
00215     int mpeg = sc->track_type == 4 || sc->track_type == 9;
00216 
00217     /* track description section */
00218     avio_w8(pb, sc->media_type + 0x80);
00219     avio_w8(pb, index + 0xC0);
00220 
00221     pos = avio_tell(pb);
00222     avio_wb16(pb, 0); /* size */
00223 
00224     /* media file name */
00225     avio_w8(pb, TRACK_NAME);
00226     avio_w8(pb, strlen(ES_NAME_PATTERN) + 3);
00227     avio_write(pb, ES_NAME_PATTERN, sizeof(ES_NAME_PATTERN) - 1);
00228     avio_wb16(pb, sc->media_info);
00229     avio_w8(pb, 0);
00230 
00231     if (!mpeg) {
00232         /* auxiliary information */
00233         avio_w8(pb, TRACK_AUX);
00234         avio_w8(pb, 8);
00235         if (sc->track_type == 3)
00236             gxf_write_timecode_auxiliary(pb, sc);
00237         else
00238             avio_wl64(pb, 0);
00239     }
00240 
00241     /* file system version */
00242     avio_w8(pb, TRACK_VER);
00243     avio_w8(pb, 4);
00244     avio_wb32(pb, 0);
00245 
00246     if (mpeg)
00247         gxf_write_mpeg_auxiliary(pb, s->streams[index]);
00248 
00249     /* frame rate */
00250     avio_w8(pb, TRACK_FPS);
00251     avio_w8(pb, 4);
00252     avio_wb32(pb, sc->frame_rate_index);
00253 
00254     /* lines per frame */
00255     avio_w8(pb, TRACK_LINES);
00256     avio_w8(pb, 4);
00257     avio_wb32(pb, sc->lines_index);
00258 
00259     /* fields per frame */
00260     avio_w8(pb, TRACK_FPF);
00261     avio_w8(pb, 4);
00262     avio_wb32(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     AVIOContext *pb = s->pb;
00271     int64_t pos;
00272     int len;
00273     const char *filename = strrchr(s->filename, '/');
00274 
00275     pos = avio_tell(pb);
00276     avio_wb16(pb, 0); /* size */
00277 
00278     /* name */
00279     if (filename)
00280         filename++;
00281     else
00282         filename = s->filename;
00283     len = strlen(filename);
00284 
00285     avio_w8(pb, MAT_NAME);
00286     avio_w8(pb, strlen(SERVER_PATH) + len + 1);
00287     avio_write(pb, SERVER_PATH, sizeof(SERVER_PATH) - 1);
00288     avio_write(pb, filename, len);
00289     avio_w8(pb, 0);
00290 
00291     /* first field */
00292     avio_w8(pb, MAT_FIRST_FIELD);
00293     avio_w8(pb, 4);
00294     avio_wb32(pb, 0);
00295 
00296     /* last field */
00297     avio_w8(pb, MAT_LAST_FIELD);
00298     avio_w8(pb, 4);
00299     avio_wb32(pb, gxf->nb_fields);
00300 
00301     /* reserved */
00302     avio_w8(pb, MAT_MARK_IN);
00303     avio_w8(pb, 4);
00304     avio_wb32(pb, 0);
00305 
00306     avio_w8(pb, MAT_MARK_OUT);
00307     avio_w8(pb, 4);
00308     avio_wb32(pb, gxf->nb_fields);
00309 
00310     /* estimated size */
00311     avio_w8(pb, MAT_SIZE);
00312     avio_w8(pb, 4);
00313     avio_wb32(pb, avio_size(pb) / 1024);
00314 
00315     return updateSize(pb, pos);
00316 }
00317 
00318 static int gxf_write_track_description_section(AVFormatContext *s)
00319 {
00320     GXFContext *gxf = s->priv_data;
00321     AVIOContext *pb = s->pb;
00322     int64_t pos;
00323     int i;
00324 
00325     pos = avio_tell(pb);
00326     avio_wb16(pb, 0); /* size */
00327     for (i = 0; i < s->nb_streams; ++i)
00328         gxf_write_track_description(s, s->streams[i]->priv_data, i);
00329 
00330     gxf_write_track_description(s, &gxf->timecode_track, s->nb_streams);
00331 
00332     return updateSize(pb, pos);
00333 }
00334 
00335 static int gxf_write_map_packet(AVFormatContext *s, int rewrite)
00336 {
00337     GXFContext *gxf = s->priv_data;
00338     AVIOContext *pb = s->pb;
00339     int64_t pos = avio_tell(pb);
00340 
00341     if (!rewrite) {
00342         if (!(gxf->map_offsets_nb % 30)) {
00343             gxf->map_offsets = av_realloc(gxf->map_offsets,
00344                                           (gxf->map_offsets_nb+30)*sizeof(*gxf->map_offsets));
00345             if (!gxf->map_offsets) {
00346                 av_log(s, AV_LOG_ERROR, "could not realloc map offsets\n");
00347                 return -1;
00348             }
00349         }
00350         gxf->map_offsets[gxf->map_offsets_nb++] = pos; // do not increment here
00351     }
00352 
00353     gxf_write_packet_header(pb, PKT_MAP);
00354 
00355     /* preamble */
00356     avio_w8(pb, 0xE0); /* version */
00357     avio_w8(pb, 0xFF); /* reserved */
00358 
00359     gxf_write_material_data_section(s);
00360     gxf_write_track_description_section(s);
00361 
00362     return updatePacketSize(pb, pos);
00363 }
00364 
00365 static int gxf_write_flt_packet(AVFormatContext *s)
00366 {
00367     GXFContext *gxf = s->priv_data;
00368     AVIOContext *pb = s->pb;
00369     int64_t pos = avio_tell(pb);
00370     int fields_per_flt = (gxf->nb_fields+1) / 1000 + 1;
00371     int flt_entries = gxf->nb_fields / fields_per_flt;
00372     int i = 0;
00373 
00374     gxf_write_packet_header(pb, PKT_FLT);
00375 
00376     avio_wl32(pb, fields_per_flt); /* number of fields */
00377     avio_wl32(pb, flt_entries); /* number of active flt entries */
00378 
00379     if (gxf->flt_entries) {
00380         for (i = 0; i < flt_entries; i++)
00381             avio_wl32(pb, gxf->flt_entries[(i*fields_per_flt)>>1]);
00382     }
00383 
00384     for (; i < 1000; i++)
00385         avio_wl32(pb, 0);
00386 
00387     return updatePacketSize(pb, pos);
00388 }
00389 
00390 static int gxf_write_umf_material_description(AVFormatContext *s)
00391 {
00392     GXFContext *gxf = s->priv_data;
00393     AVIOContext *pb = s->pb;
00394     int timecode_base = gxf->time_base.den == 60000 ? 60 : 50;
00395 
00396     // XXX drop frame
00397     uint32_t timecode =
00398         gxf->nb_fields / (timecode_base * 3600) % 24 << 24 | // hours
00399         gxf->nb_fields / (timecode_base * 60) % 60   << 16 | // minutes
00400         gxf->nb_fields /  timecode_base % 60         <<  8 | // seconds
00401         gxf->nb_fields %  timecode_base;                     // fields
00402 
00403     avio_wl32(pb, gxf->flags);
00404     avio_wl32(pb, gxf->nb_fields); /* length of the longest track */
00405     avio_wl32(pb, gxf->nb_fields); /* length of the shortest track */
00406     avio_wl32(pb, 0); /* mark in */
00407     avio_wl32(pb, gxf->nb_fields); /* mark out */
00408     avio_wl32(pb, 0); /* timecode mark in */
00409     avio_wl32(pb, timecode); /* timecode mark out */
00410     avio_wl64(pb, s->timestamp); /* modification time */
00411     avio_wl64(pb, s->timestamp); /* creation time */
00412     avio_wl16(pb, 0); /* reserved */
00413     avio_wl16(pb, 0); /* reserved */
00414     avio_wl16(pb, gxf->audio_tracks);
00415     avio_wl16(pb, 1); /* timecode track count */
00416     avio_wl16(pb, 0); /* reserved */
00417     avio_wl16(pb, gxf->mpeg_tracks);
00418     return 48;
00419 }
00420 
00421 static int gxf_write_umf_payload(AVFormatContext *s)
00422 {
00423     GXFContext *gxf = s->priv_data;
00424     AVIOContext *pb = s->pb;
00425 
00426     avio_wl32(pb, gxf->umf_length); /* total length of the umf data */
00427     avio_wl32(pb, 3); /* version */
00428     avio_wl32(pb, s->nb_streams+1);
00429     avio_wl32(pb, gxf->umf_track_offset); /* umf track section offset */
00430     avio_wl32(pb, gxf->umf_track_size);
00431     avio_wl32(pb, s->nb_streams+1);
00432     avio_wl32(pb, gxf->umf_media_offset);
00433     avio_wl32(pb, gxf->umf_media_size);
00434     avio_wl32(pb, gxf->umf_length); /* user data offset */
00435     avio_wl32(pb, 0); /* user data size */
00436     avio_wl32(pb, 0); /* reserved */
00437     avio_wl32(pb, 0); /* reserved */
00438     return 48;
00439 }
00440 
00441 static int gxf_write_umf_track_description(AVFormatContext *s)
00442 {
00443     AVIOContext *pb = s->pb;
00444     GXFContext *gxf = s->priv_data;
00445     int64_t pos = avio_tell(pb);
00446     int i;
00447 
00448     gxf->umf_track_offset = pos - gxf->umf_start_offset;
00449     for (i = 0; i < s->nb_streams; ++i) {
00450         GXFStreamContext *sc = s->streams[i]->priv_data;
00451         avio_wl16(pb, sc->media_info);
00452         avio_wl16(pb, 1);
00453     }
00454 
00455     avio_wl16(pb, gxf->timecode_track.media_info);
00456     avio_wl16(pb, 1);
00457 
00458     return avio_tell(pb) - pos;
00459 }
00460 
00461 static int gxf_write_umf_media_mpeg(AVIOContext *pb, AVStream *st)
00462 {
00463     GXFStreamContext *sc = st->priv_data;
00464 
00465     if (st->codec->pix_fmt == PIX_FMT_YUV422P)
00466         avio_wl32(pb, 2);
00467     else
00468         avio_wl32(pb, 1); /* default to 420 */
00469     avio_wl32(pb, sc->first_gop_closed == 1); /* closed = 1, open = 0, unknown = 255 */
00470     avio_wl32(pb, 3); /* top = 1, bottom = 2, frame = 3, unknown = 0 */
00471     avio_wl32(pb, 1); /* I picture per GOP */
00472     avio_wl32(pb, sc->p_per_gop);
00473     avio_wl32(pb, sc->b_per_i_or_p);
00474     if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO)
00475         avio_wl32(pb, 2);
00476     else if (st->codec->codec_id == CODEC_ID_MPEG1VIDEO)
00477         avio_wl32(pb, 1);
00478     else
00479         avio_wl32(pb, 0);
00480     avio_wl32(pb, 0); /* reserved */
00481     return 32;
00482 }
00483 
00484 static int gxf_write_umf_media_timecode(AVIOContext *pb, GXFStreamContext *sc)
00485 {
00486     avio_wl32(pb, 1); /* non drop frame */
00487     avio_wl32(pb, 0); /* reserved */
00488     avio_wl32(pb, 0); /* reserved */
00489     avio_wl32(pb, 0); /* reserved */
00490     avio_wl32(pb, 0); /* reserved */
00491     avio_wl32(pb, 0); /* reserved */
00492     avio_wl32(pb, 0); /* reserved */
00493     avio_wl32(pb, 0); /* reserved */
00494     return 32;
00495 }
00496 
00497 static int gxf_write_umf_media_dv(AVIOContext *pb, GXFStreamContext *sc)
00498 {
00499     int i;
00500 
00501     for (i = 0; i < 8; i++) {
00502         avio_wb32(pb, 0);
00503     }
00504     return 32;
00505 }
00506 
00507 static int gxf_write_umf_media_audio(AVIOContext *pb, GXFStreamContext *sc)
00508 {
00509     avio_wl64(pb, av_dbl2int(1)); /* sound level to begin to */
00510     avio_wl64(pb, av_dbl2int(1)); /* sound level to begin to */
00511     avio_wl32(pb, 0); /* number of fields over which to ramp up sound level */
00512     avio_wl32(pb, 0); /* number of fields over which to ramp down sound level */
00513     avio_wl32(pb, 0); /* reserved */
00514     avio_wl32(pb, 0); /* reserved */
00515     return 32;
00516 }
00517 
00518 #if 0
00519 static int gxf_write_umf_media_mjpeg(AVIOContext *pb, GXFStreamContext *sc)
00520 {
00521     avio_wb64(pb, 0); /* FIXME FLOAT max chroma quant level */
00522     avio_wb64(pb, 0); /* FIXME FLOAT max luma quant level */
00523     avio_wb64(pb, 0); /* FIXME FLOAT min chroma quant level */
00524     avio_wb64(pb, 0); /* FIXME FLOAT min luma quant level */
00525     return 32;
00526 }
00527 #endif
00528 
00529 static int gxf_write_umf_media_description(AVFormatContext *s)
00530 {
00531     GXFContext *gxf = s->priv_data;
00532     AVIOContext *pb = s->pb;
00533     int64_t pos;
00534     int i, j;
00535 
00536     pos = avio_tell(pb);
00537     gxf->umf_media_offset = pos - gxf->umf_start_offset;
00538     for (i = 0; i <= s->nb_streams; ++i) {
00539         GXFStreamContext *sc;
00540         int64_t startpos, curpos;
00541 
00542         if (i == s->nb_streams)
00543             sc = &gxf->timecode_track;
00544         else
00545             sc = s->streams[i]->priv_data;
00546 
00547         startpos = avio_tell(pb);
00548         avio_wl16(pb, 0); /* length */
00549         avio_wl16(pb, sc->media_info);
00550         avio_wl16(pb, 0); /* reserved */
00551         avio_wl16(pb, 0); /* reserved */
00552         avio_wl32(pb, gxf->nb_fields);
00553         avio_wl32(pb, 0); /* attributes rw, ro */
00554         avio_wl32(pb, 0); /* mark in */
00555         avio_wl32(pb, gxf->nb_fields); /* mark out */
00556         avio_write(pb, ES_NAME_PATTERN, strlen(ES_NAME_PATTERN));
00557         avio_wb16(pb, sc->media_info);
00558         for (j = strlen(ES_NAME_PATTERN)+2; j < 88; j++)
00559             avio_w8(pb, 0);
00560         avio_wl32(pb, sc->track_type);
00561         avio_wl32(pb, sc->sample_rate);
00562         avio_wl32(pb, sc->sample_size);
00563         avio_wl32(pb, 0); /* reserved */
00564 
00565         if (sc == &gxf->timecode_track)
00566             gxf_write_umf_media_timecode(pb, sc); /* 8 0bytes */
00567         else {
00568             AVStream *st = s->streams[i];
00569             switch (st->codec->codec_id) {
00570             case CODEC_ID_MPEG1VIDEO:
00571             case CODEC_ID_MPEG2VIDEO:
00572                 gxf_write_umf_media_mpeg(pb, st);
00573                 break;
00574             case CODEC_ID_PCM_S16LE:
00575                 gxf_write_umf_media_audio(pb, sc);
00576                 break;
00577             case CODEC_ID_DVVIDEO:
00578                 gxf_write_umf_media_dv(pb, sc);
00579                 break;
00580             }
00581         }
00582 
00583         curpos = avio_tell(pb);
00584         avio_seek(pb, startpos, SEEK_SET);
00585         avio_wl16(pb, curpos - startpos);
00586         avio_seek(pb, curpos, SEEK_SET);
00587     }
00588     return avio_tell(pb) - pos;
00589 }
00590 
00591 static int gxf_write_umf_packet(AVFormatContext *s)
00592 {
00593     GXFContext *gxf = s->priv_data;
00594     AVIOContext *pb = s->pb;
00595     int64_t pos = avio_tell(pb);
00596 
00597     gxf_write_packet_header(pb, PKT_UMF);
00598 
00599     /* preamble */
00600     avio_w8(pb, 3); /* first and last (only) packet */
00601     avio_wb32(pb, gxf->umf_length); /* data length */
00602 
00603     gxf->umf_start_offset = avio_tell(pb);
00604     gxf_write_umf_payload(s);
00605     gxf_write_umf_material_description(s);
00606     gxf->umf_track_size = gxf_write_umf_track_description(s);
00607     gxf->umf_media_size = gxf_write_umf_media_description(s);
00608     gxf->umf_length = avio_tell(pb) - gxf->umf_start_offset;
00609     return updatePacketSize(pb, pos);
00610 }
00611 
00612 static const int GXF_samples_per_frame[] = { 32768, 0 };
00613 
00614 static void gxf_init_timecode_track(GXFStreamContext *sc, GXFStreamContext *vsc)
00615 {
00616     if (!vsc)
00617         return;
00618 
00619     sc->media_type = vsc->sample_rate == 60 ? 7 : 8;
00620     sc->sample_rate = vsc->sample_rate;
00621     sc->media_info = ('T'<<8) | '0';
00622     sc->track_type = 3;
00623     sc->frame_rate_index = vsc->frame_rate_index;
00624     sc->lines_index = vsc->lines_index;
00625     sc->sample_size = 16;
00626     sc->fields = vsc->fields;
00627 }
00628 
00629 static int gxf_write_header(AVFormatContext *s)
00630 {
00631     AVIOContext *pb = s->pb;
00632     GXFContext *gxf = s->priv_data;
00633     GXFStreamContext *vsc = NULL;
00634     uint8_t tracks[255] = {0};
00635     int i, media_info = 0;
00636 
00637     if (!pb->seekable) {
00638         av_log(s, AV_LOG_ERROR, "gxf muxer does not support streamed output, patch welcome");
00639         return -1;
00640     }
00641 
00642     gxf->flags |= 0x00080000; /* material is simple clip */
00643     for (i = 0; i < s->nb_streams; ++i) {
00644         AVStream *st = s->streams[i];
00645         GXFStreamContext *sc = av_mallocz(sizeof(*sc));
00646         if (!sc)
00647             return AVERROR(ENOMEM);
00648         st->priv_data = sc;
00649 
00650         sc->media_type = ff_codec_get_tag(gxf_media_types, st->codec->codec_id);
00651         if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
00652             if (st->codec->codec_id != CODEC_ID_PCM_S16LE) {
00653                 av_log(s, AV_LOG_ERROR, "only 16 BIT PCM LE allowed for now\n");
00654                 return -1;
00655             }
00656             if (st->codec->sample_rate != 48000) {
00657                 av_log(s, AV_LOG_ERROR, "only 48000hz sampling rate is allowed\n");
00658                 return -1;
00659             }
00660             if (st->codec->channels != 1) {
00661                 av_log(s, AV_LOG_ERROR, "only mono tracks are allowed\n");
00662                 return -1;
00663             }
00664             sc->track_type = 2;
00665             sc->sample_rate = st->codec->sample_rate;
00666             av_set_pts_info(st, 64, 1, sc->sample_rate);
00667             sc->sample_size = 16;
00668             sc->frame_rate_index = -2;
00669             sc->lines_index = -2;
00670             sc->fields = -2;
00671             gxf->audio_tracks++;
00672             gxf->flags |= 0x04000000; /* audio is 16 bit pcm */
00673             media_info = 'A';
00674         } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
00675             if (i != 0) {
00676                 av_log(s, AV_LOG_ERROR, "video stream must be the first track\n");
00677                 return -1;
00678             }
00679             /* FIXME check from time_base ? */
00680             if (st->codec->height == 480 || st->codec->height == 512) { /* NTSC or NTSC+VBI */
00681                 sc->frame_rate_index = 5;
00682                 sc->sample_rate = 60;
00683                 gxf->flags |= 0x00000080;
00684                 gxf->time_base = (AVRational){ 1001, 60000 };
00685             } else if (st->codec->height == 576 || st->codec->height == 608) { /* PAL or PAL+VBI */
00686                 sc->frame_rate_index = 6;
00687                 sc->media_type++;
00688                 sc->sample_rate = 50;
00689                 gxf->flags |= 0x00000040;
00690                 gxf->time_base = (AVRational){ 1, 50 };
00691             } else {
00692                 av_log(s, AV_LOG_ERROR, "unsupported video resolution, "
00693                        "gxf muxer only accepts PAL or NTSC resolutions currently\n");
00694                 return -1;
00695             }
00696             av_set_pts_info(st, 64, gxf->time_base.num, gxf->time_base.den);
00697             if (gxf_find_lines_index(st) < 0)
00698                 sc->lines_index = -1;
00699             sc->sample_size = st->codec->bit_rate;
00700             sc->fields = 2; /* interlaced */
00701 
00702             vsc = sc;
00703 
00704             switch (st->codec->codec_id) {
00705             case CODEC_ID_MJPEG:
00706                 sc->track_type = 1;
00707                 gxf->flags |= 0x00004000;
00708                 media_info = 'J';
00709                 break;
00710             case CODEC_ID_MPEG1VIDEO:
00711                 sc->track_type = 9;
00712                 gxf->mpeg_tracks++;
00713                 media_info = 'L';
00714                 break;
00715             case CODEC_ID_MPEG2VIDEO:
00716                 sc->first_gop_closed = -1;
00717                 sc->track_type = 4;
00718                 gxf->mpeg_tracks++;
00719                 gxf->flags |= 0x00008000;
00720                 media_info = 'M';
00721                 break;
00722             case CODEC_ID_DVVIDEO:
00723                 if (st->codec->pix_fmt == PIX_FMT_YUV422P) {
00724                     sc->media_type += 2;
00725                     sc->track_type = 6;
00726                     gxf->flags |= 0x00002000;
00727                     media_info = 'E';
00728                 } else {
00729                     sc->track_type = 5;
00730                     gxf->flags |= 0x00001000;
00731                     media_info = 'D';
00732                 }
00733                 break;
00734             default:
00735                 av_log(s, AV_LOG_ERROR, "video codec not supported\n");
00736                 return -1;
00737             }
00738         }
00739         /* FIXME first 10 audio tracks are 0 to 9 next 22 are A to V */
00740         sc->media_info = media_info<<8 | ('0'+tracks[media_info]++);
00741         sc->order = s->nb_streams - st->index;
00742     }
00743 
00744     if (ff_audio_interleave_init(s, GXF_samples_per_frame, (AVRational){ 1, 48000 }) < 0)
00745         return -1;
00746 
00747     gxf_init_timecode_track(&gxf->timecode_track, vsc);
00748     gxf->flags |= 0x200000; // time code track is non-drop frame
00749 
00750     gxf_write_map_packet(s, 0);
00751     gxf_write_flt_packet(s);
00752     gxf_write_umf_packet(s);
00753 
00754     gxf->packet_count = 3;
00755 
00756     avio_flush(pb);
00757     return 0;
00758 }
00759 
00760 static int gxf_write_eos_packet(AVIOContext *pb)
00761 {
00762     int64_t pos = avio_tell(pb);
00763 
00764     gxf_write_packet_header(pb, PKT_EOS);
00765     return updatePacketSize(pb, pos);
00766 }
00767 
00768 static int gxf_write_trailer(AVFormatContext *s)
00769 {
00770     GXFContext *gxf = s->priv_data;
00771     AVIOContext *pb = s->pb;
00772     int64_t end;
00773     int i;
00774 
00775     ff_audio_interleave_close(s);
00776 
00777     gxf_write_eos_packet(pb);
00778     end = avio_tell(pb);
00779     avio_seek(pb, 0, SEEK_SET);
00780     /* overwrite map, flt and umf packets with new values */
00781     gxf_write_map_packet(s, 1);
00782     gxf_write_flt_packet(s);
00783     gxf_write_umf_packet(s);
00784     avio_flush(pb);
00785     /* update duration in all map packets */
00786     for (i = 1; i < gxf->map_offsets_nb; i++) {
00787         avio_seek(pb, gxf->map_offsets[i], SEEK_SET);
00788         gxf_write_map_packet(s, 1);
00789         avio_flush(pb);
00790     }
00791 
00792     avio_seek(pb, end, SEEK_SET);
00793 
00794     av_freep(&gxf->flt_entries);
00795     av_freep(&gxf->map_offsets);
00796 
00797     return 0;
00798 }
00799 
00800 static int gxf_parse_mpeg_frame(GXFStreamContext *sc, const uint8_t *buf, int size)
00801 {
00802     uint32_t c=-1;
00803     int i;
00804     for(i=0; i<size-4 && c!=0x100; i++){
00805         c = (c<<8) + buf[i];
00806         if(c == 0x1B8 && sc->first_gop_closed == -1) /* GOP start code */
00807             sc->first_gop_closed= (buf[i+4]>>6)&1;
00808     }
00809     return (buf[i+1]>>3)&7;
00810 }
00811 
00812 static int gxf_write_media_preamble(AVFormatContext *s, AVPacket *pkt, int size)
00813 {
00814     GXFContext *gxf = s->priv_data;
00815     AVIOContext *pb = s->pb;
00816     AVStream *st = s->streams[pkt->stream_index];
00817     GXFStreamContext *sc = st->priv_data;
00818     unsigned field_nb;
00819     /* If the video is frame-encoded, the frame numbers shall be represented by
00820      * even field numbers.
00821      * see SMPTE360M-2004  6.4.2.1.3 Media field number */
00822     if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
00823         field_nb = gxf->nb_fields;
00824     } else {
00825         field_nb = av_rescale_rnd(pkt->dts, gxf->time_base.den,
00826                                   (int64_t)48000*gxf->time_base.num, AV_ROUND_UP);
00827     }
00828 
00829     avio_w8(pb, sc->media_type);
00830     avio_w8(pb, st->index);
00831     avio_wb32(pb, field_nb);
00832     if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
00833         avio_wb16(pb, 0);
00834         avio_wb16(pb, size / 2);
00835     } else if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO) {
00836         int frame_type = gxf_parse_mpeg_frame(sc, pkt->data, pkt->size);
00837         if (frame_type == AV_PICTURE_TYPE_I) {
00838             avio_w8(pb, 0x0d);
00839             sc->iframes++;
00840         } else if (frame_type == AV_PICTURE_TYPE_B) {
00841             avio_w8(pb, 0x0f);
00842             sc->bframes++;
00843         } else {
00844             avio_w8(pb, 0x0e);
00845             sc->pframes++;
00846         }
00847         avio_wb24(pb, size);
00848     } else if (st->codec->codec_id == CODEC_ID_DVVIDEO) {
00849         avio_w8(pb, size / 4096);
00850         avio_wb24(pb, 0);
00851     } else
00852         avio_wb32(pb, size);
00853     avio_wb32(pb, field_nb);
00854     avio_w8(pb, 1); /* flags */
00855     avio_w8(pb, 0); /* reserved */
00856     return 16;
00857 }
00858 
00859 static int gxf_write_packet(AVFormatContext *s, AVPacket *pkt)
00860 {
00861     GXFContext *gxf = s->priv_data;
00862     AVIOContext *pb = s->pb;
00863     AVStream *st = s->streams[pkt->stream_index];
00864     int64_t pos = avio_tell(pb);
00865     int padding = 0;
00866     int packet_start_offset = avio_tell(pb) / 1024;
00867 
00868     gxf_write_packet_header(pb, PKT_MEDIA);
00869     if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO && pkt->size % 4) /* MPEG-2 frames must be padded */
00870         padding = 4 - pkt->size % 4;
00871     else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
00872         padding = GXF_AUDIO_PACKET_SIZE - pkt->size;
00873     gxf_write_media_preamble(s, pkt, pkt->size + padding);
00874     avio_write(pb, pkt->data, pkt->size);
00875     gxf_write_padding(pb, padding);
00876 
00877     if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
00878         if (!(gxf->flt_entries_nb % 500)) {
00879             gxf->flt_entries = av_realloc(gxf->flt_entries,
00880                                           (gxf->flt_entries_nb+500)*sizeof(*gxf->flt_entries));
00881             if (!gxf->flt_entries) {
00882                 av_log(s, AV_LOG_ERROR, "could not reallocate flt entries\n");
00883                 return -1;
00884             }
00885         }
00886         gxf->flt_entries[gxf->flt_entries_nb++] = packet_start_offset;
00887         gxf->nb_fields += 2; // count fields
00888     }
00889 
00890     updatePacketSize(pb, pos);
00891 
00892     gxf->packet_count++;
00893     if (gxf->packet_count == 100) {
00894         gxf_write_map_packet(s, 0);
00895         gxf->packet_count = 0;
00896     }
00897 
00898     avio_flush(pb);
00899 
00900     return 0;
00901 }
00902 
00903 static int gxf_compare_field_nb(AVFormatContext *s, AVPacket *next, AVPacket *cur)
00904 {
00905     GXFContext *gxf = s->priv_data;
00906     AVPacket *pkt[2] = { cur, next };
00907     int i, field_nb[2];
00908     GXFStreamContext *sc[2];
00909 
00910     for (i = 0; i < 2; i++) {
00911         AVStream *st = s->streams[pkt[i]->stream_index];
00912         sc[i] = st->priv_data;
00913         if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
00914             field_nb[i] = av_rescale_rnd(pkt[i]->dts, gxf->time_base.den,
00915                                          (int64_t)48000*gxf->time_base.num, AV_ROUND_UP);
00916             field_nb[i] &= ~1; // compare against even field number because audio must be before video
00917         } else
00918             field_nb[i] = pkt[i]->dts; // dts are field based
00919     }
00920 
00921     return field_nb[1] > field_nb[0] ||
00922         (field_nb[1] == field_nb[0] && sc[1]->order > sc[0]->order);
00923 }
00924 
00925 static int gxf_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush)
00926 {
00927     if (pkt && s->streams[pkt->stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
00928         pkt->duration = 2; // enforce 2 fields
00929     return ff_audio_rechunk_interleave(s, out, pkt, flush,
00930                                av_interleave_packet_per_dts, gxf_compare_field_nb);
00931 }
00932 
00933 AVOutputFormat ff_gxf_muxer = {
00934     "gxf",
00935     NULL_IF_CONFIG_SMALL("GXF format"),
00936     NULL,
00937     "gxf",
00938     sizeof(GXFContext),
00939     CODEC_ID_PCM_S16LE,
00940     CODEC_ID_MPEG2VIDEO,
00941     gxf_write_header,
00942     gxf_write_packet,
00943     gxf_write_trailer,
00944     0,
00945     NULL,
00946     gxf_interleave_packet,
00947 };