• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • 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(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_f(gxf->map_offsets,
00344                                             sizeof(*gxf->map_offsets),
00345                                             gxf->map_offsets_nb+30);
00346             if (!gxf->map_offsets) {
00347                 av_log(s, AV_LOG_ERROR, "could not realloc map offsets\n");
00348                 return -1;
00349             }
00350         }
00351         gxf->map_offsets[gxf->map_offsets_nb++] = pos; // do not increment here
00352     }
00353 
00354     gxf_write_packet_header(pb, PKT_MAP);
00355 
00356     /* preamble */
00357     avio_w8(pb, 0xE0); /* version */
00358     avio_w8(pb, 0xFF); /* reserved */
00359 
00360     gxf_write_material_data_section(s);
00361     gxf_write_track_description_section(s);
00362 
00363     return updatePacketSize(pb, pos);
00364 }
00365 
00366 static int gxf_write_flt_packet(AVFormatContext *s)
00367 {
00368     GXFContext *gxf = s->priv_data;
00369     AVIOContext *pb = s->pb;
00370     int64_t pos = avio_tell(pb);
00371     int fields_per_flt = (gxf->nb_fields+1) / 1000 + 1;
00372     int flt_entries = gxf->nb_fields / fields_per_flt;
00373     int i = 0;
00374 
00375     gxf_write_packet_header(pb, PKT_FLT);
00376 
00377     avio_wl32(pb, fields_per_flt); /* number of fields */
00378     avio_wl32(pb, flt_entries); /* number of active flt entries */
00379 
00380     if (gxf->flt_entries) {
00381         for (i = 0; i < flt_entries; i++)
00382             avio_wl32(pb, gxf->flt_entries[(i*fields_per_flt)>>1]);
00383     }
00384 
00385     for (; i < 1000; i++)
00386         avio_wl32(pb, 0);
00387 
00388     return updatePacketSize(pb, pos);
00389 }
00390 
00391 static int gxf_write_umf_material_description(AVFormatContext *s)
00392 {
00393     GXFContext *gxf = s->priv_data;
00394     AVIOContext *pb = s->pb;
00395     int timecode_base = gxf->time_base.den == 60000 ? 60 : 50;
00396 
00397     // XXX drop frame
00398     uint32_t timecode =
00399         gxf->nb_fields / (timecode_base * 3600) % 24 << 24 | // hours
00400         gxf->nb_fields / (timecode_base * 60) % 60   << 16 | // minutes
00401         gxf->nb_fields /  timecode_base % 60         <<  8 | // seconds
00402         gxf->nb_fields %  timecode_base;                     // fields
00403 
00404     avio_wl32(pb, gxf->flags);
00405     avio_wl32(pb, gxf->nb_fields); /* length of the longest track */
00406     avio_wl32(pb, gxf->nb_fields); /* length of the shortest track */
00407     avio_wl32(pb, 0); /* mark in */
00408     avio_wl32(pb, gxf->nb_fields); /* mark out */
00409     avio_wl32(pb, 0); /* timecode mark in */
00410     avio_wl32(pb, timecode); /* timecode mark out */
00411     avio_wl64(pb, s->timestamp); /* modification time */
00412     avio_wl64(pb, s->timestamp); /* creation time */
00413     avio_wl16(pb, 0); /* reserved */
00414     avio_wl16(pb, 0); /* reserved */
00415     avio_wl16(pb, gxf->audio_tracks);
00416     avio_wl16(pb, 1); /* timecode track count */
00417     avio_wl16(pb, 0); /* reserved */
00418     avio_wl16(pb, gxf->mpeg_tracks);
00419     return 48;
00420 }
00421 
00422 static int gxf_write_umf_payload(AVFormatContext *s)
00423 {
00424     GXFContext *gxf = s->priv_data;
00425     AVIOContext *pb = s->pb;
00426 
00427     avio_wl32(pb, gxf->umf_length); /* total length of the umf data */
00428     avio_wl32(pb, 3); /* version */
00429     avio_wl32(pb, s->nb_streams+1);
00430     avio_wl32(pb, gxf->umf_track_offset); /* umf track section offset */
00431     avio_wl32(pb, gxf->umf_track_size);
00432     avio_wl32(pb, s->nb_streams+1);
00433     avio_wl32(pb, gxf->umf_media_offset);
00434     avio_wl32(pb, gxf->umf_media_size);
00435     avio_wl32(pb, gxf->umf_length); /* user data offset */
00436     avio_wl32(pb, 0); /* user data size */
00437     avio_wl32(pb, 0); /* reserved */
00438     avio_wl32(pb, 0); /* reserved */
00439     return 48;
00440 }
00441 
00442 static int gxf_write_umf_track_description(AVFormatContext *s)
00443 {
00444     AVIOContext *pb = s->pb;
00445     GXFContext *gxf = s->priv_data;
00446     int64_t pos = avio_tell(pb);
00447     int i;
00448 
00449     gxf->umf_track_offset = pos - gxf->umf_start_offset;
00450     for (i = 0; i < s->nb_streams; ++i) {
00451         GXFStreamContext *sc = s->streams[i]->priv_data;
00452         avio_wl16(pb, sc->media_info);
00453         avio_wl16(pb, 1);
00454     }
00455 
00456     avio_wl16(pb, gxf->timecode_track.media_info);
00457     avio_wl16(pb, 1);
00458 
00459     return avio_tell(pb) - pos;
00460 }
00461 
00462 static int gxf_write_umf_media_mpeg(AVIOContext *pb, AVStream *st)
00463 {
00464     GXFStreamContext *sc = st->priv_data;
00465 
00466     if (st->codec->pix_fmt == PIX_FMT_YUV422P)
00467         avio_wl32(pb, 2);
00468     else
00469         avio_wl32(pb, 1); /* default to 420 */
00470     avio_wl32(pb, sc->first_gop_closed == 1); /* closed = 1, open = 0, unknown = 255 */
00471     avio_wl32(pb, 3); /* top = 1, bottom = 2, frame = 3, unknown = 0 */
00472     avio_wl32(pb, 1); /* I picture per GOP */
00473     avio_wl32(pb, sc->p_per_gop);
00474     avio_wl32(pb, sc->b_per_i_or_p);
00475     if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO)
00476         avio_wl32(pb, 2);
00477     else if (st->codec->codec_id == CODEC_ID_MPEG1VIDEO)
00478         avio_wl32(pb, 1);
00479     else
00480         avio_wl32(pb, 0);
00481     avio_wl32(pb, 0); /* reserved */
00482     return 32;
00483 }
00484 
00485 static int gxf_write_umf_media_timecode(AVIOContext *pb, GXFStreamContext *sc)
00486 {
00487     avio_wl32(pb, 1); /* non drop frame */
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     avio_wl32(pb, 0); /* reserved */
00495     return 32;
00496 }
00497 
00498 static int gxf_write_umf_media_dv(AVIOContext *pb, GXFStreamContext *sc)
00499 {
00500     int i;
00501 
00502     for (i = 0; i < 8; i++) {
00503         avio_wb32(pb, 0);
00504     }
00505     return 32;
00506 }
00507 
00508 static int gxf_write_umf_media_audio(AVIOContext *pb, GXFStreamContext *sc)
00509 {
00510     avio_wl64(pb, av_dbl2int(1)); /* sound level to begin to */
00511     avio_wl64(pb, av_dbl2int(1)); /* sound level to begin to */
00512     avio_wl32(pb, 0); /* number of fields over which to ramp up sound level */
00513     avio_wl32(pb, 0); /* number of fields over which to ramp down sound level */
00514     avio_wl32(pb, 0); /* reserved */
00515     avio_wl32(pb, 0); /* reserved */
00516     return 32;
00517 }
00518 
00519 #if 0
00520 static int gxf_write_umf_media_mjpeg(AVIOContext *pb, GXFStreamContext *sc)
00521 {
00522     avio_wb64(pb, 0); /* FIXME FLOAT max chroma quant level */
00523     avio_wb64(pb, 0); /* FIXME FLOAT max luma quant level */
00524     avio_wb64(pb, 0); /* FIXME FLOAT min chroma quant level */
00525     avio_wb64(pb, 0); /* FIXME FLOAT min luma quant level */
00526     return 32;
00527 }
00528 #endif
00529 
00530 static int gxf_write_umf_media_description(AVFormatContext *s)
00531 {
00532     GXFContext *gxf = s->priv_data;
00533     AVIOContext *pb = s->pb;
00534     int64_t pos;
00535     int i, j;
00536 
00537     pos = avio_tell(pb);
00538     gxf->umf_media_offset = pos - gxf->umf_start_offset;
00539     for (i = 0; i <= s->nb_streams; ++i) {
00540         GXFStreamContext *sc;
00541         int64_t startpos, curpos;
00542 
00543         if (i == s->nb_streams)
00544             sc = &gxf->timecode_track;
00545         else
00546             sc = s->streams[i]->priv_data;
00547 
00548         startpos = avio_tell(pb);
00549         avio_wl16(pb, 0); /* length */
00550         avio_wl16(pb, sc->media_info);
00551         avio_wl16(pb, 0); /* reserved */
00552         avio_wl16(pb, 0); /* reserved */
00553         avio_wl32(pb, gxf->nb_fields);
00554         avio_wl32(pb, 0); /* attributes rw, ro */
00555         avio_wl32(pb, 0); /* mark in */
00556         avio_wl32(pb, gxf->nb_fields); /* mark out */
00557         avio_write(pb, ES_NAME_PATTERN, strlen(ES_NAME_PATTERN));
00558         avio_wb16(pb, sc->media_info);
00559         for (j = strlen(ES_NAME_PATTERN)+2; j < 88; j++)
00560             avio_w8(pb, 0);
00561         avio_wl32(pb, sc->track_type);
00562         avio_wl32(pb, sc->sample_rate);
00563         avio_wl32(pb, sc->sample_size);
00564         avio_wl32(pb, 0); /* reserved */
00565 
00566         if (sc == &gxf->timecode_track)
00567             gxf_write_umf_media_timecode(pb, sc); /* 8 0bytes */
00568         else {
00569             AVStream *st = s->streams[i];
00570             switch (st->codec->codec_id) {
00571             case CODEC_ID_MPEG1VIDEO:
00572             case CODEC_ID_MPEG2VIDEO:
00573                 gxf_write_umf_media_mpeg(pb, st);
00574                 break;
00575             case CODEC_ID_PCM_S16LE:
00576                 gxf_write_umf_media_audio(pb, sc);
00577                 break;
00578             case CODEC_ID_DVVIDEO:
00579                 gxf_write_umf_media_dv(pb, sc);
00580                 break;
00581             }
00582         }
00583 
00584         curpos = avio_tell(pb);
00585         avio_seek(pb, startpos, SEEK_SET);
00586         avio_wl16(pb, curpos - startpos);
00587         avio_seek(pb, curpos, SEEK_SET);
00588     }
00589     return avio_tell(pb) - pos;
00590 }
00591 
00592 static int gxf_write_umf_packet(AVFormatContext *s)
00593 {
00594     GXFContext *gxf = s->priv_data;
00595     AVIOContext *pb = s->pb;
00596     int64_t pos = avio_tell(pb);
00597 
00598     gxf_write_packet_header(pb, PKT_UMF);
00599 
00600     /* preamble */
00601     avio_w8(pb, 3); /* first and last (only) packet */
00602     avio_wb32(pb, gxf->umf_length); /* data length */
00603 
00604     gxf->umf_start_offset = avio_tell(pb);
00605     gxf_write_umf_payload(s);
00606     gxf_write_umf_material_description(s);
00607     gxf->umf_track_size = gxf_write_umf_track_description(s);
00608     gxf->umf_media_size = gxf_write_umf_media_description(s);
00609     gxf->umf_length = avio_tell(pb) - gxf->umf_start_offset;
00610     return updatePacketSize(pb, pos);
00611 }
00612 
00613 static const int GXF_samples_per_frame[] = { 32768, 0 };
00614 
00615 static void gxf_init_timecode_track(GXFStreamContext *sc, GXFStreamContext *vsc)
00616 {
00617     if (!vsc)
00618         return;
00619 
00620     sc->media_type = vsc->sample_rate == 60 ? 7 : 8;
00621     sc->sample_rate = vsc->sample_rate;
00622     sc->media_info = ('T'<<8) | '0';
00623     sc->track_type = 3;
00624     sc->frame_rate_index = vsc->frame_rate_index;
00625     sc->lines_index = vsc->lines_index;
00626     sc->sample_size = 16;
00627     sc->fields = vsc->fields;
00628 }
00629 
00630 static int gxf_write_header(AVFormatContext *s)
00631 {
00632     AVIOContext *pb = s->pb;
00633     GXFContext *gxf = s->priv_data;
00634     GXFStreamContext *vsc = NULL;
00635     uint8_t tracks[255] = {0};
00636     int i, media_info = 0;
00637 
00638     if (!pb->seekable) {
00639         av_log(s, AV_LOG_ERROR, "gxf muxer does not support streamed output, patch welcome");
00640         return -1;
00641     }
00642 
00643     gxf->flags |= 0x00080000; /* material is simple clip */
00644     for (i = 0; i < s->nb_streams; ++i) {
00645         AVStream *st = s->streams[i];
00646         GXFStreamContext *sc = av_mallocz(sizeof(*sc));
00647         if (!sc)
00648             return AVERROR(ENOMEM);
00649         st->priv_data = sc;
00650 
00651         sc->media_type = ff_codec_get_tag(gxf_media_types, st->codec->codec_id);
00652         if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
00653             if (st->codec->codec_id != CODEC_ID_PCM_S16LE) {
00654                 av_log(s, AV_LOG_ERROR, "only 16 BIT PCM LE allowed for now\n");
00655                 return -1;
00656             }
00657             if (st->codec->sample_rate != 48000) {
00658                 av_log(s, AV_LOG_ERROR, "only 48000hz sampling rate is allowed\n");
00659                 return -1;
00660             }
00661             if (st->codec->channels != 1) {
00662                 av_log(s, AV_LOG_ERROR, "only mono tracks are allowed\n");
00663                 return -1;
00664             }
00665             sc->track_type = 2;
00666             sc->sample_rate = st->codec->sample_rate;
00667             av_set_pts_info(st, 64, 1, sc->sample_rate);
00668             sc->sample_size = 16;
00669             sc->frame_rate_index = -2;
00670             sc->lines_index = -2;
00671             sc->fields = -2;
00672             gxf->audio_tracks++;
00673             gxf->flags |= 0x04000000; /* audio is 16 bit pcm */
00674             media_info = 'A';
00675         } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
00676             if (i != 0) {
00677                 av_log(s, AV_LOG_ERROR, "video stream must be the first track\n");
00678                 return -1;
00679             }
00680             /* FIXME check from time_base ? */
00681             if (st->codec->height == 480 || st->codec->height == 512) { /* NTSC or NTSC+VBI */
00682                 sc->frame_rate_index = 5;
00683                 sc->sample_rate = 60;
00684                 gxf->flags |= 0x00000080;
00685                 gxf->time_base = (AVRational){ 1001, 60000 };
00686             } else if (st->codec->height == 576 || st->codec->height == 608) { /* PAL or PAL+VBI */
00687                 sc->frame_rate_index = 6;
00688                 sc->media_type++;
00689                 sc->sample_rate = 50;
00690                 gxf->flags |= 0x00000040;
00691                 gxf->time_base = (AVRational){ 1, 50 };
00692             } else {
00693                 av_log(s, AV_LOG_ERROR, "unsupported video resolution, "
00694                        "gxf muxer only accepts PAL or NTSC resolutions currently\n");
00695                 return -1;
00696             }
00697             av_set_pts_info(st, 64, gxf->time_base.num, gxf->time_base.den);
00698             if (gxf_find_lines_index(st) < 0)
00699                 sc->lines_index = -1;
00700             sc->sample_size = st->codec->bit_rate;
00701             sc->fields = 2; /* interlaced */
00702 
00703             vsc = sc;
00704 
00705             switch (st->codec->codec_id) {
00706             case CODEC_ID_MJPEG:
00707                 sc->track_type = 1;
00708                 gxf->flags |= 0x00004000;
00709                 media_info = 'J';
00710                 break;
00711             case CODEC_ID_MPEG1VIDEO:
00712                 sc->track_type = 9;
00713                 gxf->mpeg_tracks++;
00714                 media_info = 'L';
00715                 break;
00716             case CODEC_ID_MPEG2VIDEO:
00717                 sc->first_gop_closed = -1;
00718                 sc->track_type = 4;
00719                 gxf->mpeg_tracks++;
00720                 gxf->flags |= 0x00008000;
00721                 media_info = 'M';
00722                 break;
00723             case CODEC_ID_DVVIDEO:
00724                 if (st->codec->pix_fmt == PIX_FMT_YUV422P) {
00725                     sc->media_type += 2;
00726                     sc->track_type = 6;
00727                     gxf->flags |= 0x00002000;
00728                     media_info = 'E';
00729                 } else {
00730                     sc->track_type = 5;
00731                     gxf->flags |= 0x00001000;
00732                     media_info = 'D';
00733                 }
00734                 break;
00735             default:
00736                 av_log(s, AV_LOG_ERROR, "video codec not supported\n");
00737                 return -1;
00738             }
00739         }
00740         /* FIXME first 10 audio tracks are 0 to 9 next 22 are A to V */
00741         sc->media_info = media_info<<8 | ('0'+tracks[media_info]++);
00742         sc->order = s->nb_streams - st->index;
00743     }
00744 
00745     if (ff_audio_interleave_init(s, GXF_samples_per_frame, (AVRational){ 1, 48000 }) < 0)
00746         return -1;
00747 
00748     gxf_init_timecode_track(&gxf->timecode_track, vsc);
00749     gxf->flags |= 0x200000; // time code track is non-drop frame
00750 
00751     gxf_write_map_packet(s, 0);
00752     gxf_write_flt_packet(s);
00753     gxf_write_umf_packet(s);
00754 
00755     gxf->packet_count = 3;
00756 
00757     avio_flush(pb);
00758     return 0;
00759 }
00760 
00761 static int gxf_write_eos_packet(AVIOContext *pb)
00762 {
00763     int64_t pos = avio_tell(pb);
00764 
00765     gxf_write_packet_header(pb, PKT_EOS);
00766     return updatePacketSize(pb, pos);
00767 }
00768 
00769 static int gxf_write_trailer(AVFormatContext *s)
00770 {
00771     GXFContext *gxf = s->priv_data;
00772     AVIOContext *pb = s->pb;
00773     int64_t end;
00774     int i;
00775 
00776     ff_audio_interleave_close(s);
00777 
00778     gxf_write_eos_packet(pb);
00779     end = avio_tell(pb);
00780     avio_seek(pb, 0, SEEK_SET);
00781     /* overwrite map, flt and umf packets with new values */
00782     gxf_write_map_packet(s, 1);
00783     gxf_write_flt_packet(s);
00784     gxf_write_umf_packet(s);
00785     avio_flush(pb);
00786     /* update duration in all map packets */
00787     for (i = 1; i < gxf->map_offsets_nb; i++) {
00788         avio_seek(pb, gxf->map_offsets[i], SEEK_SET);
00789         gxf_write_map_packet(s, 1);
00790         avio_flush(pb);
00791     }
00792 
00793     avio_seek(pb, end, SEEK_SET);
00794 
00795     av_freep(&gxf->flt_entries);
00796     av_freep(&gxf->map_offsets);
00797 
00798     return 0;
00799 }
00800 
00801 static int gxf_parse_mpeg_frame(GXFStreamContext *sc, const uint8_t *buf, int size)
00802 {
00803     uint32_t c=-1;
00804     int i;
00805     for(i=0; i<size-4 && c!=0x100; i++){
00806         c = (c<<8) + buf[i];
00807         if(c == 0x1B8 && sc->first_gop_closed == -1) /* GOP start code */
00808             sc->first_gop_closed= (buf[i+4]>>6)&1;
00809     }
00810     return (buf[i+1]>>3)&7;
00811 }
00812 
00813 static int gxf_write_media_preamble(AVFormatContext *s, AVPacket *pkt, int size)
00814 {
00815     GXFContext *gxf = s->priv_data;
00816     AVIOContext *pb = s->pb;
00817     AVStream *st = s->streams[pkt->stream_index];
00818     GXFStreamContext *sc = st->priv_data;
00819     unsigned field_nb;
00820     /* If the video is frame-encoded, the frame numbers shall be represented by
00821      * even field numbers.
00822      * see SMPTE360M-2004  6.4.2.1.3 Media field number */
00823     if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
00824         field_nb = gxf->nb_fields;
00825     } else {
00826         field_nb = av_rescale_rnd(pkt->dts, gxf->time_base.den,
00827                                   (int64_t)48000*gxf->time_base.num, AV_ROUND_UP);
00828     }
00829 
00830     avio_w8(pb, sc->media_type);
00831     avio_w8(pb, st->index);
00832     avio_wb32(pb, field_nb);
00833     if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
00834         avio_wb16(pb, 0);
00835         avio_wb16(pb, size / 2);
00836     } else if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO) {
00837         int frame_type = gxf_parse_mpeg_frame(sc, pkt->data, pkt->size);
00838         if (frame_type == AV_PICTURE_TYPE_I) {
00839             avio_w8(pb, 0x0d);
00840             sc->iframes++;
00841         } else if (frame_type == AV_PICTURE_TYPE_B) {
00842             avio_w8(pb, 0x0f);
00843             sc->bframes++;
00844         } else {
00845             avio_w8(pb, 0x0e);
00846             sc->pframes++;
00847         }
00848         avio_wb24(pb, size);
00849     } else if (st->codec->codec_id == CODEC_ID_DVVIDEO) {
00850         avio_w8(pb, size / 4096);
00851         avio_wb24(pb, 0);
00852     } else
00853         avio_wb32(pb, size);
00854     avio_wb32(pb, field_nb);
00855     avio_w8(pb, 1); /* flags */
00856     avio_w8(pb, 0); /* reserved */
00857     return 16;
00858 }
00859 
00860 static int gxf_write_packet(AVFormatContext *s, AVPacket *pkt)
00861 {
00862     GXFContext *gxf = s->priv_data;
00863     AVIOContext *pb = s->pb;
00864     AVStream *st = s->streams[pkt->stream_index];
00865     int64_t pos = avio_tell(pb);
00866     int padding = 0;
00867     int packet_start_offset = avio_tell(pb) / 1024;
00868 
00869     gxf_write_packet_header(pb, PKT_MEDIA);
00870     if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO && pkt->size % 4) /* MPEG-2 frames must be padded */
00871         padding = 4 - pkt->size % 4;
00872     else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
00873         padding = GXF_AUDIO_PACKET_SIZE - pkt->size;
00874     gxf_write_media_preamble(s, pkt, pkt->size + padding);
00875     avio_write(pb, pkt->data, pkt->size);
00876     gxf_write_padding(pb, padding);
00877 
00878     if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
00879         if (!(gxf->flt_entries_nb % 500)) {
00880             gxf->flt_entries = av_realloc_f(gxf->flt_entries,
00881                                             sizeof(*gxf->flt_entries),
00882                                             gxf->flt_entries_nb+500);
00883             if (!gxf->flt_entries) {
00884                 av_log(s, AV_LOG_ERROR, "could not reallocate flt entries\n");
00885                 return -1;
00886             }
00887         }
00888         gxf->flt_entries[gxf->flt_entries_nb++] = packet_start_offset;
00889         gxf->nb_fields += 2; // count fields
00890     }
00891 
00892     updatePacketSize(pb, pos);
00893 
00894     gxf->packet_count++;
00895     if (gxf->packet_count == 100) {
00896         gxf_write_map_packet(s, 0);
00897         gxf->packet_count = 0;
00898     }
00899 
00900     avio_flush(pb);
00901 
00902     return 0;
00903 }
00904 
00905 static int gxf_compare_field_nb(AVFormatContext *s, AVPacket *next, AVPacket *cur)
00906 {
00907     GXFContext *gxf = s->priv_data;
00908     AVPacket *pkt[2] = { cur, next };
00909     int i, field_nb[2];
00910     GXFStreamContext *sc[2];
00911 
00912     for (i = 0; i < 2; i++) {
00913         AVStream *st = s->streams[pkt[i]->stream_index];
00914         sc[i] = st->priv_data;
00915         if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
00916             field_nb[i] = av_rescale_rnd(pkt[i]->dts, gxf->time_base.den,
00917                                          (int64_t)48000*gxf->time_base.num, AV_ROUND_UP);
00918             field_nb[i] &= ~1; // compare against even field number because audio must be before video
00919         } else
00920             field_nb[i] = pkt[i]->dts; // dts are field based
00921     }
00922 
00923     return field_nb[1] > field_nb[0] ||
00924         (field_nb[1] == field_nb[0] && sc[1]->order > sc[0]->order);
00925 }
00926 
00927 static int gxf_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush)
00928 {
00929     if (pkt && s->streams[pkt->stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
00930         pkt->duration = 2; // enforce 2 fields
00931     return ff_audio_rechunk_interleave(s, out, pkt, flush,
00932                                av_interleave_packet_per_dts, gxf_compare_field_nb);
00933 }
00934 
00935 AVOutputFormat ff_gxf_muxer = {
00936     "gxf",
00937     NULL_IF_CONFIG_SMALL("GXF format"),
00938     NULL,
00939     "gxf",
00940     sizeof(GXFContext),
00941     CODEC_ID_PCM_S16LE,
00942     CODEC_ID_MPEG2VIDEO,
00943     gxf_write_header,
00944     gxf_write_packet,
00945     gxf_write_trailer,
00946     0,
00947     NULL,
00948     gxf_interleave_packet,
00949 };

Generated on Fri Feb 22 2013 07:24:31 for FFmpeg by  doxygen 1.7.1