FFmpeg
Loading...
Searching...
No Matches
gxfenc.c
Go to the documentation of this file.
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/avassert.h"
23#include "libavutil/intfloat.h"
25#include "libavutil/mem.h"
26#include "avformat.h"
27#include "avio_internal.h"
28#include "internal.h"
29#include "gxf.h"
30#include "mux.h"
31
32#define GXF_SAMPLES_PER_FRAME 32768
33#define GXF_AUDIO_PACKET_SIZE 65536
34
35#define GXF_TIMECODE(c, d, h, m, s, f) \
36 ((c) << 30 | (d) << 29 | (h) << 24 | (m) << 16 | (s) << 8 | (f))
37
38typedef struct GXFTimecode{
39 int hh;
40 int mm;
41 int ss;
42 int ff;
43 int color;
44 int drop;
46
47typedef struct GXFStreamContext {
49 uint32_t track_type;
50 uint32_t sample_size;
51 uint32_t sample_rate;
52 uint16_t media_type;
53 uint16_t media_info;
56 int fields;
61 int b_per_i_or_p; ///< number of B-frames per I-frame or P-frame
63 unsigned order; ///< interleaving order
65
66typedef struct GXFContext {
68 uint32_t nb_fields;
69 uint16_t audio_tracks;
70 uint16_t mpeg_tracks;
75 uint32_t umf_length;
79 int flags;
81 unsigned *flt_entries; ///< offsets of packets /1024, starts after 2nd video field
83 uint64_t *map_offsets; ///< offset of map packets
85 unsigned packet_count;
88
89static const struct {
91} gxf_lines_tab[] = {
92 { 480, 1 }, /* NTSC */
93 { 512, 1 }, /* NTSC + VBI */
94 { 576, 2 }, /* PAL */
95 { 608, 2 }, /* PAL + VBI */
96 { 1080, 4 },
97 { 720, 6 },
98};
99
100static const AVCodecTag gxf_media_types[] = {
101 { AV_CODEC_ID_MJPEG , 3 }, /* NTSC */
102 { AV_CODEC_ID_MJPEG , 4 }, /* PAL */
103 { AV_CODEC_ID_PCM_S24LE , 9 },
104 { AV_CODEC_ID_PCM_S16LE , 10 },
105 { AV_CODEC_ID_MPEG2VIDEO, 11 }, /* NTSC */
106 { AV_CODEC_ID_MPEG2VIDEO, 12 }, /* PAL */
107 { AV_CODEC_ID_DVVIDEO , 13 }, /* NTSC */
108 { AV_CODEC_ID_DVVIDEO , 14 }, /* PAL */
109 { AV_CODEC_ID_DVVIDEO , 15 }, /* 50M NTSC */
110 { AV_CODEC_ID_DVVIDEO , 16 }, /* 50M PAL */
111 { AV_CODEC_ID_AC3 , 17 },
112 //{ AV_CODEC_ID_NONE, , 18 }, /* Non compressed 24 bit audio */
113 { AV_CODEC_ID_MPEG2VIDEO, 20 }, /* MPEG HD */
114 { AV_CODEC_ID_MPEG1VIDEO, 22 }, /* NTSC */
115 { AV_CODEC_ID_MPEG1VIDEO, 23 }, /* PAL */
116 { AV_CODEC_ID_NONE, 0 },
117};
118
119#define SERVER_PATH "EXT:/PDR/default/"
120#define ES_NAME_PATTERN "EXT:/PDR/default/ES."
121
123{
124 GXFStreamContext *sc = st->priv_data;
125 int i;
126
127 for (i = 0; i < 6; ++i) {
128 if (st->codecpar->height == gxf_lines_tab[i].height) {
129 sc->lines_index = gxf_lines_tab[i].index;
130 return 0;
131 }
132 }
133 return -1;
134}
135
136static void gxf_write_padding(AVIOContext *pb, int64_t to_pad)
137{
138 ffio_fill(pb, 0, to_pad);
139}
140
142{
143 int64_t curpos;
144 int size;
145
146 size = avio_tell(pb) - pos;
147 if (size % 4) {
148 gxf_write_padding(pb, 4 - size % 4);
149 size = avio_tell(pb) - pos;
150 }
151 curpos = avio_tell(pb);
152 avio_seek(pb, pos + 6, SEEK_SET);
153 avio_wb32(pb, size);
154 avio_seek(pb, curpos, SEEK_SET);
155 return curpos - pos;
156}
157
159{
160 int64_t curpos;
161
162 curpos = avio_tell(pb);
163 avio_seek(pb, pos, SEEK_SET);
164 avio_wb16(pb, curpos - pos - 2);
165 avio_seek(pb, curpos, SEEK_SET);
166 return curpos - pos;
167}
168
170{
171 avio_wb32(pb, 0); /* packet leader for synchro */
172 avio_w8(pb, 1);
173 avio_w8(pb, type); /* map packet */
174 avio_wb32(pb, 0); /* size */
175 avio_wb32(pb, 0); /* reserved */
176 avio_w8(pb, 0xE1); /* trailer 1 */
177 avio_w8(pb, 0xE2); /* trailer 2 */
178}
179
181{
182 GXFStreamContext *sc = st->priv_data;
183 char buffer[1024];
184 int size, starting_line;
185
186 if (sc->iframes) {
187 sc->p_per_gop = sc->pframes / sc->iframes;
188 if (sc->pframes % sc->iframes)
189 sc->p_per_gop++;
190 if (sc->pframes) {
191 sc->b_per_i_or_p = sc->bframes / sc->pframes;
192 if (sc->bframes % sc->pframes)
193 sc->b_per_i_or_p++;
194 }
195 if (sc->p_per_gop > 9)
196 sc->p_per_gop = 9; /* ensure value won't take more than one char */
197 if (sc->b_per_i_or_p > 9)
198 sc->b_per_i_or_p = 9; /* ensure value won't take more than one char */
199 }
200 if (st->codecpar->height == 512 || st->codecpar->height == 608)
201 starting_line = 7; // VBI
202 else if (st->codecpar->height == 480)
203 starting_line = 20;
204 else
205 starting_line = 23; // default PAL
206
207 size = snprintf(buffer, sizeof(buffer), "Ver 1\nBr %.6f\nIpg 1\nPpi %d\nBpiop %d\n"
208 "Pix 0\nCf %d\nCg %d\nSl %d\nnl16 %d\nVi 1\nf1 1\n",
209 (float)st->codecpar->bit_rate, sc->p_per_gop, sc->b_per_i_or_p,
210 st->codecpar->format == AV_PIX_FMT_YUV422P ? 2 : 1, sc->first_gop_closed == 1,
211 starting_line, (st->codecpar->height + 15) / 16);
212 av_assert0(size < sizeof(buffer));
214 avio_w8(pb, size + 1);
215 avio_write(pb, (uint8_t *)buffer, size + 1);
216 return size + 3;
217}
218
220{
221 int64_t track_aux_data = 0;
222
223 avio_w8(pb, TRACK_AUX);
224 avio_w8(pb, 8);
226 track_aux_data |= 0x01; /* marks stream as DVCAM instead of DVPRO */
227 track_aux_data |= 0x40000000; /* aux data is valid */
228 avio_wl64(pb, track_aux_data);
229 return 8;
230}
231
233{
234 uint32_t timecode = GXF_TIMECODE(gxf->tc.color, gxf->tc.drop,
235 gxf->tc.hh, gxf->tc.mm,
236 gxf->tc.ss, gxf->tc.ff);
237
238 avio_w8(pb, TRACK_AUX);
239 avio_w8(pb, 8);
240 avio_wl32(pb, timecode);
241 /* reserved */
242 avio_wl32(pb, 0);
243 return 8;
244}
245
247{
248 GXFContext *gxf = s->priv_data;
249 AVIOContext *pb = s->pb;
250 int64_t pos;
251
252 /* track description section */
253 avio_w8(pb, sc->media_type + 0x80);
254 avio_w8(pb, index + 0xC0);
255
256 pos = avio_tell(pb);
257 avio_wb16(pb, 0); /* size */
258
259 /* media file name */
260 avio_w8(pb, TRACK_NAME);
261 avio_w8(pb, strlen(ES_NAME_PATTERN) + 3);
263 avio_wb16(pb, sc->media_info);
264 avio_w8(pb, 0);
265
266 switch (sc->track_type) {
267 case 3: /* timecode */
269 break;
270 case 4: /* MPEG2 */
271 case 9: /* MPEG1 */
272 gxf_write_mpeg_auxiliary(pb, s->streams[index]);
273 break;
274 case 5: /* DV25 */
275 case 6: /* DV50 */
276 gxf_write_dv_auxiliary(pb, s->streams[index]);
277 break;
278 default:
279 avio_w8(pb, TRACK_AUX);
280 avio_w8(pb, 8);
281 avio_wl64(pb, 0);
282 }
283
284 /* file system version */
285 avio_w8(pb, TRACK_VER);
286 avio_w8(pb, 4);
287 avio_wb32(pb, 0);
288
289 /* frame rate */
290 avio_w8(pb, TRACK_FPS);
291 avio_w8(pb, 4);
293
294 /* lines per frame */
295 avio_w8(pb, TRACK_LINES);
296 avio_w8(pb, 4);
297 avio_wb32(pb, sc->lines_index);
298
299 /* fields per frame */
300 avio_w8(pb, TRACK_FPF);
301 avio_w8(pb, 4);
302 avio_wb32(pb, sc->fields);
303
304 return update_size(pb, pos);
305}
306
308{
309 GXFContext *gxf = s->priv_data;
310 AVIOContext *pb = s->pb;
311 int64_t pos;
312 int len;
313 const char *filename = strrchr(s->url, '/');
314
315 pos = avio_tell(pb);
316 avio_wb16(pb, 0); /* size */
317
318 /* name */
319 if (filename)
320 filename++;
321 else
322 filename = s->url;
323 len = strlen(filename);
324
325 avio_w8(pb, MAT_NAME);
326 avio_w8(pb, strlen(SERVER_PATH) + len + 1);
327 avio_write(pb, SERVER_PATH, sizeof(SERVER_PATH) - 1);
328 avio_write(pb, filename, len);
329 avio_w8(pb, 0);
330
331 /* first field */
333 avio_w8(pb, 4);
334 avio_wb32(pb, 0);
335
336 /* last field */
338 avio_w8(pb, 4);
339 avio_wb32(pb, gxf->nb_fields);
340
341 /* reserved */
342 avio_w8(pb, MAT_MARK_IN);
343 avio_w8(pb, 4);
344 avio_wb32(pb, 0);
345
347 avio_w8(pb, 4);
348 avio_wb32(pb, gxf->nb_fields);
349
350 /* estimated size */
351 avio_w8(pb, MAT_SIZE);
352 avio_w8(pb, 4);
353 avio_wb32(pb, avio_size(pb) / 1024);
354
355 return update_size(pb, pos);
356}
357
359{
360 GXFContext *gxf = s->priv_data;
361 AVIOContext *pb = s->pb;
362 int64_t pos;
363 int i;
364
365 pos = avio_tell(pb);
366 avio_wb16(pb, 0); /* size */
367 for (i = 0; i < s->nb_streams; ++i)
368 gxf_write_track_description(s, s->streams[i]->priv_data, i);
369
370 gxf_write_track_description(s, &gxf->timecode_track, s->nb_streams);
371
372 return update_size(pb, pos);
373}
374
375static int gxf_write_map_packet(AVFormatContext *s, int rewrite)
376{
377 GXFContext *gxf = s->priv_data;
378 AVIOContext *pb = s->pb;
379 int64_t pos = avio_tell(pb);
380
381 if (!rewrite) {
382 if (!(gxf->map_offsets_nb % 30)) {
383 int err;
384 if ((err = av_reallocp_array(&gxf->map_offsets,
385 gxf->map_offsets_nb + 30,
386 sizeof(*gxf->map_offsets))) < 0) {
387 gxf->map_offsets_nb = 0;
388 av_log(s, AV_LOG_ERROR, "could not realloc map offsets\n");
389 return err;
390 }
391 }
392 gxf->map_offsets[gxf->map_offsets_nb++] = pos; // do not increment here
393 }
394
396
397 /* preamble */
398 avio_w8(pb, 0xE0); /* version */
399 avio_w8(pb, 0xFF); /* reserved */
400
403
404 return update_packet_size(pb, pos);
405}
406
408{
409 GXFContext *gxf = s->priv_data;
410 AVIOContext *pb = s->pb;
411 int64_t pos = avio_tell(pb);
412 int fields_per_flt = (gxf->nb_fields+1) / 1000 + 1;
413 int flt_entries = gxf->nb_fields / fields_per_flt;
414 int i = 0;
415
417
418 avio_wl32(pb, fields_per_flt); /* number of fields */
419 avio_wl32(pb, flt_entries); /* number of active flt entries */
420
421 if (gxf->flt_entries) {
422 for (i = 0; i < flt_entries; i++)
423 avio_wl32(pb, gxf->flt_entries[(i*fields_per_flt)>>1]);
424 }
425
426 ffio_fill(pb, 0, (1000 - i) * 4);
427
428 return update_packet_size(pb, pos);
429}
430
432{
433 GXFContext *gxf = s->priv_data;
434 AVIOContext *pb = s->pb;
435 int timecode_base = gxf->time_base.den == 60000 ? 60 : 50;
436 int64_t timestamp = 0;
437 uint64_t nb_fields;
438 uint32_t timecode_in; // timecode at mark in
439 uint32_t timecode_out; // timecode at mark out
440
441 ff_parse_creation_time_metadata(s, &timestamp, 1);
442
443 timecode_in = GXF_TIMECODE(gxf->tc.color, gxf->tc.drop,
444 gxf->tc.hh, gxf->tc.mm,
445 gxf->tc.ss, gxf->tc.ff);
446
447 nb_fields = gxf->nb_fields +
448 gxf->tc.hh * (timecode_base * 3600) +
449 gxf->tc.mm * (timecode_base * 60) +
450 gxf->tc.ss * timecode_base +
451 gxf->tc.ff;
452
453 timecode_out = GXF_TIMECODE(gxf->tc.color, gxf->tc.drop,
454 nb_fields / (timecode_base * 3600) % 24,
455 nb_fields / (timecode_base * 60) % 60,
456 nb_fields / timecode_base % 60,
457 nb_fields % timecode_base);
458
459 avio_wl32(pb, gxf->flags);
460 avio_wl32(pb, gxf->nb_fields); /* length of the longest track */
461 avio_wl32(pb, gxf->nb_fields); /* length of the shortest track */
462 avio_wl32(pb, 0); /* mark in */
463 avio_wl32(pb, gxf->nb_fields); /* mark out */
464 avio_wl32(pb, timecode_in); /* timecode mark in */
465 avio_wl32(pb, timecode_out); /* timecode mark out */
466 avio_wl64(pb, timestamp); /* modification time */
467 avio_wl64(pb, timestamp); /* creation time */
468 avio_wl16(pb, 0); /* reserved */
469 avio_wl16(pb, 0); /* reserved */
470 avio_wl16(pb, gxf->audio_tracks);
471 avio_wl16(pb, 1); /* timecode track count */
472 avio_wl16(pb, 0); /* reserved */
473 avio_wl16(pb, gxf->mpeg_tracks);
474 return 48;
475}
476
478{
479 GXFContext *gxf = s->priv_data;
480 AVIOContext *pb = s->pb;
481
482 avio_wl32(pb, gxf->umf_length); /* total length of the umf data */
483 avio_wl32(pb, 3); /* version */
484 avio_wl32(pb, s->nb_streams+1);
485 avio_wl32(pb, gxf->umf_track_offset); /* umf track section offset */
486 avio_wl32(pb, gxf->umf_track_size);
487 avio_wl32(pb, s->nb_streams+1);
488 avio_wl32(pb, gxf->umf_media_offset);
489 avio_wl32(pb, gxf->umf_media_size);
490 avio_wl32(pb, gxf->umf_length); /* user data offset */
491 avio_wl32(pb, 0); /* user data size */
492 avio_wl32(pb, 0); /* reserved */
493 avio_wl32(pb, 0); /* reserved */
494 return 48;
495}
496
498{
499 AVIOContext *pb = s->pb;
500 GXFContext *gxf = s->priv_data;
501 int64_t pos = avio_tell(pb);
502 int i;
503
505 for (i = 0; i < s->nb_streams; ++i) {
506 GXFStreamContext *sc = s->streams[i]->priv_data;
507 avio_wl16(pb, sc->media_info);
508 avio_wl16(pb, 1);
509 }
510
512 avio_wl16(pb, 1);
513
514 return avio_tell(pb) - pos;
515}
516
518{
519 GXFStreamContext *sc = st->priv_data;
520
522 avio_wl32(pb, 2);
523 else
524 avio_wl32(pb, 1); /* default to 420 */
525 avio_wl32(pb, sc->first_gop_closed == 1); /* closed = 1, open = 0, unknown = 255 */
526 avio_wl32(pb, 3); /* top = 1, bottom = 2, frame = 3, unknown = 0 */
527 avio_wl32(pb, 1); /* I picture per GOP */
528 avio_wl32(pb, sc->p_per_gop);
529 avio_wl32(pb, sc->b_per_i_or_p);
531 avio_wl32(pb, 2);
533 avio_wl32(pb, 1);
534 else
535 avio_wl32(pb, 0);
536 avio_wl32(pb, 0); /* reserved */
537 return 32;
538}
539
541{
542 avio_wl32(pb, drop); /* drop frame */
543 ffio_fill(pb, 0, 7 * 4); /* reserved */
544 return 32;
545}
546
548{
549 int dv_umf_data = 0;
550
552 dv_umf_data |= 0x20; /* marks as DVCAM instead of DVPRO */
553 avio_wl32(pb, dv_umf_data);
554 ffio_fill(pb, 0, 7 * 4);
555 return 32;
556}
557
559{
560 avio_wl64(pb, av_double2int(1)); /* sound level to begin to */
561 avio_wl64(pb, av_double2int(1)); /* sound level to begin to */
562 avio_wl32(pb, 0); /* number of fields over which to ramp up sound level */
563 avio_wl32(pb, 0); /* number of fields over which to ramp down sound level */
564 avio_wl32(pb, 0); /* reserved */
565 avio_wl32(pb, 0); /* reserved */
566 return 32;
567}
568
570{
571 GXFContext *gxf = s->priv_data;
572 AVIOContext *pb = s->pb;
573 int64_t pos;
574
575 pos = avio_tell(pb);
577 for (unsigned i = 0; i <= s->nb_streams; ++i) {
579 int64_t startpos, curpos;
580
581 if (i == s->nb_streams)
582 sc = &gxf->timecode_track;
583 else
584 sc = s->streams[i]->priv_data;
585
586 startpos = avio_tell(pb);
587 avio_wl16(pb, 0); /* length */
588 avio_wl16(pb, sc->media_info);
589 avio_wl16(pb, 0); /* reserved */
590 avio_wl16(pb, 0); /* reserved */
591 avio_wl32(pb, gxf->nb_fields);
592 avio_wl32(pb, 0); /* attributes rw, ro */
593 avio_wl32(pb, 0); /* mark in */
594 avio_wl32(pb, gxf->nb_fields); /* mark out */
596 avio_wb16(pb, sc->media_info);
597 ffio_fill(pb, 0, 88 - (strlen(ES_NAME_PATTERN) + 2));
598 avio_wl32(pb, sc->track_type);
599 avio_wl32(pb, sc->sample_rate);
600 avio_wl32(pb, sc->sample_size);
601 avio_wl32(pb, 0); /* reserved */
602
603 if (sc == &gxf->timecode_track)
605 else {
606 AVStream *st = s->streams[i];
607 switch (st->codecpar->codec_id) {
611 break;
614 break;
616 gxf_write_umf_media_dv(pb, sc, st);
617 break;
618 }
619 }
620
621 curpos = avio_tell(pb);
622 avio_seek(pb, startpos, SEEK_SET);
623 avio_wl16(pb, curpos - startpos);
624 avio_seek(pb, curpos, SEEK_SET);
625 }
626 return avio_tell(pb) - pos;
627}
628
630{
631 GXFContext *gxf = s->priv_data;
632 AVIOContext *pb = s->pb;
633 int64_t pos = avio_tell(pb);
634
636
637 /* preamble */
638 avio_w8(pb, 3); /* first and last (only) packet */
639 avio_wb32(pb, gxf->umf_length); /* data length */
640
641 gxf->umf_start_offset = avio_tell(pb);
646 gxf->umf_length = avio_tell(pb) - gxf->umf_start_offset;
647 return update_packet_size(pb, pos);
648}
649
651{
652 if (!vsc)
653 return;
654
655 sc->media_type = vsc->sample_rate == 60 ? 7 : 8;
656 sc->sample_rate = vsc->sample_rate;
657 sc->media_info = ('T'<<8) | '0';
658 sc->track_type = 3;
660 sc->lines_index = vsc->lines_index;
661 sc->sample_size = 16;
662 sc->fields = vsc->fields;
663}
664
665static int gxf_init_timecode(AVFormatContext *s, GXFTimecode *tc, const char *tcstr, int fields)
666{
667 char c;
668
669 if (sscanf(tcstr, "%d:%d:%d%c%d", &tc->hh, &tc->mm, &tc->ss, &c, &tc->ff) != 5) {
670 av_log(s, AV_LOG_ERROR, "unable to parse timecode, "
671 "syntax: hh:mm:ss[:;.]ff\n");
672 return AVERROR(EINVAL);
673 }
674
675 if (tc->hh > 31U || tc->mm > 255U || tc->ss > 255U || tc->ff > (255U >> (fields == 2)))
676 return AVERROR(EINVAL);
677
678 tc->color = 0;
679 tc->drop = c != ':';
680
681 if (fields == 2)
682 tc->ff = tc->ff * 2;
683
684 return 0;
685}
686
688{
689 AVIOContext *pb = s->pb;
690 GXFContext *gxf = s->priv_data;
691 GXFStreamContext *vsc = NULL;
692 uint8_t tracks[255] = {0};
693 int i, media_info = 0;
694 int ret;
695 AVDictionaryEntry *tcr = av_dict_get(s->metadata, "timecode", NULL, 0);
696
697 if (!(pb->seekable & AVIO_SEEKABLE_NORMAL)) {
698 av_log(s, AV_LOG_ERROR, "gxf muxer does not support streamed output, patch welcome\n");
700 }
701
702 gxf->flags |= 0x00080000; /* material is simple clip */
703 for (i = 0; i < s->nb_streams; ++i) {
704 AVStream *st = s->streams[i];
705 GXFStreamContext *sc = av_mallocz(sizeof(*sc));
706 if (!sc)
707 return AVERROR(ENOMEM);
708 st->priv_data = sc;
709
713 av_log(s, AV_LOG_ERROR, "only 16 BIT PCM LE allowed for now\n");
714 return AVERROR(EINVAL);
715 }
716 if (st->codecpar->sample_rate != 48000) {
717 av_log(s, AV_LOG_ERROR, "only 48000hz sampling rate is allowed\n");
718 return AVERROR(EINVAL);
719 }
720 if (st->codecpar->ch_layout.nb_channels != 1) {
721 av_log(s, AV_LOG_ERROR, "only mono tracks are allowed\n");
722 return AVERROR(EINVAL);
723 }
725 if (ret < 0)
726 return ret;
727 sc->track_type = 2;
729 avpriv_set_pts_info(st, 64, 1, sc->sample_rate);
730 sc->sample_size = 16;
731 sc->frame_rate_index = -2;
732 sc->lines_index = -2;
733 sc->fields = -2;
734 gxf->audio_tracks++;
735 gxf->flags |= 0x04000000; /* audio is 16 bit pcm */
736 media_info = 'A';
737 } else if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
738 if (i != 0) {
739 av_log(s, AV_LOG_ERROR, "video stream must be the first track\n");
740 return AVERROR(EINVAL);
741 }
742 /* FIXME check from time_base ? */
743 if (st->codecpar->height == 480 || st->codecpar->height == 512) { /* NTSC or NTSC+VBI */
744 sc->frame_rate_index = 5;
745 sc->sample_rate = 60;
746 gxf->flags |= 0x00000080;
747 gxf->time_base = (AVRational){ 1001, 60000 };
748 } else if (st->codecpar->height == 576 || st->codecpar->height == 608) { /* PAL or PAL+VBI */
749 sc->frame_rate_index = 6;
750 sc->media_type++;
751 sc->sample_rate = 50;
752 gxf->flags |= 0x00000040;
753 gxf->time_base = (AVRational){ 1, 50 };
754 } else {
755 av_log(s, AV_LOG_ERROR, "unsupported video resolution, "
756 "gxf muxer only accepts PAL or NTSC resolutions currently\n");
757 return AVERROR(EINVAL);
758 }
759 if (!tcr)
760 tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
761 avpriv_set_pts_info(st, 64, gxf->time_base.num, gxf->time_base.den);
762 if (gxf_find_lines_index(st) < 0)
763 sc->lines_index = -1;
764 sc->sample_size = st->codecpar->bit_rate;
765 sc->fields = 2; /* interlaced */
766
767 vsc = sc;
768
769 switch (st->codecpar->codec_id) {
771 sc->track_type = 1;
772 gxf->flags |= 0x00004000;
773 media_info = 'J';
774 break;
776 sc->track_type = 9;
777 gxf->mpeg_tracks++;
778 media_info = 'L';
779 break;
781 sc->first_gop_closed = -1;
782 sc->track_type = 4;
783 gxf->mpeg_tracks++;
784 gxf->flags |= 0x00008000;
785 media_info = 'M';
786 break;
788 if (st->codecpar->format == AV_PIX_FMT_YUV422P) {
789 sc->media_type += 2;
790 sc->track_type = 6;
791 gxf->flags |= 0x00002000;
792 media_info = 'E';
793 } else {
794 sc->track_type = 5;
795 gxf->flags |= 0x00001000;
796 media_info = 'D';
797 }
798 break;
799 default:
800 av_log(s, AV_LOG_ERROR, "video codec not supported\n");
801 return -1;
802 }
803 }
804 /* FIXME first 10 audio tracks are 0 to 9 next 22 are A to V */
805 sc->media_info = media_info<<8 | ('0'+tracks[media_info]++);
806 sc->order = s->nb_streams - st->index;
807 }
808
809 if (tcr && vsc) {
810 ret = gxf_init_timecode(s, &gxf->tc, tcr->value, vsc->fields);
811 if (ret < 0)
812 return ret;
813 }
814
816 gxf->flags |= 0x200000; // time code track is non-drop frame
817
818 if ((ret = gxf_write_map_packet(s, 0)) < 0)
819 return ret;
822
823 gxf->packet_count = 3;
824
825 return 0;
826}
827
829{
830 int64_t pos = avio_tell(pb);
831
833 return update_packet_size(pb, pos);
834}
835
837{
838 GXFContext *gxf = s->priv_data;
839 AVIOContext *pb = s->pb;
840 int64_t end;
841 int i;
842 int ret;
843
845 end = avio_tell(pb);
846 avio_seek(pb, 0, SEEK_SET);
847 /* overwrite map, flt and umf packets with new values */
848 if ((ret = gxf_write_map_packet(s, 1)) < 0)
849 return ret;
852 /* update duration in all map packets */
853 for (i = 1; i < gxf->map_offsets_nb; i++) {
854 avio_seek(pb, gxf->map_offsets[i], SEEK_SET);
855 if ((ret = gxf_write_map_packet(s, 1)) < 0)
856 return ret;
857 }
858
859 avio_seek(pb, end, SEEK_SET);
860
861 return 0;
862}
863
865{
866 GXFContext *gxf = s->priv_data;
867
868 av_freep(&gxf->flt_entries);
869 av_freep(&gxf->map_offsets);
870}
871
872static int gxf_parse_mpeg_frame(GXFStreamContext *sc, const uint8_t *buf, int size)
873{
874 uint32_t c=-1;
875 int i;
876 for(i=0; i<size-4 && c!=0x100; i++){
877 c = (c<<8) + buf[i];
878 if(c == 0x1B8 && sc->first_gop_closed == -1) /* GOP start code */
879 sc->first_gop_closed= (buf[i+4]>>6)&1;
880 }
881 return (buf[i+1]>>3)&7;
882}
883
885{
886 GXFContext *gxf = s->priv_data;
887 AVIOContext *pb = s->pb;
888 AVStream *st = s->streams[pkt->stream_index];
889 GXFStreamContext *sc = st->priv_data;
890 unsigned field_nb;
891 /* If the video is frame-encoded, the frame numbers shall be represented by
892 * even field numbers.
893 * see SMPTE360M-2004 6.4.2.1.3 Media field number */
895 field_nb = gxf->nb_fields;
896 } else {
897 field_nb = av_rescale_rnd(pkt->dts, gxf->time_base.den,
898 (int64_t)48000*gxf->time_base.num, AV_ROUND_UP);
899 }
900
901 avio_w8(pb, sc->media_type);
902 avio_w8(pb, st->index);
903 avio_wb32(pb, field_nb);
905 avio_wb16(pb, 0);
906 avio_wb16(pb, size / 2);
907 } else if (st->codecpar->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
908 int frame_type = gxf_parse_mpeg_frame(sc, pkt->data, pkt->size);
910 avio_w8(pb, 0x0d);
911 sc->iframes++;
912 } else if (frame_type == AV_PICTURE_TYPE_B) {
913 avio_w8(pb, 0x0f);
914 sc->bframes++;
915 } else {
916 avio_w8(pb, 0x0e);
917 sc->pframes++;
918 }
919 avio_wb24(pb, size);
920 } else if (st->codecpar->codec_id == AV_CODEC_ID_DVVIDEO) {
921 avio_w8(pb, size / 4096);
922 avio_wb24(pb, 0);
923 } else
924 avio_wb32(pb, size);
925 avio_wb32(pb, field_nb);
926 avio_w8(pb, 1); /* flags */
927 avio_w8(pb, 0); /* reserved */
928 return 16;
929}
930
932{
933 GXFContext *gxf = s->priv_data;
934 AVIOContext *pb = s->pb;
935 AVStream *st = s->streams[pkt->stream_index];
936 int64_t pos = avio_tell(pb);
937 int padding = 0;
938 unsigned packet_start_offset = avio_tell(pb) / 1024;
939 int ret;
940
942 if (st->codecpar->codec_id == AV_CODEC_ID_MPEG2VIDEO && pkt->size % 4) /* MPEG-2 frames must be padded */
943 padding = 4 - pkt->size % 4;
944 else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
945 padding = GXF_AUDIO_PACKET_SIZE - pkt->size;
946 gxf_write_media_preamble(s, pkt, pkt->size + padding);
947 avio_write(pb, pkt->data, pkt->size);
948 gxf_write_padding(pb, padding);
949
951 if (!(gxf->flt_entries_nb % 500)) {
952 int err;
953 if ((err = av_reallocp_array(&gxf->flt_entries,
954 gxf->flt_entries_nb + 500,
955 sizeof(*gxf->flt_entries))) < 0) {
956 gxf->flt_entries_nb = 0;
957 gxf->nb_fields = 0;
958 av_log(s, AV_LOG_ERROR, "could not reallocate flt entries\n");
959 return err;
960 }
961 }
962 gxf->flt_entries[gxf->flt_entries_nb++] = packet_start_offset;
963 gxf->nb_fields += 2; // count fields
964 }
965
967
968 gxf->packet_count++;
969 if (gxf->packet_count == 100) {
970 if ((ret = gxf_write_map_packet(s, 0)) < 0)
971 return ret;
972 gxf->packet_count = 0;
973 }
974
975 return 0;
976}
977
979 const AVPacket *cur)
980{
981 GXFContext *gxf = s->priv_data;
982 const AVPacket *pkt[2] = { cur, next };
983 int i, field_nb[2];
984 GXFStreamContext *sc[2];
985
986 for (i = 0; i < 2; i++) {
987 AVStream *st = s->streams[pkt[i]->stream_index];
988 sc[i] = st->priv_data;
990 field_nb[i] = av_rescale_rnd(pkt[i]->dts, gxf->time_base.den,
991 (int64_t)48000*gxf->time_base.num, AV_ROUND_UP);
992 field_nb[i] &= ~1; // compare against even field number because audio must be before video
993 } else
994 field_nb[i] = pkt[i]->dts; // dts are field based
995 }
996
997 return field_nb[1] > field_nb[0] ||
998 (field_nb[1] == field_nb[0] && sc[1]->order > sc[0]->order);
999}
1000
1002 int flush, int has_packet)
1003{
1004 int ret;
1005 if (has_packet) {
1006 AVStream *st = s->streams[pkt->stream_index];
1007 GXFStreamContext *sc = st->priv_data;
1009 pkt->pts = pkt->dts = sc->pkt_cnt * 2; // enforce 2 fields
1010 else
1011 pkt->pts = pkt->dts = sc->pkt_cnt * GXF_SAMPLES_PER_FRAME;
1012 sc->pkt_cnt++;
1014 return ret;
1015 }
1017}
1018
1020 .p.name = "gxf",
1021 .p.long_name = NULL_IF_CONFIG_SMALL("GXF (General eXchange Format)"),
1022 .p.extensions = "gxf",
1023 .priv_data_size = sizeof(GXFContext),
1024 .p.audio_codec = AV_CODEC_ID_PCM_S16LE,
1025 .p.video_codec = AV_CODEC_ID_MPEG2VIDEO,
1026 .write_header = gxf_write_header,
1027 .write_packet = gxf_write_packet,
1028 .write_trailer = gxf_write_trailer,
1029 .deinit = gxf_deinit,
1030 .interleave_packet = gxf_interleave_packet,
1031};
const FFOutputFormat ff_gxf_muxer
Definition gxfenc.c:1019
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition avformat.c:834
Main libavformat public API header.
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition aviobuf.c:236
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition avio.h:41
void avio_wl64(AVIOContext *s, uint64_t val)
Definition aviobuf.c:428
void avio_wl32(AVIOContext *s, unsigned int val)
Definition aviobuf.c:360
void avio_wl16(AVIOContext *s, unsigned int val)
Definition aviobuf.c:440
void avio_w8(AVIOContext *s, int b)
Definition aviobuf.c:184
void avio_wb32(AVIOContext *s, unsigned int val)
Definition aviobuf.c:368
void avio_wb16(AVIOContext *s, unsigned int val)
Definition aviobuf.c:446
int64_t avio_size(AVIOContext *s)
Get the filesize.
Definition aviobuf.c:326
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition avio.h:494
void avio_wb24(AVIOContext *s, unsigned int val)
Definition aviobuf.c:458
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition aviobuf.c:206
void ffio_fill(AVIOContext *s, int b, int64_t count)
Definition aviobuf.c:192
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
static AVPacket * pkt
void(* flush)(AVBSFContext *ctx)
Definition dts2pts.c:610
@ AV_CODEC_ID_PCM_S16LE
Definition codec_id.h:330
@ AV_CODEC_ID_NONE
Definition codec_id.h:48
@ AV_CODEC_ID_PCM_S24LE
Definition codec_id.h:342
@ AV_CODEC_ID_DVVIDEO
Definition codec_id.h:74
@ AV_CODEC_ID_AC3
Definition codec_id.h:456
@ AV_CODEC_ID_MJPEG
Definition codec_id.h:57
@ AV_CODEC_ID_MPEG1VIDEO
Definition codec_id.h:51
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
Definition codec_id.h:52
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition dict.c:60
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition error.h:64
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd)
Rescale a 64-bit integer with specified rounding.
Definition mathematics.c:58
@ AV_ROUND_UP
Round toward +infinity.
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate an array through a pointer to a pointer.
Definition mem.c:225
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
@ AV_PICTURE_TYPE_I
Intra.
Definition avutil.h:278
@ AV_PICTURE_TYPE_B
Bi-dir predicted.
Definition avutil.h:280
#define AV_STRINGIFY(s)
Definition macros.h:66
GXFPktType
Definition gxf.h:25
@ PKT_UMF
Definition gxf.h:30
@ PKT_MAP
Definition gxf.h:26
@ PKT_MEDIA
Definition gxf.h:27
@ PKT_EOS
Definition gxf.h:28
@ PKT_FLT
Definition gxf.h:29
@ TRACK_MPG_AUX
Definition gxf.h:46
@ TRACK_VER
Definition gxf.h:45
@ TRACK_AUX
Definition gxf.h:44
@ TRACK_FPF
Definition gxf.h:49
@ TRACK_LINES
Definition gxf.h:48
@ TRACK_FPS
Definition gxf.h:47
@ TRACK_NAME
Definition gxf.h:43
@ MAT_NAME
Definition gxf.h:34
@ MAT_LAST_FIELD
Definition gxf.h:36
@ MAT_MARK_IN
Definition gxf.h:37
@ MAT_FIRST_FIELD
Definition gxf.h:35
@ MAT_MARK_OUT
Definition gxf.h:38
static int gxf_interleave_packet(AVFormatContext *s, AVPacket *pkt, int flush, int has_packet)
Definition gxfenc.c:1001
#define GXF_SAMPLES_PER_FRAME
Definition gxfenc.c:32
static int gxf_write_eos_packet(AVIOContext *pb)
Definition gxfenc.c:828
static void gxf_deinit(AVFormatContext *s)
Definition gxfenc.c:864
static int gxf_write_header(AVFormatContext *s)
Definition gxfenc.c:687
static const AVCodecTag gxf_media_types[]
Definition gxfenc.c:100
static int gxf_init_timecode(AVFormatContext *s, GXFTimecode *tc, const char *tcstr, int fields)
Definition gxfenc.c:665
static int gxf_write_flt_packet(AVFormatContext *s)
Definition gxfenc.c:407
static int gxf_write_mpeg_auxiliary(AVIOContext *pb, AVStream *st)
Definition gxfenc.c:180
static int gxf_write_map_packet(AVFormatContext *s, int rewrite)
Definition gxfenc.c:375
static int gxf_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition gxfenc.c:931
#define GXF_AUDIO_PACKET_SIZE
Definition gxfenc.c:33
static int gxf_write_umf_media_description(AVFormatContext *s)
Definition gxfenc.c:569
static int gxf_write_umf_media_timecode(AVIOContext *pb, int drop)
Definition gxfenc.c:540
static const struct @245204121255110231221056270036157303047216147250 gxf_lines_tab[]
static int gxf_write_track_description_section(AVFormatContext *s)
Definition gxfenc.c:358
#define SERVER_PATH
Definition gxfenc.c:119
static int gxf_write_umf_packet(AVFormatContext *s)
Definition gxfenc.c:629
static int gxf_write_media_preamble(AVFormatContext *s, AVPacket *pkt, int size)
Definition gxfenc.c:884
static int gxf_write_material_data_section(AVFormatContext *s)
Definition gxfenc.c:307
#define ES_NAME_PATTERN
Definition gxfenc.c:120
static void gxf_init_timecode_track(GXFStreamContext *sc, GXFStreamContext *vsc)
Definition gxfenc.c:650
static int64_t update_size(AVIOContext *pb, int64_t pos)
Definition gxfenc.c:158
int index
Definition gxfenc.c:90
static int gxf_write_umf_payload(AVFormatContext *s)
Definition gxfenc.c:477
static int gxf_write_track_description(AVFormatContext *s, GXFStreamContext *sc, int index)
Definition gxfenc.c:246
#define GXF_TIMECODE(c, d, h, m, s, f)
Definition gxfenc.c:35
static int gxf_write_dv_auxiliary(AVIOContext *pb, AVStream *st)
Definition gxfenc.c:219
static int gxf_find_lines_index(AVStream *st)
Definition gxfenc.c:122
static int gxf_write_umf_track_description(AVFormatContext *s)
Definition gxfenc.c:497
static void gxf_write_packet_header(AVIOContext *pb, GXFPktType type)
Definition gxfenc.c:169
static int gxf_compare_field_nb(AVFormatContext *s, const AVPacket *next, const AVPacket *cur)
Definition gxfenc.c:978
static int64_t update_packet_size(AVIOContext *pb, int64_t pos)
Definition gxfenc.c:141
static int gxf_write_umf_material_description(AVFormatContext *s)
Definition gxfenc.c:431
static void gxf_write_padding(AVIOContext *pb, int64_t to_pad)
Definition gxfenc.c:136
static int gxf_write_umf_media_mpeg(AVIOContext *pb, AVStream *st)
Definition gxfenc.c:517
static int gxf_write_umf_media_dv(AVIOContext *pb, GXFStreamContext *sc, AVStream *st)
Definition gxfenc.c:547
static int gxf_write_umf_media_audio(AVIOContext *pb, GXFStreamContext *sc)
Definition gxfenc.c:558
static int gxf_parse_mpeg_frame(GXFStreamContext *sc, const uint8_t *buf, int size)
Definition gxfenc.c:872
static int gxf_write_timecode_auxiliary(AVIOContext *pb, GXFContext *gxf)
Definition gxfenc.c:232
static int gxf_write_trailer(AVFormatContext *s)
Definition gxfenc.c:836
#define MAT_SIZE
Definition hq_hqadata.h:113
cl_device_type type
static av_always_inline uint64_t av_double2int(double f)
Reinterpret a double as a 64-bit integer.
Definition intfloat.h:70
frame_type
unsigned int ff_codec_get_tag(const AVCodecTag *tags, enum AVCodecID id)
Definition utils.c:133
int ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt, int(*compare)(AVFormatContext *, const AVPacket *, const AVPacket *))
Add packet to an AVFormatContext's packet_buffer list, determining its interleaved position using com...
Definition mux.c:835
int ff_stream_add_bitstream_filter(AVStream *st, const char *name, const char *args)
Add a bitstream filter to a stream.
Definition mux.c:1294
int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *pkt, int flush, int has_packet)
Interleave an AVPacket per dts so it can be muxed.
Definition mux.c:939
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
Memory handling functions.
int ff_parse_creation_time_metadata(AVFormatContext *s, int64_t *timestamp, int return_seconds)
Parse creation_time in AVFormatContext metadata if exists and warn if the parsing fails.
Definition mux_utils.c:137
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition pixfmt.h:73
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition pixfmt.h:77
#define snprintf
Definition snprintf.h:34
unsigned int pos
Definition spdifenc.c:431
int nb_channels
Number of channels in this layout.
Describe the class of an AVClass context structure.
Definition log.h:76
int height
The height of the video frame in pixels.
Definition codec_par.h:150
AVChannelLayout ch_layout
The channel layout and number of channels.
Definition codec_par.h:207
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition codec_par.h:99
enum AVMediaType codec_type
General type of the encoded data.
Definition codec_par.h:53
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition codec_par.h:57
int sample_rate
The number of audio samples per second.
Definition codec_par.h:213
char * value
Definition dict.h:92
Format I/O context.
Definition avformat.h:1333
Bytestream IO Context.
Definition avio.h:160
int seekable
A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
Definition avio.h:261
This structure stores compressed data.
Definition packet.h:580
Rational number (pair of numerator and denominator).
Definition rational.h:58
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
Stream structure.
Definition avformat.h:766
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:789
AVDictionary * metadata
Definition avformat.h:846
void * priv_data
Definition avformat.h:791
int index
stream index in AVFormatContext
Definition avformat.h:772
uint16_t umf_media_size
Definition gxfenc.c:77
AVRational time_base
Definition gxfenc.c:78
unsigned map_offsets_nb
Definition gxfenc.c:84
uint16_t umf_track_size
Definition gxfenc.c:76
uint32_t umf_track_offset
Definition gxfenc.c:73
uint16_t mpeg_tracks
Definition gxfenc.c:70
uint32_t nb_fields
Definition gxfenc.c:68
GXFTimecode tc
Definition gxfenc.c:86
uint16_t audio_tracks
Definition gxfenc.c:69
uint32_t umf_media_offset
Definition gxfenc.c:74
uint32_t umf_length
Definition gxfenc.c:75
unsigned * flt_entries
offsets of packets /1024, starts after 2nd video field
Definition gxfenc.c:81
AVClass * av_class
Definition gxfenc.c:67
GXFStreamContext timecode_track
Definition gxfenc.c:80
int64_t creation_time
Definition gxfenc.c:71
uint64_t * map_offsets
offset of map packets
Definition gxfenc.c:83
uint32_t umf_start_offset
Definition gxfenc.c:72
unsigned packet_count
Definition gxfenc.c:85
int flags
Definition gxfenc.c:79
unsigned flt_entries_nb
Definition gxfenc.c:82
int64_t pkt_cnt
Definition gxfenc.c:48
int frame_rate_index
Definition gxfenc.c:54
int first_gop_closed
Definition gxfenc.c:62
uint16_t media_info
Definition gxfenc.c:53
uint32_t track_type
Definition gxfenc.c:49
unsigned order
interleaving order
Definition gxfenc.c:63
uint16_t media_type
Definition gxfenc.c:52
uint32_t sample_size
Definition gxfenc.c:50
uint32_t sample_rate
Definition gxfenc.c:51
int b_per_i_or_p
number of B-frames per I-frame or P-frame
Definition gxfenc.c:61
int drop
Definition gxfenc.c:44
int color
Definition gxfenc.c:43
#define av_mallocz(s)
#define av_freep(p)
#define av_log(a,...)
static char buffer[20]
Definition seek.c:32
#define height
Definition dsp.h:89
int size
int len
static double c[64]