3 * Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>
5 * This file is part of FFmpeg.
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.
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.
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
22 #include "libavutil/avassert.h"
23 #include "libavutil/intfloat.h"
24 #include "libavutil/opt.h"
25 #include "libavutil/mathematics.h"
26 #include "libavutil/timecode.h"
30 #include "audiointerleave.h"
32 #define GXF_AUDIO_PACKET_SIZE 65536
34 #define GXF_TIMECODE(c, d, h, m, s, f) \
35 ((c) << 30 | (d) << 29 | (h) << 24 | (m) << 16 | (s) << 8 | (f))
37 typedef struct GXFTimecode
{
46 typedef struct GXFStreamContext
{
47 AudioInterleaveContext aic
;
60 int b_per_i_or_p
; ///< number of B frames per I frame or P frame
62 unsigned order
; ///< interleaving order
65 typedef struct GXFContext
{
68 uint16_t audio_tracks
;
70 int64_t creation_time
;
71 uint32_t umf_start_offset
;
72 uint32_t umf_track_offset
;
73 uint32_t umf_media_offset
;
75 uint16_t umf_track_size
;
76 uint16_t umf_media_size
;
79 GXFStreamContext timecode_track
;
80 unsigned *flt_entries
; ///< offsets of packets /1024, starts after 2nd video field
81 unsigned flt_entries_nb
;
82 uint64_t *map_offsets
; ///< offset of map packets
83 unsigned map_offsets_nb
;
84 unsigned packet_count
;
91 { 480, 1 }, /* NTSC */
92 { 512, 1 }, /* NTSC + VBI */
94 { 608, 2 }, /* PAL + VBI */
99 static const AVCodecTag gxf_media_types
[] = {
100 { AV_CODEC_ID_MJPEG
, 3 }, /* NTSC */
101 { AV_CODEC_ID_MJPEG
, 4 }, /* PAL */
102 { AV_CODEC_ID_PCM_S24LE
, 9 },
103 { AV_CODEC_ID_PCM_S16LE
, 10 },
104 { AV_CODEC_ID_MPEG2VIDEO
, 11 }, /* NTSC */
105 { AV_CODEC_ID_MPEG2VIDEO
, 12 }, /* PAL */
106 { AV_CODEC_ID_DVVIDEO
, 13 }, /* NTSC */
107 { AV_CODEC_ID_DVVIDEO
, 14 }, /* PAL */
108 { AV_CODEC_ID_DVVIDEO
, 15 }, /* 50M NTSC */
109 { AV_CODEC_ID_DVVIDEO
, 16 }, /* 50M PAL */
110 { AV_CODEC_ID_AC3
, 17 },
111 //{ AV_CODEC_ID_NONE, , 18 }, /* Non compressed 24 bit audio */
112 { AV_CODEC_ID_MPEG2VIDEO
, 20 }, /* MPEG HD */
113 { AV_CODEC_ID_MPEG1VIDEO
, 22 }, /* NTSC */
114 { AV_CODEC_ID_MPEG1VIDEO
, 23 }, /* PAL */
115 { AV_CODEC_ID_NONE
, 0 },
118 #define SERVER_PATH "EXT:/PDR/default/"
119 #define ES_NAME_PATTERN "EXT:/PDR/default/ES."
121 static int gxf_find_lines_index(AVStream
*st
)
123 GXFStreamContext
*sc
= st
->priv_data
;
126 for (i
= 0; i
< 6; ++i
) {
127 if (st
->codec
->height
== gxf_lines_tab
[i
].height
) {
128 sc
->lines_index
= gxf_lines_tab
[i
].index
;
135 static void gxf_write_padding(AVIOContext
*pb
, int64_t to_pad
)
137 for (; to_pad
> 0; to_pad
--) {
142 static int64_t updatePacketSize(AVIOContext
*pb
, int64_t pos
)
147 size
= avio_tell(pb
) - pos
;
149 gxf_write_padding(pb
, 4 - size
% 4);
150 size
= avio_tell(pb
) - pos
;
152 curpos
= avio_tell(pb
);
153 avio_seek(pb
, pos
+ 6, SEEK_SET
);
155 avio_seek(pb
, curpos
, SEEK_SET
);
159 static int64_t updateSize(AVIOContext
*pb
, int64_t pos
)
163 curpos
= avio_tell(pb
);
164 avio_seek(pb
, pos
, SEEK_SET
);
165 avio_wb16(pb
, curpos
- pos
- 2);
166 avio_seek(pb
, curpos
, SEEK_SET
);
170 static void gxf_write_packet_header(AVIOContext
*pb
, GXFPktType type
)
172 avio_wb32(pb
, 0); /* packet leader for synchro */
174 avio_w8(pb
, type
); /* map packet */
175 avio_wb32(pb
, 0); /* size */
176 avio_wb32(pb
, 0); /* reserved */
177 avio_w8(pb
, 0xE1); /* trailer 1 */
178 avio_w8(pb
, 0xE2); /* trailer 2 */
181 static int gxf_write_mpeg_auxiliary(AVIOContext
*pb
, AVStream
*st
)
183 GXFStreamContext
*sc
= st
->priv_data
;
185 int size
, starting_line
;
188 sc
->p_per_gop
= sc
->pframes
/ sc
->iframes
;
189 if (sc
->pframes
% sc
->iframes
)
192 sc
->b_per_i_or_p
= sc
->bframes
/ sc
->pframes
;
193 if (sc
->bframes
% sc
->pframes
)
196 if (sc
->p_per_gop
> 9)
197 sc
->p_per_gop
= 9; /* ensure value won't take more than one char */
198 if (sc
->b_per_i_or_p
> 9)
199 sc
->b_per_i_or_p
= 9; /* ensure value won't take more than one char */
201 if (st
->codec
->height
== 512 || st
->codec
->height
== 608)
202 starting_line
= 7; // VBI
203 else if (st
->codec
->height
== 480)
206 starting_line
= 23; // default PAL
208 size
= snprintf(buffer
, sizeof(buffer
), "Ver 1\nBr %.6f\nIpg 1\nPpi %d\nBpiop %d\n"
209 "Pix 0\nCf %d\nCg %d\nSl %d\nnl16 %d\nVi 1\nf1 1\n",
210 (float)st
->codec
->bit_rate
, sc
->p_per_gop
, sc
->b_per_i_or_p
,
211 st
->codec
->pix_fmt
== AV_PIX_FMT_YUV422P
? 2 : 1, sc
->first_gop_closed
== 1,
212 starting_line
, (st
->codec
->height
+ 15) / 16);
213 av_assert0(size
< sizeof(buffer
));
214 avio_w8(pb
, TRACK_MPG_AUX
);
215 avio_w8(pb
, size
+ 1);
216 avio_write(pb
, (uint8_t *)buffer
, size
+ 1);
220 static int gxf_write_dv_auxiliary(AVIOContext
*pb
, AVStream
*st
)
222 int64_t track_aux_data
= 0;
224 avio_w8(pb
, TRACK_AUX
);
226 if (st
->codec
->pix_fmt
== AV_PIX_FMT_YUV420P
)
227 track_aux_data
|= 0x01; /* marks stream as DVCAM instead of DVPRO */
228 track_aux_data
|= 0x40000000; /* aux data is valid */
229 avio_wl64(pb
, track_aux_data
);
233 static int gxf_write_timecode_auxiliary(AVIOContext
*pb
, GXFContext
*gxf
)
235 uint32_t timecode
= GXF_TIMECODE(gxf
->tc
.color
, gxf
->tc
.drop
,
236 gxf
->tc
.hh
, gxf
->tc
.mm
,
237 gxf
->tc
.ss
, gxf
->tc
.ff
);
239 avio_w8(pb
, TRACK_AUX
);
241 avio_wl32(pb
, timecode
);
247 static int gxf_write_track_description(AVFormatContext
*s
, GXFStreamContext
*sc
, int index
)
249 GXFContext
*gxf
= s
->priv_data
;
250 AVIOContext
*pb
= s
->pb
;
253 /* track description section */
254 avio_w8(pb
, sc
->media_type
+ 0x80);
255 avio_w8(pb
, index
+ 0xC0);
258 avio_wb16(pb
, 0); /* size */
260 /* media file name */
261 avio_w8(pb
, TRACK_NAME
);
262 avio_w8(pb
, strlen(ES_NAME_PATTERN
) + 3);
263 avio_write(pb
, ES_NAME_PATTERN
, sizeof(ES_NAME_PATTERN
) - 1);
264 avio_wb16(pb
, sc
->media_info
);
267 switch (sc
->track_type
) {
268 case 3: /* timecode */
269 gxf_write_timecode_auxiliary(pb
, gxf
);
273 gxf_write_mpeg_auxiliary(pb
, s
->streams
[index
]);
277 gxf_write_dv_auxiliary(pb
, s
->streams
[index
]);
280 avio_w8(pb
, TRACK_AUX
);
285 /* file system version */
286 avio_w8(pb
, TRACK_VER
);
291 avio_w8(pb
, TRACK_FPS
);
293 avio_wb32(pb
, sc
->frame_rate_index
);
295 /* lines per frame */
296 avio_w8(pb
, TRACK_LINES
);
298 avio_wb32(pb
, sc
->lines_index
);
300 /* fields per frame */
301 avio_w8(pb
, TRACK_FPF
);
303 avio_wb32(pb
, sc
->fields
);
305 return updateSize(pb
, pos
);
308 static int gxf_write_material_data_section(AVFormatContext
*s
)
310 GXFContext
*gxf
= s
->priv_data
;
311 AVIOContext
*pb
= s
->pb
;
314 const char *filename
= strrchr(s
->filename
, '/');
317 avio_wb16(pb
, 0); /* size */
323 filename
= s
->filename
;
324 len
= strlen(filename
);
326 avio_w8(pb
, MAT_NAME
);
327 avio_w8(pb
, strlen(SERVER_PATH
) + len
+ 1);
328 avio_write(pb
, SERVER_PATH
, sizeof(SERVER_PATH
) - 1);
329 avio_write(pb
, filename
, len
);
333 avio_w8(pb
, MAT_FIRST_FIELD
);
338 avio_w8(pb
, MAT_LAST_FIELD
);
340 avio_wb32(pb
, gxf
->nb_fields
);
343 avio_w8(pb
, MAT_MARK_IN
);
347 avio_w8(pb
, MAT_MARK_OUT
);
349 avio_wb32(pb
, gxf
->nb_fields
);
352 avio_w8(pb
, MAT_SIZE
);
354 avio_wb32(pb
, avio_size(pb
) / 1024);
356 return updateSize(pb
, pos
);
359 static int gxf_write_track_description_section(AVFormatContext
*s
)
361 GXFContext
*gxf
= s
->priv_data
;
362 AVIOContext
*pb
= s
->pb
;
367 avio_wb16(pb
, 0); /* size */
368 for (i
= 0; i
< s
->nb_streams
; ++i
)
369 gxf_write_track_description(s
, s
->streams
[i
]->priv_data
, i
);
371 gxf_write_track_description(s
, &gxf
->timecode_track
, s
->nb_streams
);
373 return updateSize(pb
, pos
);
376 static int gxf_write_map_packet(AVFormatContext
*s
, int rewrite
)
378 GXFContext
*gxf
= s
->priv_data
;
379 AVIOContext
*pb
= s
->pb
;
380 int64_t pos
= avio_tell(pb
);
383 if (!(gxf
->map_offsets_nb
% 30)) {
385 if ((err
= av_reallocp_array(&gxf
->map_offsets
,
386 gxf
->map_offsets_nb
+ 30,
387 sizeof(*gxf
->map_offsets
))) < 0) {
388 gxf
->map_offsets_nb
= 0;
389 av_log(s
, AV_LOG_ERROR
, "could not realloc map offsets\n");
393 gxf
->map_offsets
[gxf
->map_offsets_nb
++] = pos
; // do not increment here
396 gxf_write_packet_header(pb
, PKT_MAP
);
399 avio_w8(pb
, 0xE0); /* version */
400 avio_w8(pb
, 0xFF); /* reserved */
402 gxf_write_material_data_section(s
);
403 gxf_write_track_description_section(s
);
405 return updatePacketSize(pb
, pos
);
408 static int gxf_write_flt_packet(AVFormatContext
*s
)
410 GXFContext
*gxf
= s
->priv_data
;
411 AVIOContext
*pb
= s
->pb
;
412 int64_t pos
= avio_tell(pb
);
413 int fields_per_flt
= (gxf
->nb_fields
+1) / 1000 + 1;
414 int flt_entries
= gxf
->nb_fields
/ fields_per_flt
;
417 gxf_write_packet_header(pb
, PKT_FLT
);
419 avio_wl32(pb
, fields_per_flt
); /* number of fields */
420 avio_wl32(pb
, flt_entries
); /* number of active flt entries */
422 if (gxf
->flt_entries
) {
423 for (i
= 0; i
< flt_entries
; i
++)
424 avio_wl32(pb
, gxf
->flt_entries
[(i
*fields_per_flt
)>>1]);
427 for (; i
< 1000; i
++)
430 return updatePacketSize(pb
, pos
);
433 static int gxf_write_umf_material_description(AVFormatContext
*s
)
435 GXFContext
*gxf
= s
->priv_data
;
436 AVIOContext
*pb
= s
->pb
;
437 int timecode_base
= gxf
->time_base
.den
== 60000 ? 60 : 50;
438 int64_t timestamp
= 0;
439 AVDictionaryEntry
*t
;
441 uint32_t timecode_in
; // timecode at mark in
442 uint32_t timecode_out
; // timecode at mark out
444 if (t
= av_dict_get(s
->metadata
, "creation_time", NULL
, 0))
445 timestamp
= ff_iso8601_to_unix_time(t
->value
);
447 timecode_in
= GXF_TIMECODE(gxf
->tc
.color
, gxf
->tc
.drop
,
448 gxf
->tc
.hh
, gxf
->tc
.mm
,
449 gxf
->tc
.ss
, gxf
->tc
.ff
);
451 nb_fields
= gxf
->nb_fields
+
452 gxf
->tc
.hh
* (timecode_base
* 3600) +
453 gxf
->tc
.mm
* (timecode_base
* 60) +
454 gxf
->tc
.ss
* timecode_base
+
457 timecode_out
= GXF_TIMECODE(gxf
->tc
.color
, gxf
->tc
.drop
,
458 nb_fields
/ (timecode_base
* 3600) % 24,
459 nb_fields
/ (timecode_base
* 60) % 60,
460 nb_fields
/ timecode_base
% 60,
461 nb_fields
% timecode_base
);
463 avio_wl32(pb
, gxf
->flags
);
464 avio_wl32(pb
, gxf
->nb_fields
); /* length of the longest track */
465 avio_wl32(pb
, gxf
->nb_fields
); /* length of the shortest track */
466 avio_wl32(pb
, 0); /* mark in */
467 avio_wl32(pb
, gxf
->nb_fields
); /* mark out */
468 avio_wl32(pb
, timecode_in
); /* timecode mark in */
469 avio_wl32(pb
, timecode_out
); /* timecode mark out */
470 avio_wl64(pb
, timestamp
); /* modification time */
471 avio_wl64(pb
, timestamp
); /* creation time */
472 avio_wl16(pb
, 0); /* reserved */
473 avio_wl16(pb
, 0); /* reserved */
474 avio_wl16(pb
, gxf
->audio_tracks
);
475 avio_wl16(pb
, 1); /* timecode track count */
476 avio_wl16(pb
, 0); /* reserved */
477 avio_wl16(pb
, gxf
->mpeg_tracks
);
481 static int gxf_write_umf_payload(AVFormatContext
*s
)
483 GXFContext
*gxf
= s
->priv_data
;
484 AVIOContext
*pb
= s
->pb
;
486 avio_wl32(pb
, gxf
->umf_length
); /* total length of the umf data */
487 avio_wl32(pb
, 3); /* version */
488 avio_wl32(pb
, s
->nb_streams
+1);
489 avio_wl32(pb
, gxf
->umf_track_offset
); /* umf track section offset */
490 avio_wl32(pb
, gxf
->umf_track_size
);
491 avio_wl32(pb
, s
->nb_streams
+1);
492 avio_wl32(pb
, gxf
->umf_media_offset
);
493 avio_wl32(pb
, gxf
->umf_media_size
);
494 avio_wl32(pb
, gxf
->umf_length
); /* user data offset */
495 avio_wl32(pb
, 0); /* user data size */
496 avio_wl32(pb
, 0); /* reserved */
497 avio_wl32(pb
, 0); /* reserved */
501 static int gxf_write_umf_track_description(AVFormatContext
*s
)
503 AVIOContext
*pb
= s
->pb
;
504 GXFContext
*gxf
= s
->priv_data
;
505 int64_t pos
= avio_tell(pb
);
508 gxf
->umf_track_offset
= pos
- gxf
->umf_start_offset
;
509 for (i
= 0; i
< s
->nb_streams
; ++i
) {
510 GXFStreamContext
*sc
= s
->streams
[i
]->priv_data
;
511 avio_wl16(pb
, sc
->media_info
);
515 avio_wl16(pb
, gxf
->timecode_track
.media_info
);
518 return avio_tell(pb
) - pos
;
521 static int gxf_write_umf_media_mpeg(AVIOContext
*pb
, AVStream
*st
)
523 GXFStreamContext
*sc
= st
->priv_data
;
525 if (st
->codec
->pix_fmt
== AV_PIX_FMT_YUV422P
)
528 avio_wl32(pb
, 1); /* default to 420 */
529 avio_wl32(pb
, sc
->first_gop_closed
== 1); /* closed = 1, open = 0, unknown = 255 */
530 avio_wl32(pb
, 3); /* top = 1, bottom = 2, frame = 3, unknown = 0 */
531 avio_wl32(pb
, 1); /* I picture per GOP */
532 avio_wl32(pb
, sc
->p_per_gop
);
533 avio_wl32(pb
, sc
->b_per_i_or_p
);
534 if (st
->codec
->codec_id
== AV_CODEC_ID_MPEG2VIDEO
)
536 else if (st
->codec
->codec_id
== AV_CODEC_ID_MPEG1VIDEO
)
540 avio_wl32(pb
, 0); /* reserved */
544 static int gxf_write_umf_media_timecode(AVIOContext
*pb
, int drop
)
546 avio_wl32(pb
, drop
); /* drop frame */
547 avio_wl32(pb
, 0); /* reserved */
548 avio_wl32(pb
, 0); /* reserved */
549 avio_wl32(pb
, 0); /* reserved */
550 avio_wl32(pb
, 0); /* reserved */
551 avio_wl32(pb
, 0); /* reserved */
552 avio_wl32(pb
, 0); /* reserved */
553 avio_wl32(pb
, 0); /* reserved */
557 static int gxf_write_umf_media_dv(AVIOContext
*pb
, GXFStreamContext
*sc
, AVStream
*st
)
561 if (st
->codec
->pix_fmt
== AV_PIX_FMT_YUV420P
)
562 dv_umf_data
|= 0x20; /* marks as DVCAM instead of DVPRO */
563 avio_wl32(pb
, dv_umf_data
);
574 static int gxf_write_umf_media_audio(AVIOContext
*pb
, GXFStreamContext
*sc
)
576 avio_wl64(pb
, av_double2int(1)); /* sound level to begin to */
577 avio_wl64(pb
, av_double2int(1)); /* sound level to begin to */
578 avio_wl32(pb
, 0); /* number of fields over which to ramp up sound level */
579 avio_wl32(pb
, 0); /* number of fields over which to ramp down sound level */
580 avio_wl32(pb
, 0); /* reserved */
581 avio_wl32(pb
, 0); /* reserved */
585 static int gxf_write_umf_media_description(AVFormatContext
*s
)
587 GXFContext
*gxf
= s
->priv_data
;
588 AVIOContext
*pb
= s
->pb
;
593 gxf
->umf_media_offset
= pos
- gxf
->umf_start_offset
;
594 for (i
= 0; i
<= s
->nb_streams
; ++i
) {
595 GXFStreamContext
*sc
;
596 int64_t startpos
, curpos
;
598 if (i
== s
->nb_streams
)
599 sc
= &gxf
->timecode_track
;
601 sc
= s
->streams
[i
]->priv_data
;
603 startpos
= avio_tell(pb
);
604 avio_wl16(pb
, 0); /* length */
605 avio_wl16(pb
, sc
->media_info
);
606 avio_wl16(pb
, 0); /* reserved */
607 avio_wl16(pb
, 0); /* reserved */
608 avio_wl32(pb
, gxf
->nb_fields
);
609 avio_wl32(pb
, 0); /* attributes rw, ro */
610 avio_wl32(pb
, 0); /* mark in */
611 avio_wl32(pb
, gxf
->nb_fields
); /* mark out */
612 avio_write(pb
, ES_NAME_PATTERN
, strlen(ES_NAME_PATTERN
));
613 avio_wb16(pb
, sc
->media_info
);
614 for (j
= strlen(ES_NAME_PATTERN
)+2; j
< 88; j
++)
616 avio_wl32(pb
, sc
->track_type
);
617 avio_wl32(pb
, sc
->sample_rate
);
618 avio_wl32(pb
, sc
->sample_size
);
619 avio_wl32(pb
, 0); /* reserved */
621 if (sc
== &gxf
->timecode_track
)
622 gxf_write_umf_media_timecode(pb
, gxf
->tc
.drop
);
624 AVStream
*st
= s
->streams
[i
];
625 switch (st
->codec
->codec_id
) {
626 case AV_CODEC_ID_MPEG1VIDEO
:
627 case AV_CODEC_ID_MPEG2VIDEO
:
628 gxf_write_umf_media_mpeg(pb
, st
);
630 case AV_CODEC_ID_PCM_S16LE
:
631 gxf_write_umf_media_audio(pb
, sc
);
633 case AV_CODEC_ID_DVVIDEO
:
634 gxf_write_umf_media_dv(pb
, sc
, st
);
639 curpos
= avio_tell(pb
);
640 avio_seek(pb
, startpos
, SEEK_SET
);
641 avio_wl16(pb
, curpos
- startpos
);
642 avio_seek(pb
, curpos
, SEEK_SET
);
644 return avio_tell(pb
) - pos
;
647 static int gxf_write_umf_packet(AVFormatContext
*s
)
649 GXFContext
*gxf
= s
->priv_data
;
650 AVIOContext
*pb
= s
->pb
;
651 int64_t pos
= avio_tell(pb
);
653 gxf_write_packet_header(pb
, PKT_UMF
);
656 avio_w8(pb
, 3); /* first and last (only) packet */
657 avio_wb32(pb
, gxf
->umf_length
); /* data length */
659 gxf
->umf_start_offset
= avio_tell(pb
);
660 gxf_write_umf_payload(s
);
661 gxf_write_umf_material_description(s
);
662 gxf
->umf_track_size
= gxf_write_umf_track_description(s
);
663 gxf
->umf_media_size
= gxf_write_umf_media_description(s
);
664 gxf
->umf_length
= avio_tell(pb
) - gxf
->umf_start_offset
;
665 return updatePacketSize(pb
, pos
);
668 static const int GXF_samples_per_frame
[] = { 32768, 0 };
670 static void gxf_init_timecode_track(GXFStreamContext
*sc
, GXFStreamContext
*vsc
)
675 sc
->media_type
= vsc
->sample_rate
== 60 ? 7 : 8;
676 sc
->sample_rate
= vsc
->sample_rate
;
677 sc
->media_info
= ('T'<<8) | '0';
679 sc
->frame_rate_index
= vsc
->frame_rate_index
;
680 sc
->lines_index
= vsc
->lines_index
;
681 sc
->sample_size
= 16;
682 sc
->fields
= vsc
->fields
;
685 static int gxf_init_timecode(AVFormatContext
*s
, GXFTimecode
*tc
, const char *tcstr
, int fields
)
689 if (sscanf(tcstr
, "%d:%d:%d%c%d", &tc
->hh
, &tc
->mm
, &tc
->ss
, &c
, &tc
->ff
) != 5) {
690 av_log(s
, AV_LOG_ERROR
, "unable to parse timecode, "
691 "syntax: hh:mm:ss[:;.]ff\n");
704 static int gxf_write_header(AVFormatContext
*s
)
706 AVIOContext
*pb
= s
->pb
;
707 GXFContext
*gxf
= s
->priv_data
;
708 GXFStreamContext
*vsc
= NULL
;
709 uint8_t tracks
[255] = {0};
710 int i
, media_info
= 0;
712 AVDictionaryEntry
*tcr
= av_dict_get(s
->metadata
, "timecode", NULL
, 0);
715 av_log(s
, AV_LOG_ERROR
, "gxf muxer does not support streamed output, patch welcome\n");
719 gxf
->flags
|= 0x00080000; /* material is simple clip */
720 for (i
= 0; i
< s
->nb_streams
; ++i
) {
721 AVStream
*st
= s
->streams
[i
];
722 GXFStreamContext
*sc
= av_mallocz(sizeof(*sc
));
724 return AVERROR(ENOMEM
);
727 sc
->media_type
= ff_codec_get_tag(gxf_media_types
, st
->codec
->codec_id
);
728 if (st
->codec
->codec_type
== AVMEDIA_TYPE_AUDIO
) {
729 if (st
->codec
->codec_id
!= AV_CODEC_ID_PCM_S16LE
) {
730 av_log(s
, AV_LOG_ERROR
, "only 16 BIT PCM LE allowed for now\n");
733 if (st
->codec
->sample_rate
!= 48000) {
734 av_log(s
, AV_LOG_ERROR
, "only 48000hz sampling rate is allowed\n");
737 if (st
->codec
->channels
!= 1) {
738 av_log(s
, AV_LOG_ERROR
, "only mono tracks are allowed\n");
742 sc
->sample_rate
= st
->codec
->sample_rate
;
743 avpriv_set_pts_info(st
, 64, 1, sc
->sample_rate
);
744 sc
->sample_size
= 16;
745 sc
->frame_rate_index
= -2;
746 sc
->lines_index
= -2;
749 gxf
->flags
|= 0x04000000; /* audio is 16 bit pcm */
751 } else if (st
->codec
->codec_type
== AVMEDIA_TYPE_VIDEO
) {
753 av_log(s
, AV_LOG_ERROR
, "video stream must be the first track\n");
756 /* FIXME check from time_base ? */
757 if (st
->codec
->height
== 480 || st
->codec
->height
== 512) { /* NTSC or NTSC+VBI */
758 sc
->frame_rate_index
= 5;
759 sc
->sample_rate
= 60;
760 gxf
->flags
|= 0x00000080;
761 gxf
->time_base
= (AVRational
){ 1001, 60000 };
762 } else if (st
->codec
->height
== 576 || st
->codec
->height
== 608) { /* PAL or PAL+VBI */
763 sc
->frame_rate_index
= 6;
765 sc
->sample_rate
= 50;
766 gxf
->flags
|= 0x00000040;
767 gxf
->time_base
= (AVRational
){ 1, 50 };
769 av_log(s
, AV_LOG_ERROR
, "unsupported video resolution, "
770 "gxf muxer only accepts PAL or NTSC resolutions currently\n");
774 tcr
= av_dict_get(st
->metadata
, "timecode", NULL
, 0);
775 avpriv_set_pts_info(st
, 64, gxf
->time_base
.num
, gxf
->time_base
.den
);
776 if (gxf_find_lines_index(st
) < 0)
777 sc
->lines_index
= -1;
778 sc
->sample_size
= st
->codec
->bit_rate
;
779 sc
->fields
= 2; /* interlaced */
783 switch (st
->codec
->codec_id
) {
784 case AV_CODEC_ID_MJPEG
:
786 gxf
->flags
|= 0x00004000;
789 case AV_CODEC_ID_MPEG1VIDEO
:
794 case AV_CODEC_ID_MPEG2VIDEO
:
795 sc
->first_gop_closed
= -1;
798 gxf
->flags
|= 0x00008000;
801 case AV_CODEC_ID_DVVIDEO
:
802 if (st
->codec
->pix_fmt
== AV_PIX_FMT_YUV422P
) {
805 gxf
->flags
|= 0x00002000;
809 gxf
->flags
|= 0x00001000;
814 av_log(s
, AV_LOG_ERROR
, "video codec not supported\n");
818 /* FIXME first 10 audio tracks are 0 to 9 next 22 are A to V */
819 sc
->media_info
= media_info
<<8 | ('0'+tracks
[media_info
]++);
820 sc
->order
= s
->nb_streams
- st
->index
;
823 if (ff_audio_interleave_init(s
, GXF_samples_per_frame
, (AVRational
){ 1, 48000 }) < 0)
827 gxf_init_timecode(s
, &gxf
->tc
, tcr
->value
, vsc
->fields
);
829 gxf_init_timecode_track(&gxf
->timecode_track
, vsc
);
830 gxf
->flags
|= 0x200000; // time code track is non-drop frame
832 if ((ret
= gxf_write_map_packet(s
, 0)) < 0)
834 gxf_write_flt_packet(s
);
835 gxf_write_umf_packet(s
);
837 gxf
->packet_count
= 3;
843 static int gxf_write_eos_packet(AVIOContext
*pb
)
845 int64_t pos
= avio_tell(pb
);
847 gxf_write_packet_header(pb
, PKT_EOS
);
848 return updatePacketSize(pb
, pos
);
851 static int gxf_write_trailer(AVFormatContext
*s
)
853 GXFContext
*gxf
= s
->priv_data
;
854 AVIOContext
*pb
= s
->pb
;
859 ff_audio_interleave_close(s
);
861 gxf_write_eos_packet(pb
);
863 avio_seek(pb
, 0, SEEK_SET
);
864 /* overwrite map, flt and umf packets with new values */
865 if ((ret
= gxf_write_map_packet(s
, 1)) < 0)
867 gxf_write_flt_packet(s
);
868 gxf_write_umf_packet(s
);
870 /* update duration in all map packets */
871 for (i
= 1; i
< gxf
->map_offsets_nb
; i
++) {
872 avio_seek(pb
, gxf
->map_offsets
[i
], SEEK_SET
);
873 if ((ret
= gxf_write_map_packet(s
, 1)) < 0)
878 avio_seek(pb
, end
, SEEK_SET
);
880 av_freep(&gxf
->flt_entries
);
881 av_freep(&gxf
->map_offsets
);
886 static int gxf_parse_mpeg_frame(GXFStreamContext
*sc
, const uint8_t *buf
, int size
)
890 for(i
=0; i
<size
-4 && c
!=0x100; i
++){
892 if(c
== 0x1B8 && sc
->first_gop_closed
== -1) /* GOP start code */
893 sc
->first_gop_closed
= (buf
[i
+4]>>6)&1;
895 return (buf
[i
+1]>>3)&7;
898 static int gxf_write_media_preamble(AVFormatContext
*s
, AVPacket
*pkt
, int size
)
900 GXFContext
*gxf
= s
->priv_data
;
901 AVIOContext
*pb
= s
->pb
;
902 AVStream
*st
= s
->streams
[pkt
->stream_index
];
903 GXFStreamContext
*sc
= st
->priv_data
;
905 /* If the video is frame-encoded, the frame numbers shall be represented by
906 * even field numbers.
907 * see SMPTE360M-2004 6.4.2.1.3 Media field number */
908 if (st
->codec
->codec_type
== AVMEDIA_TYPE_VIDEO
) {
909 field_nb
= gxf
->nb_fields
;
911 field_nb
= av_rescale_rnd(pkt
->dts
, gxf
->time_base
.den
,
912 (int64_t)48000*gxf
->time_base
.num
, AV_ROUND_UP
);
915 avio_w8(pb
, sc
->media_type
);
916 avio_w8(pb
, st
->index
);
917 avio_wb32(pb
, field_nb
);
918 if (st
->codec
->codec_type
== AVMEDIA_TYPE_AUDIO
) {
920 avio_wb16(pb
, size
/ 2);
921 } else if (st
->codec
->codec_id
== AV_CODEC_ID_MPEG2VIDEO
) {
922 int frame_type
= gxf_parse_mpeg_frame(sc
, pkt
->data
, pkt
->size
);
923 if (frame_type
== AV_PICTURE_TYPE_I
) {
926 } else if (frame_type
== AV_PICTURE_TYPE_B
) {
934 } else if (st
->codec
->codec_id
== AV_CODEC_ID_DVVIDEO
) {
935 avio_w8(pb
, size
/ 4096);
939 avio_wb32(pb
, field_nb
);
940 avio_w8(pb
, 1); /* flags */
941 avio_w8(pb
, 0); /* reserved */
945 static int gxf_write_packet(AVFormatContext
*s
, AVPacket
*pkt
)
947 GXFContext
*gxf
= s
->priv_data
;
948 AVIOContext
*pb
= s
->pb
;
949 AVStream
*st
= s
->streams
[pkt
->stream_index
];
950 int64_t pos
= avio_tell(pb
);
952 unsigned packet_start_offset
= avio_tell(pb
) / 1024;
955 gxf_write_packet_header(pb
, PKT_MEDIA
);
956 if (st
->codec
->codec_id
== AV_CODEC_ID_MPEG2VIDEO
&& pkt
->size
% 4) /* MPEG-2 frames must be padded */
957 padding
= 4 - pkt
->size
% 4;
958 else if (st
->codec
->codec_type
== AVMEDIA_TYPE_AUDIO
)
959 padding
= GXF_AUDIO_PACKET_SIZE
- pkt
->size
;
960 gxf_write_media_preamble(s
, pkt
, pkt
->size
+ padding
);
961 avio_write(pb
, pkt
->data
, pkt
->size
);
962 gxf_write_padding(pb
, padding
);
964 if (st
->codec
->codec_type
== AVMEDIA_TYPE_VIDEO
) {
965 if (!(gxf
->flt_entries_nb
% 500)) {
967 if ((err
= av_reallocp_array(&gxf
->flt_entries
,
968 gxf
->flt_entries_nb
+ 500,
969 sizeof(*gxf
->flt_entries
))) < 0) {
970 gxf
->flt_entries_nb
= 0;
972 av_log(s
, AV_LOG_ERROR
, "could not reallocate flt entries\n");
976 gxf
->flt_entries
[gxf
->flt_entries_nb
++] = packet_start_offset
;
977 gxf
->nb_fields
+= 2; // count fields
980 updatePacketSize(pb
, pos
);
983 if (gxf
->packet_count
== 100) {
984 if ((ret
= gxf_write_map_packet(s
, 0)) < 0)
986 gxf
->packet_count
= 0;
992 static int gxf_compare_field_nb(AVFormatContext
*s
, AVPacket
*next
, AVPacket
*cur
)
994 GXFContext
*gxf
= s
->priv_data
;
995 AVPacket
*pkt
[2] = { cur
, next
};
997 GXFStreamContext
*sc
[2];
999 for (i
= 0; i
< 2; i
++) {
1000 AVStream
*st
= s
->streams
[pkt
[i
]->stream_index
];
1001 sc
[i
] = st
->priv_data
;
1002 if (st
->codec
->codec_type
== AVMEDIA_TYPE_AUDIO
) {
1003 field_nb
[i
] = av_rescale_rnd(pkt
[i
]->dts
, gxf
->time_base
.den
,
1004 (int64_t)48000*gxf
->time_base
.num
, AV_ROUND_UP
);
1005 field_nb
[i
] &= ~1; // compare against even field number because audio must be before video
1007 field_nb
[i
] = pkt
[i
]->dts
; // dts are field based
1010 return field_nb
[1] > field_nb
[0] ||
1011 (field_nb
[1] == field_nb
[0] && sc
[1]->order
> sc
[0]->order
);
1014 static int gxf_interleave_packet(AVFormatContext
*s
, AVPacket
*out
, AVPacket
*pkt
, int flush
)
1016 if (pkt
&& s
->streams
[pkt
->stream_index
]->codec
->codec_type
== AVMEDIA_TYPE_VIDEO
)
1017 pkt
->duration
= 2; // enforce 2 fields
1018 return ff_audio_rechunk_interleave(s
, out
, pkt
, flush
,
1019 ff_interleave_packet_per_dts
, gxf_compare_field_nb
);
1022 AVOutputFormat ff_gxf_muxer
= {
1024 .long_name
= NULL_IF_CONFIG_SMALL("GXF (General eXchange Format)"),
1025 .extensions
= "gxf",
1026 .priv_data_size
= sizeof(GXFContext
),
1027 .audio_codec
= AV_CODEC_ID_PCM_S16LE
,
1028 .video_codec
= AV_CODEC_ID_MPEG2VIDEO
,
1029 .write_header
= gxf_write_header
,
1030 .write_packet
= gxf_write_packet
,
1031 .write_trailer
= gxf_write_trailer
,
1032 .interleave_packet
= gxf_interleave_packet
,