00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 #include "libavutil/intfloat.h"
00023 #include "libavutil/opt.h"
00024 #include "libavutil/mathematics.h"
00025 #include "libavutil/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 }, 
00093     { 512,  1 }, 
00094     { 576,  2 }, 
00095     { 608,  2 }, 
00096     { 1080, 4 },
00097     { 720,  6 },
00098 };
00099 
00100 static const AVCodecTag gxf_media_types[] = {
00101     { CODEC_ID_MJPEG     ,   3 }, 
00102     { CODEC_ID_MJPEG     ,   4 }, 
00103     { CODEC_ID_PCM_S24LE ,   9 },
00104     { CODEC_ID_PCM_S16LE ,  10 },
00105     { CODEC_ID_MPEG2VIDEO,  11 }, 
00106     { CODEC_ID_MPEG2VIDEO,  12 }, 
00107     { CODEC_ID_DVVIDEO   ,  13 }, 
00108     { CODEC_ID_DVVIDEO   ,  14 }, 
00109     { CODEC_ID_DVVIDEO   ,  15 }, 
00110     { CODEC_ID_DVVIDEO   ,  16 }, 
00111     { CODEC_ID_AC3       ,  17 },
00112     
00113     { CODEC_ID_MPEG2VIDEO,  20 }, 
00114     { CODEC_ID_MPEG1VIDEO,  22 }, 
00115     { CODEC_ID_MPEG1VIDEO,  23 }, 
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);  
00174     avio_w8(pb, 1);
00175     avio_w8(pb, type); 
00176     avio_wb32(pb, 0);  
00177     avio_wb32(pb, 0);  
00178     avio_w8(pb, 0xE1); 
00179     avio_w8(pb, 0xE2); 
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; 
00199         if (sc->b_per_i_or_p > 9)
00200             sc->b_per_i_or_p = 9; 
00201     }
00202     if (st->codec->height == 512 || st->codec->height == 608)
00203         starting_line = 7; 
00204     else if (st->codec->height == 480)
00205         starting_line = 20;
00206     else
00207         starting_line = 23; 
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     
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     
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); 
00245 
00246     
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         
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     
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     
00272     avio_w8(pb, TRACK_FPS);
00273     avio_w8(pb, 4);
00274     avio_wb32(pb, sc->frame_rate_index);
00275 
00276     
00277     avio_w8(pb, TRACK_LINES);
00278     avio_w8(pb, 4);
00279     avio_wb32(pb, sc->lines_index);
00280 
00281     
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); 
00299 
00300     
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     
00314     avio_w8(pb, MAT_FIRST_FIELD);
00315     avio_w8(pb, 4);
00316     avio_wb32(pb, 0);
00317 
00318     
00319     avio_w8(pb, MAT_LAST_FIELD);
00320     avio_w8(pb, 4);
00321     avio_wb32(pb, gxf->nb_fields);
00322 
00323     
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     
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); 
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; 
00374     }
00375 
00376     gxf_write_packet_header(pb, PKT_MAP);
00377 
00378     
00379     avio_w8(pb, 0xE0); 
00380     avio_w8(pb, 0xFF); 
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); 
00400     avio_wl32(pb, 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; 
00422     uint32_t timecode_out; 
00423 
00424     if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))
00425         timestamp = ff_iso8601_to_unix_time(t->value);
00426 
00427     timecode_in = GXF_TIMECODE(gxf->tc.color, gxf->tc.drop,
00428                                gxf->tc.hh, gxf->tc.mm,
00429                                gxf->tc.ss, gxf->tc.ff);
00430 
00431     nb_fields = gxf->nb_fields +
00432                 gxf->tc.hh * (timecode_base * 3600) +
00433                 gxf->tc.mm * (timecode_base * 60)   +
00434                 gxf->tc.ss * timecode_base          +
00435                 gxf->tc.ff;
00436 
00437     timecode_out = GXF_TIMECODE(gxf->tc.color, gxf->tc.drop,
00438                                 nb_fields / (timecode_base * 3600) % 24,
00439                                 nb_fields / (timecode_base * 60)   % 60,
00440                                 nb_fields /  timecode_base % 60,
00441                                 nb_fields %  timecode_base);
00442 
00443     avio_wl32(pb, gxf->flags);
00444     avio_wl32(pb, gxf->nb_fields); 
00445     avio_wl32(pb, gxf->nb_fields); 
00446     avio_wl32(pb, 0); 
00447     avio_wl32(pb, gxf->nb_fields); 
00448     avio_wl32(pb, timecode_in); 
00449     avio_wl32(pb, timecode_out); 
00450     avio_wl64(pb, timestamp); 
00451     avio_wl64(pb, timestamp); 
00452     avio_wl16(pb, 0); 
00453     avio_wl16(pb, 0); 
00454     avio_wl16(pb, gxf->audio_tracks);
00455     avio_wl16(pb, 1); 
00456     avio_wl16(pb, 0); 
00457     avio_wl16(pb, gxf->mpeg_tracks);
00458     return 48;
00459 }
00460 
00461 static int gxf_write_umf_payload(AVFormatContext *s)
00462 {
00463     GXFContext *gxf = s->priv_data;
00464     AVIOContext *pb = s->pb;
00465 
00466     avio_wl32(pb, gxf->umf_length); 
00467     avio_wl32(pb, 3); 
00468     avio_wl32(pb, s->nb_streams+1);
00469     avio_wl32(pb, gxf->umf_track_offset); 
00470     avio_wl32(pb, gxf->umf_track_size);
00471     avio_wl32(pb, s->nb_streams+1);
00472     avio_wl32(pb, gxf->umf_media_offset);
00473     avio_wl32(pb, gxf->umf_media_size);
00474     avio_wl32(pb, gxf->umf_length); 
00475     avio_wl32(pb, 0); 
00476     avio_wl32(pb, 0); 
00477     avio_wl32(pb, 0); 
00478     return 48;
00479 }
00480 
00481 static int gxf_write_umf_track_description(AVFormatContext *s)
00482 {
00483     AVIOContext *pb = s->pb;
00484     GXFContext *gxf = s->priv_data;
00485     int64_t pos = avio_tell(pb);
00486     int i;
00487 
00488     gxf->umf_track_offset = pos - gxf->umf_start_offset;
00489     for (i = 0; i < s->nb_streams; ++i) {
00490         GXFStreamContext *sc = s->streams[i]->priv_data;
00491         avio_wl16(pb, sc->media_info);
00492         avio_wl16(pb, 1);
00493     }
00494 
00495     avio_wl16(pb, gxf->timecode_track.media_info);
00496     avio_wl16(pb, 1);
00497 
00498     return avio_tell(pb) - pos;
00499 }
00500 
00501 static int gxf_write_umf_media_mpeg(AVIOContext *pb, AVStream *st)
00502 {
00503     GXFStreamContext *sc = st->priv_data;
00504 
00505     if (st->codec->pix_fmt == PIX_FMT_YUV422P)
00506         avio_wl32(pb, 2);
00507     else
00508         avio_wl32(pb, 1); 
00509     avio_wl32(pb, sc->first_gop_closed == 1); 
00510     avio_wl32(pb, 3); 
00511     avio_wl32(pb, 1); 
00512     avio_wl32(pb, sc->p_per_gop);
00513     avio_wl32(pb, sc->b_per_i_or_p);
00514     if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO)
00515         avio_wl32(pb, 2);
00516     else if (st->codec->codec_id == CODEC_ID_MPEG1VIDEO)
00517         avio_wl32(pb, 1);
00518     else
00519         avio_wl32(pb, 0);
00520     avio_wl32(pb, 0); 
00521     return 32;
00522 }
00523 
00524 static int gxf_write_umf_media_timecode(AVIOContext *pb, int drop)
00525 {
00526     avio_wl32(pb, drop); 
00527     avio_wl32(pb, 0); 
00528     avio_wl32(pb, 0); 
00529     avio_wl32(pb, 0); 
00530     avio_wl32(pb, 0); 
00531     avio_wl32(pb, 0); 
00532     avio_wl32(pb, 0); 
00533     avio_wl32(pb, 0); 
00534     return 32;
00535 }
00536 
00537 static int gxf_write_umf_media_dv(AVIOContext *pb, GXFStreamContext *sc)
00538 {
00539     int i;
00540 
00541     for (i = 0; i < 8; i++) {
00542         avio_wb32(pb, 0);
00543     }
00544     return 32;
00545 }
00546 
00547 static int gxf_write_umf_media_audio(AVIOContext *pb, GXFStreamContext *sc)
00548 {
00549     avio_wl64(pb, av_double2int(1)); 
00550     avio_wl64(pb, av_double2int(1)); 
00551     avio_wl32(pb, 0); 
00552     avio_wl32(pb, 0); 
00553     avio_wl32(pb, 0); 
00554     avio_wl32(pb, 0); 
00555     return 32;
00556 }
00557 
00558 static int gxf_write_umf_media_description(AVFormatContext *s)
00559 {
00560     GXFContext *gxf = s->priv_data;
00561     AVIOContext *pb = s->pb;
00562     int64_t pos;
00563     int i, j;
00564 
00565     pos = avio_tell(pb);
00566     gxf->umf_media_offset = pos - gxf->umf_start_offset;
00567     for (i = 0; i <= s->nb_streams; ++i) {
00568         GXFStreamContext *sc;
00569         int64_t startpos, curpos;
00570 
00571         if (i == s->nb_streams)
00572             sc = &gxf->timecode_track;
00573         else
00574             sc = s->streams[i]->priv_data;
00575 
00576         startpos = avio_tell(pb);
00577         avio_wl16(pb, 0); 
00578         avio_wl16(pb, sc->media_info);
00579         avio_wl16(pb, 0); 
00580         avio_wl16(pb, 0); 
00581         avio_wl32(pb, gxf->nb_fields);
00582         avio_wl32(pb, 0); 
00583         avio_wl32(pb, 0); 
00584         avio_wl32(pb, gxf->nb_fields); 
00585         avio_write(pb, ES_NAME_PATTERN, strlen(ES_NAME_PATTERN));
00586         avio_wb16(pb, sc->media_info);
00587         for (j = strlen(ES_NAME_PATTERN)+2; j < 88; j++)
00588             avio_w8(pb, 0);
00589         avio_wl32(pb, sc->track_type);
00590         avio_wl32(pb, sc->sample_rate);
00591         avio_wl32(pb, sc->sample_size);
00592         avio_wl32(pb, 0); 
00593 
00594         if (sc == &gxf->timecode_track)
00595             gxf_write_umf_media_timecode(pb, gxf->tc.drop);
00596         else {
00597             AVStream *st = s->streams[i];
00598             switch (st->codec->codec_id) {
00599             case CODEC_ID_MPEG1VIDEO:
00600             case CODEC_ID_MPEG2VIDEO:
00601                 gxf_write_umf_media_mpeg(pb, st);
00602                 break;
00603             case CODEC_ID_PCM_S16LE:
00604                 gxf_write_umf_media_audio(pb, sc);
00605                 break;
00606             case CODEC_ID_DVVIDEO:
00607                 gxf_write_umf_media_dv(pb, sc);
00608                 break;
00609             }
00610         }
00611 
00612         curpos = avio_tell(pb);
00613         avio_seek(pb, startpos, SEEK_SET);
00614         avio_wl16(pb, curpos - startpos);
00615         avio_seek(pb, curpos, SEEK_SET);
00616     }
00617     return avio_tell(pb) - pos;
00618 }
00619 
00620 static int gxf_write_umf_packet(AVFormatContext *s)
00621 {
00622     GXFContext *gxf = s->priv_data;
00623     AVIOContext *pb = s->pb;
00624     int64_t pos = avio_tell(pb);
00625 
00626     gxf_write_packet_header(pb, PKT_UMF);
00627 
00628     
00629     avio_w8(pb, 3); 
00630     avio_wb32(pb, gxf->umf_length); 
00631 
00632     gxf->umf_start_offset = avio_tell(pb);
00633     gxf_write_umf_payload(s);
00634     gxf_write_umf_material_description(s);
00635     gxf->umf_track_size = gxf_write_umf_track_description(s);
00636     gxf->umf_media_size = gxf_write_umf_media_description(s);
00637     gxf->umf_length = avio_tell(pb) - gxf->umf_start_offset;
00638     return updatePacketSize(pb, pos);
00639 }
00640 
00641 static const int GXF_samples_per_frame[] = { 32768, 0 };
00642 
00643 static void gxf_init_timecode_track(GXFStreamContext *sc, GXFStreamContext *vsc)
00644 {
00645     if (!vsc)
00646         return;
00647 
00648     sc->media_type = vsc->sample_rate == 60 ? 7 : 8;
00649     sc->sample_rate = vsc->sample_rate;
00650     sc->media_info = ('T'<<8) | '0';
00651     sc->track_type = 3;
00652     sc->frame_rate_index = vsc->frame_rate_index;
00653     sc->lines_index = vsc->lines_index;
00654     sc->sample_size = 16;
00655     sc->fields = vsc->fields;
00656 }
00657 
00658 static int gxf_init_timecode(AVFormatContext *s, GXFTimecode *tc, int fields)
00659 {
00660     char c;
00661 
00662     if (sscanf(tc->str, "%d:%d:%d%c%d", &tc->hh, &tc->mm, &tc->ss, &c, &tc->ff) != 5) {
00663         av_log(s, AV_LOG_ERROR, "unable to parse timecode, "
00664                                 "syntax: hh:mm:ss[:;.]ff\n");
00665         return -1;
00666     }
00667 
00668     tc->color = 0;
00669     tc->drop = c != ':';
00670 
00671     if (fields == 2)
00672         tc->ff = tc->ff * 2;
00673 
00674     return 0;
00675 }
00676 
00677 static int gxf_write_header(AVFormatContext *s)
00678 {
00679     AVIOContext *pb = s->pb;
00680     GXFContext *gxf = s->priv_data;
00681     GXFStreamContext *vsc = NULL;
00682     uint8_t tracks[255] = {0};
00683     int i, media_info = 0;
00684 
00685     if (!pb->seekable) {
00686         av_log(s, AV_LOG_ERROR, "gxf muxer does not support streamed output, patch welcome");
00687         return -1;
00688     }
00689 
00690     gxf->flags |= 0x00080000; 
00691     for (i = 0; i < s->nb_streams; ++i) {
00692         AVStream *st = s->streams[i];
00693         GXFStreamContext *sc = av_mallocz(sizeof(*sc));
00694         if (!sc)
00695             return AVERROR(ENOMEM);
00696         st->priv_data = sc;
00697 
00698         sc->media_type = ff_codec_get_tag(gxf_media_types, st->codec->codec_id);
00699         if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
00700             if (st->codec->codec_id != CODEC_ID_PCM_S16LE) {
00701                 av_log(s, AV_LOG_ERROR, "only 16 BIT PCM LE allowed for now\n");
00702                 return -1;
00703             }
00704             if (st->codec->sample_rate != 48000) {
00705                 av_log(s, AV_LOG_ERROR, "only 48000hz sampling rate is allowed\n");
00706                 return -1;
00707             }
00708             if (st->codec->channels != 1) {
00709                 av_log(s, AV_LOG_ERROR, "only mono tracks are allowed\n");
00710                 return -1;
00711             }
00712             sc->track_type = 2;
00713             sc->sample_rate = st->codec->sample_rate;
00714             avpriv_set_pts_info(st, 64, 1, sc->sample_rate);
00715             sc->sample_size = 16;
00716             sc->frame_rate_index = -2;
00717             sc->lines_index = -2;
00718             sc->fields = -2;
00719             gxf->audio_tracks++;
00720             gxf->flags |= 0x04000000; 
00721             media_info = 'A';
00722         } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
00723             if (i != 0) {
00724                 av_log(s, AV_LOG_ERROR, "video stream must be the first track\n");
00725                 return -1;
00726             }
00727             
00728             if (st->codec->height == 480 || st->codec->height == 512) { 
00729                 sc->frame_rate_index = 5;
00730                 sc->sample_rate = 60;
00731                 gxf->flags |= 0x00000080;
00732                 gxf->time_base = (AVRational){ 1001, 60000 };
00733             } else if (st->codec->height == 576 || st->codec->height == 608) { 
00734                 sc->frame_rate_index = 6;
00735                 sc->media_type++;
00736                 sc->sample_rate = 50;
00737                 gxf->flags |= 0x00000040;
00738                 gxf->time_base = (AVRational){ 1, 50 };
00739             } else {
00740                 av_log(s, AV_LOG_ERROR, "unsupported video resolution, "
00741                        "gxf muxer only accepts PAL or NTSC resolutions currently\n");
00742                 return -1;
00743             }
00744             avpriv_set_pts_info(st, 64, gxf->time_base.num, gxf->time_base.den);
00745             if (gxf_find_lines_index(st) < 0)
00746                 sc->lines_index = -1;
00747             sc->sample_size = st->codec->bit_rate;
00748             sc->fields = 2; 
00749 
00750             vsc = sc;
00751 
00752             switch (st->codec->codec_id) {
00753             case CODEC_ID_MJPEG:
00754                 sc->track_type = 1;
00755                 gxf->flags |= 0x00004000;
00756                 media_info = 'J';
00757                 break;
00758             case CODEC_ID_MPEG1VIDEO:
00759                 sc->track_type = 9;
00760                 gxf->mpeg_tracks++;
00761                 media_info = 'L';
00762                 break;
00763             case CODEC_ID_MPEG2VIDEO:
00764                 sc->first_gop_closed = -1;
00765                 sc->track_type = 4;
00766                 gxf->mpeg_tracks++;
00767                 gxf->flags |= 0x00008000;
00768                 media_info = 'M';
00769                 break;
00770             case CODEC_ID_DVVIDEO:
00771                 if (st->codec->pix_fmt == PIX_FMT_YUV422P) {
00772                     sc->media_type += 2;
00773                     sc->track_type = 6;
00774                     gxf->flags |= 0x00002000;
00775                     media_info = 'E';
00776                 } else {
00777                     sc->track_type = 5;
00778                     gxf->flags |= 0x00001000;
00779                     media_info = 'D';
00780                 }
00781                 break;
00782             default:
00783                 av_log(s, AV_LOG_ERROR, "video codec not supported\n");
00784                 return -1;
00785             }
00786         }
00787         
00788         sc->media_info = media_info<<8 | ('0'+tracks[media_info]++);
00789         sc->order = s->nb_streams - st->index;
00790     }
00791 
00792     if (ff_audio_interleave_init(s, GXF_samples_per_frame, (AVRational){ 1, 48000 }) < 0)
00793         return -1;
00794 
00795     if (gxf->tc.str) {
00796         gxf_init_timecode(s, &gxf->tc, vsc->fields);
00797     }
00798 
00799     gxf_init_timecode_track(&gxf->timecode_track, vsc);
00800     gxf->flags |= 0x200000; 
00801 
00802     gxf_write_map_packet(s, 0);
00803     gxf_write_flt_packet(s);
00804     gxf_write_umf_packet(s);
00805 
00806     gxf->packet_count = 3;
00807 
00808     avio_flush(pb);
00809     return 0;
00810 }
00811 
00812 static int gxf_write_eos_packet(AVIOContext *pb)
00813 {
00814     int64_t pos = avio_tell(pb);
00815 
00816     gxf_write_packet_header(pb, PKT_EOS);
00817     return updatePacketSize(pb, pos);
00818 }
00819 
00820 static int gxf_write_trailer(AVFormatContext *s)
00821 {
00822     GXFContext *gxf = s->priv_data;
00823     AVIOContext *pb = s->pb;
00824     int64_t end;
00825     int i;
00826 
00827     ff_audio_interleave_close(s);
00828 
00829     gxf_write_eos_packet(pb);
00830     end = avio_tell(pb);
00831     avio_seek(pb, 0, SEEK_SET);
00832     
00833     gxf_write_map_packet(s, 1);
00834     gxf_write_flt_packet(s);
00835     gxf_write_umf_packet(s);
00836     avio_flush(pb);
00837     
00838     for (i = 1; i < gxf->map_offsets_nb; i++) {
00839         avio_seek(pb, gxf->map_offsets[i], SEEK_SET);
00840         gxf_write_map_packet(s, 1);
00841         avio_flush(pb);
00842     }
00843 
00844     avio_seek(pb, end, SEEK_SET);
00845 
00846     av_freep(&gxf->flt_entries);
00847     av_freep(&gxf->map_offsets);
00848 
00849     return 0;
00850 }
00851 
00852 static int gxf_parse_mpeg_frame(GXFStreamContext *sc, const uint8_t *buf, int size)
00853 {
00854     uint32_t c=-1;
00855     int i;
00856     for(i=0; i<size-4 && c!=0x100; i++){
00857         c = (c<<8) + buf[i];
00858         if(c == 0x1B8 && sc->first_gop_closed == -1) 
00859             sc->first_gop_closed= (buf[i+4]>>6)&1;
00860     }
00861     return (buf[i+1]>>3)&7;
00862 }
00863 
00864 static int gxf_write_media_preamble(AVFormatContext *s, AVPacket *pkt, int size)
00865 {
00866     GXFContext *gxf = s->priv_data;
00867     AVIOContext *pb = s->pb;
00868     AVStream *st = s->streams[pkt->stream_index];
00869     GXFStreamContext *sc = st->priv_data;
00870     unsigned field_nb;
00871     
00872 
00873 
00874     if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
00875         field_nb = gxf->nb_fields;
00876     } else {
00877         field_nb = av_rescale_rnd(pkt->dts, gxf->time_base.den,
00878                                   (int64_t)48000*gxf->time_base.num, AV_ROUND_UP);
00879     }
00880 
00881     avio_w8(pb, sc->media_type);
00882     avio_w8(pb, st->index);
00883     avio_wb32(pb, field_nb);
00884     if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
00885         avio_wb16(pb, 0);
00886         avio_wb16(pb, size / 2);
00887     } else if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO) {
00888         int frame_type = gxf_parse_mpeg_frame(sc, pkt->data, pkt->size);
00889         if (frame_type == AV_PICTURE_TYPE_I) {
00890             avio_w8(pb, 0x0d);
00891             sc->iframes++;
00892         } else if (frame_type == AV_PICTURE_TYPE_B) {
00893             avio_w8(pb, 0x0f);
00894             sc->bframes++;
00895         } else {
00896             avio_w8(pb, 0x0e);
00897             sc->pframes++;
00898         }
00899         avio_wb24(pb, size);
00900     } else if (st->codec->codec_id == CODEC_ID_DVVIDEO) {
00901         avio_w8(pb, size / 4096);
00902         avio_wb24(pb, 0);
00903     } else
00904         avio_wb32(pb, size);
00905     avio_wb32(pb, field_nb);
00906     avio_w8(pb, 1); 
00907     avio_w8(pb, 0); 
00908     return 16;
00909 }
00910 
00911 static int gxf_write_packet(AVFormatContext *s, AVPacket *pkt)
00912 {
00913     GXFContext *gxf = s->priv_data;
00914     AVIOContext *pb = s->pb;
00915     AVStream *st = s->streams[pkt->stream_index];
00916     int64_t pos = avio_tell(pb);
00917     int padding = 0;
00918     int packet_start_offset = avio_tell(pb) / 1024;
00919 
00920     gxf_write_packet_header(pb, PKT_MEDIA);
00921     if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO && pkt->size % 4) 
00922         padding = 4 - pkt->size % 4;
00923     else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
00924         padding = GXF_AUDIO_PACKET_SIZE - pkt->size;
00925     gxf_write_media_preamble(s, pkt, pkt->size + padding);
00926     avio_write(pb, pkt->data, pkt->size);
00927     gxf_write_padding(pb, padding);
00928 
00929     if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
00930         if (!(gxf->flt_entries_nb % 500)) {
00931             gxf->flt_entries = av_realloc_f(gxf->flt_entries,
00932                                             sizeof(*gxf->flt_entries),
00933                                             gxf->flt_entries_nb+500);
00934             if (!gxf->flt_entries) {
00935                 av_log(s, AV_LOG_ERROR, "could not reallocate flt entries\n");
00936                 return -1;
00937             }
00938         }
00939         gxf->flt_entries[gxf->flt_entries_nb++] = packet_start_offset;
00940         gxf->nb_fields += 2; 
00941     }
00942 
00943     updatePacketSize(pb, pos);
00944 
00945     gxf->packet_count++;
00946     if (gxf->packet_count == 100) {
00947         gxf_write_map_packet(s, 0);
00948         gxf->packet_count = 0;
00949     }
00950 
00951     avio_flush(pb);
00952 
00953     return 0;
00954 }
00955 
00956 static int gxf_compare_field_nb(AVFormatContext *s, AVPacket *next, AVPacket *cur)
00957 {
00958     GXFContext *gxf = s->priv_data;
00959     AVPacket *pkt[2] = { cur, next };
00960     int i, field_nb[2];
00961     GXFStreamContext *sc[2];
00962 
00963     for (i = 0; i < 2; i++) {
00964         AVStream *st = s->streams[pkt[i]->stream_index];
00965         sc[i] = st->priv_data;
00966         if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
00967             field_nb[i] = av_rescale_rnd(pkt[i]->dts, gxf->time_base.den,
00968                                          (int64_t)48000*gxf->time_base.num, AV_ROUND_UP);
00969             field_nb[i] &= ~1; 
00970         } else
00971             field_nb[i] = pkt[i]->dts; 
00972     }
00973 
00974     return field_nb[1] > field_nb[0] ||
00975         (field_nb[1] == field_nb[0] && sc[1]->order > sc[0]->order);
00976 }
00977 
00978 static int gxf_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush)
00979 {
00980     if (pkt && s->streams[pkt->stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
00981         pkt->duration = 2; 
00982     return ff_audio_rechunk_interleave(s, out, pkt, flush,
00983                                ff_interleave_packet_per_dts, gxf_compare_field_nb);
00984 }
00985 
00986 static const AVOption options[] = {
00987     { AV_TIMECODE_OPTION(GXFContext, tc.str, AV_OPT_FLAG_ENCODING_PARAM) },
00988     { NULL }
00989 };
00990 
00991 static const AVClass gxf_muxer_class = {
00992     .class_name     = "GXF muxer",
00993     .item_name      = av_default_item_name,
00994     .option         = options,
00995     .version        = LIBAVUTIL_VERSION_INT,
00996 };
00997 
00998 AVOutputFormat ff_gxf_muxer = {
00999     .name              = "gxf",
01000     .long_name         = NULL_IF_CONFIG_SMALL("GXF format"),
01001     .extensions        = "gxf",
01002     .priv_data_size    = sizeof(GXFContext),
01003     .audio_codec       = CODEC_ID_PCM_S16LE,
01004     .video_codec       = CODEC_ID_MPEG2VIDEO,
01005     .write_header      = gxf_write_header,
01006     .write_packet      = gxf_write_packet,
01007     .write_trailer     = gxf_write_trailer,
01008     .interleave_packet = gxf_interleave_packet,
01009     .priv_class        = &gxf_muxer_class,
01010 };