]> git.sesse.net Git - ffmpeg/blob - libavformat/gxfenc.c
factorize write packet
[ffmpeg] / libavformat / gxfenc.c
1 /*
2  * GXF muxer.
3  * Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 #include "libavutil/fifo.h"
23 #include "avformat.h"
24 #include "gxf.h"
25 #include "riff.h"
26 #include "audiointerleave.h"
27
28 #define GXF_AUDIO_PACKET_SIZE 65536
29
30 typedef struct GXFStreamContext {
31     AudioInterleaveContext aic;
32     uint32_t track_type;
33     uint32_t sample_size;
34     uint32_t sample_rate;
35     uint16_t media_type;
36     uint16_t media_info;
37     int frame_rate_index;
38     int lines_index;
39     int fields;
40     int iframes;
41     int pframes;
42     int bframes;
43     int p_per_gop;
44     int b_per_i_or_p; ///< number of B frames per I frame or P frame
45     int first_gop_closed;
46 } GXFStreamContext;
47
48 typedef struct GXFContext {
49     uint32_t nb_fields;
50     uint16_t audio_tracks;
51     uint16_t mpeg_tracks;
52     int64_t creation_time;
53     uint32_t umf_start_offset;
54     uint32_t umf_track_offset;
55     uint32_t umf_media_offset;
56     uint32_t umf_length;
57     uint16_t umf_track_size;
58     uint16_t umf_media_size;
59     int sample_rate;
60     int flags;
61 } GXFContext;
62
63 typedef struct GXF_Lines {
64     int height;
65     int index;
66 } GXF_Lines;
67
68
69 /* FIXME check if it is relevant */
70 static const GXF_Lines gxf_lines_tab[] = {
71     { 480,  1 }, /* NTSC */
72     { 512,  1 }, /* NTSC + VBI */
73     { 576,  2 }, /* PAL */
74     { 608,  2 }, /* PAL + VBI */
75     { 1080, 4 },
76     { 720,  6 },
77 };
78
79 static const AVCodecTag gxf_media_types[] = {
80     { CODEC_ID_MJPEG     ,   3 }, /* NTSC */
81     { CODEC_ID_MJPEG     ,   4 }, /* PAL */
82     { CODEC_ID_PCM_S24LE ,   9 },
83     { CODEC_ID_PCM_S16LE ,  10 },
84     { CODEC_ID_MPEG2VIDEO,  11 }, /* NTSC */
85     { CODEC_ID_MPEG2VIDEO,  12 }, /* PAL */
86     { CODEC_ID_DVVIDEO   ,  13 }, /* NTSC */
87     { CODEC_ID_DVVIDEO   ,  14 }, /* PAL */
88     { CODEC_ID_DVVIDEO   ,  15 }, /* 50M NTSC */
89     { CODEC_ID_DVVIDEO   ,  16 }, /* 50M PAL */
90     { CODEC_ID_AC3       ,  17 },
91     //{ CODEC_ID_NONE,  ,   18 }, /* Non compressed 24 bit audio */
92     { CODEC_ID_MPEG2VIDEO,  20 }, /* MPEG HD */
93     { CODEC_ID_MPEG1VIDEO,  22 }, /* NTSC */
94     { CODEC_ID_MPEG1VIDEO,  23 }, /* PAL */
95     { 0, 0 },
96 };
97
98 #define SERVER_PATH "/space/"
99 #define ES_NAME_PATTERN "ES."
100
101 static int gxf_find_lines_index(AVStream *st)
102 {
103     GXFStreamContext *sc = st->priv_data;
104     int i;
105
106     for (i = 0; i < 6; ++i) {
107         if (st->codec->height == gxf_lines_tab[i].height) {
108             sc->lines_index = gxf_lines_tab[i].index;
109             return 0;
110         }
111     }
112     return -1;
113 }
114
115 static void gxf_write_padding(ByteIOContext *pb, int64_t to_pad)
116 {
117     for (; to_pad > 0; to_pad--) {
118         put_byte(pb, 0);
119     }
120 }
121
122 static int64_t updatePacketSize(ByteIOContext *pb, int64_t pos)
123 {
124     int64_t curpos;
125     int size;
126
127     size = url_ftell(pb) - pos;
128     if (size % 4) {
129         gxf_write_padding(pb, 4 - size % 4);
130         size = url_ftell(pb) - pos;
131     }
132     curpos = url_ftell(pb);
133     url_fseek(pb, pos + 6, SEEK_SET);
134     put_be32(pb, size);
135     url_fseek(pb, curpos, SEEK_SET);
136     return curpos - pos;
137 }
138
139 static int64_t updateSize(ByteIOContext *pb, int64_t pos)
140 {
141     int64_t curpos;
142
143     curpos = url_ftell(pb);
144     url_fseek(pb, pos, SEEK_SET);
145     put_be16(pb, curpos - pos - 2);
146     url_fseek(pb, curpos, SEEK_SET);
147     return curpos - pos;
148 }
149
150 static void gxf_write_packet_header(ByteIOContext *pb, GXFPktType type)
151 {
152     put_be32(pb, 0); /* packet leader for synchro */
153     put_byte(pb, 1);
154     put_byte(pb, type); /* map packet */
155     put_be32(pb, 0); /* size */
156     put_be32(pb, 0); /* reserved */
157     put_byte(pb, 0xE1); /* trailer 1 */
158     put_byte(pb, 0xE2); /* trailer 2 */
159 }
160
161 static int gxf_write_mpeg_auxiliary(ByteIOContext *pb, AVStream *st)
162 {
163     GXFStreamContext *sc = st->priv_data;
164     char buffer[1024];
165     int size, starting_line;
166
167     if (sc->iframes) {
168         sc->p_per_gop = sc->pframes / sc->iframes;
169         if (sc->pframes % sc->iframes)
170             sc->p_per_gop++;
171         if (sc->pframes) {
172             sc->b_per_i_or_p = sc->bframes / sc->pframes;
173             if (sc->bframes % sc->pframes)
174                 sc->b_per_i_or_p++;
175         }
176         if (sc->p_per_gop > 9)
177             sc->p_per_gop = 9; /* ensure value won't take more than one char */
178         if (sc->b_per_i_or_p > 9)
179             sc->b_per_i_or_p = 9; /* ensure value won't take more than one char */
180     }
181     if (st->codec->height == 512 || st->codec->height == 608)
182         starting_line = 7; // VBI
183     else if (st->codec->height == 480)
184         starting_line = 20;
185     else
186         starting_line = 23; // default PAL
187
188     size = snprintf(buffer, 1024, "Ver 1\nBr %.6f\nIpg 1\nPpi %d\nBpiop %d\n"
189                     "Pix 0\nCf %d\nCg %d\nSl %d\nnl16 %d\nVi 1\nf1 1\n",
190                     (float)st->codec->bit_rate, sc->p_per_gop, sc->b_per_i_or_p,
191                     st->codec->pix_fmt == PIX_FMT_YUV422P ? 2 : 1, sc->first_gop_closed == 1,
192                     starting_line, st->codec->height / 16);
193     put_byte(pb, TRACK_MPG_AUX);
194     put_byte(pb, size + 1);
195     put_buffer(pb, (uint8_t *)buffer, size + 1);
196     return size + 3;
197 }
198
199 static int gxf_write_timecode_auxiliary(ByteIOContext *pb, GXFStreamContext *sc)
200 {
201     /* FIXME implement that */
202     put_byte(pb, 0); /* fields */
203     put_byte(pb, 0);  /* seconds */
204     put_byte(pb, 0); /* minutes */
205     put_byte(pb, 0); /* flags + hours */
206     /* reserved */
207     put_be32(pb, 0);
208     return 8;
209 }
210
211 static int gxf_write_track_description(ByteIOContext *pb, AVStream *st)
212 {
213     GXFStreamContext *sc = st->priv_data;
214     int64_t pos;
215
216     /* track description section */
217     put_byte(pb, sc->media_type + 0x80);
218     put_byte(pb, st->index + 0xC0);
219
220     pos = url_ftell(pb);
221     put_be16(pb, 0); /* size */
222
223     /* media file name */
224     put_byte(pb, TRACK_NAME);
225     put_byte(pb, strlen(ES_NAME_PATTERN) + 3);
226     put_tag(pb, ES_NAME_PATTERN);
227     put_be16(pb, sc->media_info);
228     put_byte(pb, 0);
229
230     if (st->codec->codec_id != CODEC_ID_MPEG2VIDEO) {
231         /* auxiliary information */
232         put_byte(pb, TRACK_AUX);
233         put_byte(pb, 8);
234         if (st->codec->codec_id == CODEC_ID_NONE)
235             gxf_write_timecode_auxiliary(pb, sc);
236         else
237             put_le64(pb, 0);
238     }
239
240     /* file system version */
241     put_byte(pb, TRACK_VER);
242     put_byte(pb, 4);
243     put_be32(pb, 0);
244
245     if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO)
246         gxf_write_mpeg_auxiliary(pb, st);
247
248     /* frame rate */
249     put_byte(pb, TRACK_FPS);
250     put_byte(pb, 4);
251     put_be32(pb, sc->frame_rate_index);
252
253     /* lines per frame */
254     put_byte(pb, TRACK_LINES);
255     put_byte(pb, 4);
256     put_be32(pb, sc->lines_index);
257
258     /* fields per frame */
259     put_byte(pb, TRACK_FPF);
260     put_byte(pb, 4);
261     put_be32(pb, sc->fields);
262
263     return updateSize(pb, pos);
264 }
265
266 static int gxf_write_material_data_section(AVFormatContext *s)
267 {
268     GXFContext *gxf = s->priv_data;
269     ByteIOContext *pb = s->pb;
270     int64_t pos;
271     const char *filename = strrchr(s->filename, '/');
272
273     pos = url_ftell(pb);
274     put_be16(pb, 0); /* size */
275
276     /* name */
277     if (filename)
278         filename++;
279     else
280         filename = s->filename;
281     put_byte(pb, MAT_NAME);
282     put_byte(pb, strlen(SERVER_PATH) + strlen(filename) + 1);
283     put_tag(pb, SERVER_PATH);
284     put_tag(pb, filename);
285     put_byte(pb, 0);
286
287     /* first field */
288     put_byte(pb, MAT_FIRST_FIELD);
289     put_byte(pb, 4);
290     put_be32(pb, 0);
291
292     /* last field */
293     put_byte(pb, MAT_LAST_FIELD);
294     put_byte(pb, 4);
295     put_be32(pb, gxf->nb_fields);
296
297     /* reserved */
298     put_byte(pb, MAT_MARK_IN);
299     put_byte(pb, 4);
300     put_be32(pb, 0);
301
302     put_byte(pb, MAT_MARK_OUT);
303     put_byte(pb, 4);
304     put_be32(pb, gxf->nb_fields);
305
306     /* estimated size */
307     put_byte(pb, MAT_SIZE);
308     put_byte(pb, 4);
309     put_be32(pb, url_fsize(pb) / 1024);
310
311     return updateSize(pb, pos);
312 }
313
314 static int gxf_write_track_description_section(AVFormatContext *s)
315 {
316     ByteIOContext *pb = s->pb;
317     int64_t pos;
318     int i;
319
320     pos = url_ftell(pb);
321     put_be16(pb, 0); /* size */
322     for (i = 0; i < s->nb_streams; ++i)
323         gxf_write_track_description(pb, s->streams[i]);
324     return updateSize(pb, pos);
325 }
326
327 static int gxf_write_map_packet(AVFormatContext *s)
328 {
329     ByteIOContext *pb = s->pb;
330     int64_t pos = url_ftell(pb);
331
332     gxf_write_packet_header(pb, PKT_MAP);
333
334     /* preamble */
335     put_byte(pb, 0xE0); /* version */
336     put_byte(pb, 0xFF); /* reserved */
337
338     gxf_write_material_data_section(s);
339     gxf_write_track_description_section(s);
340
341     return updatePacketSize(pb, pos);
342 }
343
344 #if 0
345 static int gxf_write_flt_packet(AVFormatContext *s)
346 {
347     GXFContext *gxf = s->priv_data;
348     ByteIOContext *pb = s->pb;
349     int64_t pos = url_ftell(pb);
350     int i;
351
352     gxf_write_packet_header(pb, PKT_FLT);
353
354     put_le32(pb, 1000); /* number of fields */
355     put_le32(pb, 0); /* number of active flt entries */
356
357     for (i = 0; i < 1000; ++i) {
358         put_le32(pb, 0);
359     }
360     return updatePacketSize(pb, pos);
361 }
362 #endif
363
364 static int gxf_write_umf_material_description(AVFormatContext *s)
365 {
366     GXFContext *gxf = s->priv_data;
367     ByteIOContext *pb = s->pb;
368
369     // XXX drop frame
370     uint32_t timecode =
371         gxf->nb_fields / (gxf->sample_rate * 3600) % 24 << 24 | // hours
372         gxf->nb_fields / (gxf->sample_rate * 60) % 60   << 16 | // minutes
373         gxf->nb_fields / gxf->sample_rate % 60          <<  8 | // seconds
374         gxf->nb_fields % gxf->sample_rate;                    // fields
375
376     put_le32(pb, gxf->flags);
377     put_le32(pb, gxf->nb_fields); /* length of the longest track */
378     put_le32(pb, gxf->nb_fields); /* length of the shortest track */
379     put_le32(pb, 0); /* mark in */
380     put_le32(pb, gxf->nb_fields); /* mark out */
381     put_le32(pb, 0); /* timecode mark in */
382     put_le32(pb, timecode); /* timecode mark out */
383     put_le64(pb, s->timestamp); /* modification time */
384     put_le64(pb, s->timestamp); /* creation time */
385     put_le16(pb, 0); /* reserved */
386     put_le16(pb, 0); /* reserved */
387     put_le16(pb, gxf->audio_tracks);
388     put_le16(pb, 0); /* timecode track count */
389     put_le16(pb, 0); /* reserved */
390     put_le16(pb, gxf->mpeg_tracks);
391     return 48;
392 }
393
394 static int gxf_write_umf_payload(AVFormatContext *s)
395 {
396     GXFContext *gxf = s->priv_data;
397     ByteIOContext *pb = s->pb;
398
399     put_le32(pb, gxf->umf_length); /* total length of the umf data */
400     put_le32(pb, 3); /* version */
401     put_le32(pb, s->nb_streams);
402     put_le32(pb, gxf->umf_track_offset); /* umf track section offset */
403     put_le32(pb, gxf->umf_track_size);
404     put_le32(pb, s->nb_streams);
405     put_le32(pb, gxf->umf_media_offset);
406     put_le32(pb, gxf->umf_media_size);
407     put_le32(pb, gxf->umf_length); /* user data offset */
408     put_le32(pb, 0); /* user data size */
409     put_le32(pb, 0); /* reserved */
410     put_le32(pb, 0); /* reserved */
411     return 48;
412 }
413
414 static int gxf_write_umf_track_description(AVFormatContext *s)
415 {
416     ByteIOContext *pb = s->pb;
417     GXFContext *gxf = s->priv_data;
418     int64_t pos = url_ftell(pb);
419     int tracks[255]={0};
420     int i;
421
422     gxf->umf_track_offset = pos - gxf->umf_start_offset;
423     for (i = 0; i < s->nb_streams; ++i) {
424         AVStream *st = s->streams[i];
425         GXFStreamContext *sc = st->priv_data;
426         int id = 0;
427
428         switch (st->codec->codec_id) {
429         case CODEC_ID_MPEG1VIDEO: id= 'L'; break;
430         case CODEC_ID_MPEG2VIDEO: id= 'M'; break;
431         case CODEC_ID_PCM_S16LE:  id= 'A'; break;
432         case CODEC_ID_DVVIDEO:    id= sc->track_type == 6 ? 'E' : 'D'; break;
433         case CODEC_ID_MJPEG:      id= 'V'; break;
434         default:                  break;
435         }
436         sc->media_info= id << 8;
437         /* FIXME first 10 audio tracks are 0 to 9 next 22 are A to V */
438         sc->media_info |= '0' + (tracks[id]++);
439         put_le16(pb, sc->media_info);
440         put_le16(pb, 1);
441     }
442     return url_ftell(pb) - pos;
443 }
444
445 static int gxf_write_umf_media_mpeg(ByteIOContext *pb, AVStream *st)
446 {
447     GXFStreamContext *sc = st->priv_data;
448
449     if (st->codec->pix_fmt == PIX_FMT_YUV422P)
450         put_le32(pb, 2);
451     else
452         put_le32(pb, 1); /* default to 420 */
453     put_le32(pb, sc->first_gop_closed == 1); /* closed = 1, open = 0, unknown = 255 */
454     put_le32(pb, 3); /* top = 1, bottom = 2, frame = 3, unknown = 0 */
455     put_le32(pb, 1); /* I picture per GOP */
456     put_le32(pb, sc->p_per_gop);
457     put_le32(pb, sc->b_per_i_or_p);
458     if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO)
459         put_le32(pb, 2);
460     else if (st->codec->codec_id == CODEC_ID_MPEG1VIDEO)
461         put_le32(pb, 1);
462     else
463         put_le32(pb, 0);
464     put_le32(pb, 0); /* reserved */
465     return 32;
466 }
467
468 static int gxf_write_umf_media_timecode(ByteIOContext *pb, GXFStreamContext *sc)
469 {
470     /* FIXME implement */
471     put_be32(pb, 0); /* drop frame flag */
472     put_be32(pb, 0); /* reserved */
473     put_be32(pb, 0); /* reserved */
474     put_be32(pb, 0); /* reserved */
475     put_be32(pb, 0); /* reserved */
476     put_be32(pb, 0); /* reserved */
477     put_be32(pb, 0); /* reserved */
478     put_be32(pb, 0); /* reserved */
479     return 32;
480 }
481
482 static int gxf_write_umf_media_dv(ByteIOContext *pb, GXFStreamContext *sc)
483 {
484     int i;
485
486     for (i = 0; i < 8; i++) {
487         put_be32(pb, 0);
488     }
489     return 32;
490 }
491
492 static int gxf_write_umf_media_audio(ByteIOContext *pb, GXFStreamContext *sc)
493 {
494     put_le64(pb, av_dbl2int(1)); /* sound level to begin to */
495     put_le64(pb, av_dbl2int(1)); /* sound level to begin to */
496     put_le32(pb, 0); /* number of fields over which to ramp up sound level */
497     put_le32(pb, 0); /* number of fields over which to ramp down sound level */
498     put_le32(pb, 0); /* reserved */
499     put_le32(pb, 0); /* reserved */
500     return 32;
501 }
502
503 #if 0
504 static int gxf_write_umf_media_mjpeg(ByteIOContext *pb, GXFStreamContext *sc)
505 {
506     put_be64(pb, 0); /* FIXME FLOAT max chroma quant level */
507     put_be64(pb, 0); /* FIXME FLOAT max luma quant level */
508     put_be64(pb, 0); /* FIXME FLOAT min chroma quant level */
509     put_be64(pb, 0); /* FIXME FLOAT min luma quant level */
510     return 32;
511 }
512 #endif
513
514 static int gxf_write_umf_media_description(AVFormatContext *s)
515 {
516     GXFContext *gxf = s->priv_data;
517     ByteIOContext *pb = s->pb;
518     int64_t pos;
519     int i;
520
521     pos = url_ftell(pb);
522     gxf->umf_media_offset = pos - gxf->umf_start_offset;
523     for (i = 0; i < s->nb_streams; ++i) {
524         AVStream *st = s->streams[i];
525         GXFStreamContext *sc = st->priv_data;
526         char buffer[88];
527         int64_t startpos, curpos;
528         int path_size = strlen(ES_NAME_PATTERN);
529
530         memset(buffer, 0, 88);
531         startpos = url_ftell(pb);
532         put_le16(pb, 0); /* length */
533         put_le16(pb, sc->media_info);
534         put_le16(pb, 0); /* reserved */
535         put_le16(pb, 0); /* reserved */
536         put_le32(pb, gxf->nb_fields);
537         put_le32(pb, 0); /* attributes rw, ro */
538         put_le32(pb, 0); /* mark in */
539         put_le32(pb, gxf->nb_fields); /* mark out */
540         strncpy(buffer, ES_NAME_PATTERN, path_size);
541         put_buffer(pb, (uint8_t *)buffer, path_size);
542         put_be16(pb, sc->media_info);
543         put_buffer(pb, (uint8_t *)buffer + path_size + 2, 88 - path_size - 2);
544         put_le32(pb, sc->track_type);
545         put_le32(pb, sc->sample_rate);
546         put_le32(pb, sc->sample_size);
547         put_le32(pb, 0); /* reserved */
548         switch (st->codec->codec_id) {
549         case CODEC_ID_MPEG2VIDEO:
550             gxf_write_umf_media_mpeg(pb, st);
551             break;
552         case CODEC_ID_PCM_S16LE:
553             gxf_write_umf_media_audio(pb, sc);
554             break;
555         case CODEC_ID_DVVIDEO:
556             gxf_write_umf_media_dv(pb, sc);
557             break;
558         default:
559             gxf_write_umf_media_timecode(pb, sc); /* 8 0bytes */
560         }
561         curpos = url_ftell(pb);
562         url_fseek(pb, startpos, SEEK_SET);
563         put_le16(pb, curpos - startpos);
564         url_fseek(pb, curpos, SEEK_SET);
565     }
566     return url_ftell(pb) - pos;
567 }
568
569 static int gxf_write_umf_packet(AVFormatContext *s)
570 {
571     GXFContext *gxf = s->priv_data;
572     ByteIOContext *pb = s->pb;
573     int64_t pos = url_ftell(pb);
574
575     gxf_write_packet_header(pb, PKT_UMF);
576
577     /* preamble */
578     put_byte(pb, 3); /* first and last (only) packet */
579     put_be32(pb, gxf->umf_length); /* data length */
580
581     gxf->umf_start_offset = url_ftell(pb);
582     gxf_write_umf_payload(s);
583     gxf_write_umf_material_description(s);
584     gxf->umf_track_size = gxf_write_umf_track_description(s);
585     gxf->umf_media_size = gxf_write_umf_media_description(s);
586     gxf->umf_length = url_ftell(pb) - gxf->umf_start_offset;
587     return updatePacketSize(pb, pos);
588 }
589
590 static const int GXF_samples_per_frame[] = { 32768, 0 };
591
592 static int gxf_write_header(AVFormatContext *s)
593 {
594     ByteIOContext *pb = s->pb;
595     GXFContext *gxf = s->priv_data;
596     int i;
597
598     gxf->flags |= 0x00080000; /* material is simple clip */
599     for (i = 0; i < s->nb_streams; ++i) {
600         AVStream *st = s->streams[i];
601         GXFStreamContext *sc = av_mallocz(sizeof(*sc));
602         if (!sc)
603             return AVERROR(ENOMEM);
604         st->priv_data = sc;
605
606         sc->media_type = codec_get_tag(gxf_media_types, st->codec->codec_id);
607         if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
608             if (st->codec->codec_id != CODEC_ID_PCM_S16LE) {
609                 av_log(s, AV_LOG_ERROR, "only 16 BIT PCM LE allowed for now\n");
610                 return -1;
611             }
612             if (st->codec->sample_rate != 48000) {
613                 av_log(s, AV_LOG_ERROR, "only 48000hz sampling rate is allowed\n");
614                 return -1;
615             }
616             if (st->codec->channels != 1) {
617                 av_log(s, AV_LOG_ERROR, "only mono tracks are allowed\n");
618                 return -1;
619             }
620             sc->track_type = 2;
621             sc->sample_rate = st->codec->sample_rate;
622             av_set_pts_info(st, 64, 1, sc->sample_rate);
623             sc->sample_size = 16;
624             sc->frame_rate_index = -2;
625             sc->lines_index = -2;
626             sc->fields = -2;
627             gxf->audio_tracks++;
628             gxf->flags |= 0x04000000; /* audio is 16 bit pcm */
629         } else if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
630             /* FIXME check from time_base ? */
631             if (st->codec->height == 480 || st->codec->height == 512) { /* NTSC or NTSC+VBI */
632                 sc->frame_rate_index = 5;
633                 sc->sample_rate = 60;
634                 gxf->flags |= 0x00000080;
635             } else { /* assume PAL */
636                 sc->frame_rate_index = 6;
637                 sc->media_type++;
638                 sc->sample_rate = 50;
639                 gxf->flags |= 0x00000040;
640             }
641             gxf->sample_rate = sc->sample_rate;
642             av_set_pts_info(st, 64, 1, st->codec->time_base.den);
643             if (gxf_find_lines_index(st) < 0)
644                 sc->lines_index = -1;
645             sc->sample_size = st->codec->bit_rate;
646             sc->fields = 2; /* interlaced */
647             switch (st->codec->codec_id) {
648             case CODEC_ID_MPEG2VIDEO:
649                 sc->first_gop_closed = -1;
650                 sc->track_type = 4;
651                 gxf->mpeg_tracks++;
652                 gxf->flags |= 0x00008000;
653                 break;
654             case CODEC_ID_DVVIDEO:
655                 if (st->codec->pix_fmt == PIX_FMT_YUV422P) {
656                     sc->media_type += 2;
657                     sc->track_type = 6;
658                     gxf->flags |= 0x00002000;
659                 } else {
660                     sc->track_type = 5;
661                     gxf->flags |= 0x00001000;
662                 }
663                 break;
664             default:
665                 av_log(s, AV_LOG_ERROR, "video codec not supported\n");
666                 return -1;
667             }
668         }
669     }
670
671     if (ff_audio_interleave_init(s, GXF_samples_per_frame, (AVRational){ 1, 48000 }) < 0)
672         return -1;
673
674     gxf_write_map_packet(s);
675     //gxf_write_flt_packet(s);
676     gxf_write_umf_packet(s);
677     put_flush_packet(pb);
678     return 0;
679 }
680
681 static int gxf_write_eos_packet(ByteIOContext *pb)
682 {
683     int64_t pos = url_ftell(pb);
684
685     gxf_write_packet_header(pb, PKT_EOS);
686     return updatePacketSize(pb, pos);
687 }
688
689 static int gxf_write_trailer(AVFormatContext *s)
690 {
691     ByteIOContext *pb = s->pb;
692     int64_t end;
693
694     ff_audio_interleave_close(s);
695
696     gxf_write_eos_packet(pb);
697     end = url_ftell(pb);
698     url_fseek(pb, 0, SEEK_SET);
699     /* overwrite map and umf packets with new values */
700     gxf_write_map_packet(s);
701     //gxf_write_flt_packet(s);
702     gxf_write_umf_packet(s);
703     url_fseek(pb, end, SEEK_SET);
704     return 0;
705 }
706
707 static int gxf_parse_mpeg_frame(GXFStreamContext *sc, const uint8_t *buf, int size)
708 {
709     uint32_t c=-1;
710     int i;
711     for(i=0; i<size-4 && c!=0x100; i++){
712         c = (c<<8) + buf[i];
713         if(c == 0x1B8 && sc->first_gop_closed == -1) /* GOP start code */
714             sc->first_gop_closed= (buf[i+4]>>6)&1;
715     }
716     return (buf[i+1]>>3)&7;
717 }
718
719 static int gxf_write_media_preamble(AVFormatContext *s, AVPacket *pkt, int size)
720 {
721     GXFContext *gxf = s->priv_data;
722     ByteIOContext *pb = s->pb;
723     AVStream *st = s->streams[pkt->stream_index];
724     GXFStreamContext *sc = st->priv_data;
725     unsigned field_nb;
726     /* If the video is frame-encoded, the frame numbers shall be represented by
727      * even field numbers.
728      * see SMPTE360M-2004  6.4.2.1.3 Media field number */
729     if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
730         field_nb = gxf->nb_fields;
731     } else {
732         field_nb = av_rescale_rnd(pkt->dts, gxf->sample_rate, st->codec->time_base.den, AV_ROUND_UP);
733     }
734
735     put_byte(pb, sc->media_type);
736     put_byte(pb, st->index);
737     put_be32(pb, field_nb);
738     if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
739         put_be16(pb, 0);
740         put_be16(pb, size / 2);
741     } else if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO) {
742         int frame_type = gxf_parse_mpeg_frame(sc, pkt->data, pkt->size);
743         if (frame_type == FF_I_TYPE) {
744             put_byte(pb, 0x0d);
745             sc->iframes++;
746         } else if (frame_type == FF_B_TYPE) {
747             put_byte(pb, 0x0f);
748             sc->bframes++;
749         } else {
750             put_byte(pb, 0x0e);
751             sc->pframes++;
752         }
753         put_be24(pb, size);
754     } else if (st->codec->codec_id == CODEC_ID_DVVIDEO) {
755         put_byte(pb, size / 4096);
756         put_be24(pb, 0);
757     } else
758         put_be32(pb, size);
759     put_be32(pb, field_nb);
760     put_byte(pb, 1); /* flags */
761     put_byte(pb, 0); /* reserved */
762     return 16;
763 }
764
765 static int gxf_write_packet(AVFormatContext *s, AVPacket *pkt)
766 {
767     GXFContext *gxf = s->priv_data;
768     ByteIOContext *pb = s->pb;
769     AVStream *st = s->streams[pkt->stream_index];
770     int64_t pos = url_ftell(pb);
771     int padding = 0;
772
773     gxf_write_packet_header(pb, PKT_MEDIA);
774     if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO && pkt->size % 4) /* MPEG-2 frames must be padded */
775         padding = 4 - pkt->size % 4;
776     else if (st->codec->codec_type == CODEC_TYPE_AUDIO)
777         padding = GXF_AUDIO_PACKET_SIZE - pkt->size;
778     gxf_write_media_preamble(s, pkt, pkt->size + padding);
779     put_buffer(pb, pkt->data, pkt->size);
780     gxf_write_padding(pb, padding);
781
782     if (st->codec->codec_type == CODEC_TYPE_VIDEO)
783         gxf->nb_fields += 2; // count fields
784
785     put_flush_packet(pb);
786
787     return updatePacketSize(pb, pos);
788 }
789
790 static int gxf_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush)
791 {
792     return ff_audio_rechunk_interleave(s, out, pkt, flush,
793                                av_interleave_packet_per_dts, ff_interleave_compare_dts);
794 }
795
796 AVOutputFormat gxf_muxer = {
797     "gxf",
798     NULL_IF_CONFIG_SMALL("GXF format"),
799     NULL,
800     "gxf",
801     sizeof(GXFContext),
802     CODEC_ID_PCM_S16LE,
803     CODEC_ID_MPEG2VIDEO,
804     gxf_write_header,
805     gxf_write_packet,
806     gxf_write_trailer,
807     0,
808     NULL,
809     gxf_interleave_packet,
810 };