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