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
31
32 #define GXF_AUDIO_PACKET_SIZE 65536
33
34 #define GXF_TIMECODE(c, d, h, m, s, f) \
35 ((c) << 30 | (d) << 29 | (h) << 24 | (m) << 16 | (s) << 8 | (f))
36
45
62 unsigned order;
///< interleaving order
64
80 unsigned *
flt_entries;
///< offsets of packets /1024, starts after 2nd video field
87
88 static const struct {
91 { 480, 1 }, /* NTSC */
92 { 512, 1 }, /* NTSC + VBI */
93 { 576, 2 }, /* PAL */
94 { 608, 2 }, /* PAL + VBI */
95 { 1080, 4 },
96 { 720, 6 },
97 };
98
111 //{ AV_CODEC_ID_NONE, , 18 }, /* Non compressed 24 bit audio */
116 };
117
118 #define SERVER_PATH "EXT:/PDR/default/"
119 #define ES_NAME_PATTERN "EXT:/PDR/default/ES."
120
122 {
124 int i;
125
126 for (i = 0; i < 6; ++i) {
129 return 0;
130 }
131 }
132 return -1;
133 }
134
136 {
137 for (; to_pad > 0; to_pad--) {
139 }
140 }
141
143 {
144 int64_t curpos;
146
148 if (size % 4) {
151 }
156 return curpos - pos;
157 }
158
160 {
161 int64_t curpos;
162
167 return curpos - pos;
168 }
169
171 {
172 avio_wb32(pb, 0);
/* packet leader for synchro */
174 avio_w8(pb, type);
/* map packet */
177 avio_w8(pb, 0xE1);
/* trailer 1 */
178 avio_w8(pb, 0xE2);
/* trailer 2 */
179 }
180
182 {
185 int size, starting_line;
186
195 }
197 sc->
p_per_gop = 9;
/* ensure value won't take more than one char */
199 sc->
b_per_i_or_p = 9;
/* ensure value won't take more than one char */
200 }
202 starting_line = 7; // VBI
204 starting_line = 20;
205 else
206 starting_line = 23; // default PAL
207
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",
217 return size + 3;
218 }
219
221 {
222 int64_t track_aux_data = 0;
223
227 track_aux_data |= 0x01; /* marks stream as DVCAM instead of DVPRO */
228 track_aux_data |= 0x40000000; /* aux data is valid */
230 return 8;
231 }
232
234 {
238
242 /* reserved */
244 return 8;
245 }
246
248 {
251 int64_t pos;
252
253 /* track description section */
256
259
260 /* media file name */
266
268 case 3: /* timecode */
270 break;
271 case 4: /* MPEG2 */
272 case 9: /* MPEG1 */
274 break;
275 case 5: /* DV25 */
276 case 6: /* DV50 */
278 break;
279 default:
283 }
284
285 /* file system version */
289
290 /* frame rate */
294
295 /* lines per frame */
299
300 /* fields per frame */
304
306 }
307
309 {
312 int64_t pos;
314 const char *filename = strrchr(s->
filename,
'/');
315
318
319 /* name */
320 if (filename)
321 filename++;
322 else
324 len = strlen(filename);
325
331
332 /* first field */
336
337 /* last field */
341
342 /* reserved */
346
350
351 /* estimated size */
355
357 }
358
360 {
363 int64_t pos;
364 int i;
365
370
372
374 }
375
377 {
381
382 if (!rewrite) {
384 int err;
390 return err;
391 }
392 }
394 }
395
397
398 /* preamble */
399 avio_w8(pb, 0xE0);
/* version */
400 avio_w8(pb, 0xFF);
/* reserved */
401
404
406 }
407
409 {
413 int fields_per_flt = (gxf->
nb_fields+1) / 1000 + 1;
414 int flt_entries = gxf->
nb_fields / fields_per_flt;
415 int i = 0;
416
418
419 avio_wl32(pb, fields_per_flt);
/* number of fields */
420 avio_wl32(pb, flt_entries);
/* number of active flt entries */
421
423 for (i = 0; i < flt_entries; i++)
425 }
426
427 for (; i < 1000; i++)
429
431 }
432
434 {
437 int timecode_base = gxf->
time_base.
den == 60000 ? 60 : 50;
438 int64_t timestamp = 0;
439 uint64_t nb_fields;
440 uint32_t timecode_in; // timecode at mark in
441 uint32_t timecode_out; // timecode at mark out
442
444
448
450 gxf->
tc.
hh * (timecode_base * 3600) +
451 gxf->
tc.
mm * (timecode_base * 60) +
452 gxf->
tc.
ss * timecode_base +
454
456 nb_fields / (timecode_base * 3600) % 24,
457 nb_fields / (timecode_base * 60) % 60,
458 nb_fields / timecode_base % 60,
459 nb_fields % timecode_base);
460
466 avio_wl32(pb, timecode_in);
/* timecode mark in */
467 avio_wl32(pb, timecode_out);
/* timecode mark out */
468 avio_wl64(pb, timestamp);
/* modification time */
469 avio_wl64(pb, timestamp);
/* creation time */
473 avio_wl16(pb, 1);
/* timecode track count */
476 return 48;
477 }
478
480 {
483
496 return 48;
497 }
498
500 {
504 int i;
505
511 }
512
515
517 }
518
520 {
522
525 else
528 avio_wl32(pb, 3);
/* top = 1, bottom = 2, frame = 3, unknown = 0 */
529 avio_wl32(pb, 1);
/* I picture per GOP */
536 else
539 return 32;
540 }
541
543 {
552 return 32;
553 }
554
556 {
557 int dv_umf_data = 0;
558
560 dv_umf_data |= 0x20; /* marks as DVCAM instead of DVPRO */
569 return 32;
570 }
571
573 {
576 avio_wl32(pb, 0);
/* number of fields over which to ramp up sound level */
577 avio_wl32(pb, 0);
/* number of fields over which to ramp down sound level */
580 return 32;
581 }
582
584 {
587 int64_t pos;
588 int i, j;
589
594 int64_t startpos, curpos;
595
598 else
600
607 avio_wl32(pb, 0);
/* attributes rw, ro */
618
621 else {
627 break;
630 break;
633 break;
634 }
635 }
636
641 }
643 }
644
646 {
650
652
653 /* preamble */
654 avio_w8(pb, 3);
/* first and last (only) packet */
656
664 }
665
667
669 {
670 if (!vsc)
671 return;
672
681 }
682
684 {
686
687 if (sscanf(tcstr,
"%d:%d:%d%c%d", &tc->
hh, &tc->
mm, &tc->
ss, &c, &tc->
ff) != 5) {
689 "syntax: hh:mm:ss[:;.]ff\n");
690 return -1;
691 }
692
695
696 if (fields == 2)
698
699 return 0;
700 }
701
703 {
708 int i, media_info = 0;
709 int ret;
711
713 av_log(s,
AV_LOG_ERROR,
"gxf muxer does not support streamed output, patch welcome\n");
714 return -1;
715 }
716
717 gxf->
flags |= 0x00080000;
/* material is simple clip */
721 if (!sc)
724
729 return -1;
730 }
733 return -1;
734 }
737 return -1;
738 }
747 gxf->
flags |= 0x04000000;
/* audio is 16 bit pcm */
748 media_info = 'A';
750 if (i != 0) {
752 return -1;
753 }
754 /* FIXME check from time_base ? */
758 gxf->
flags |= 0x00000080;
764 gxf->
flags |= 0x00000040;
766 } else {
768 "gxf muxer only accepts PAL or NTSC resolutions currently\n");
769 return -1;
770 }
771 if (!tcr)
777 sc->
fields = 2;
/* interlaced */
778
779 vsc = sc;
780
784 gxf->
flags |= 0x00004000;
785 media_info = 'J';
786 break;
790 media_info = 'L';
791 break;
796 gxf->
flags |= 0x00008000;
797 media_info = 'M';
798 break;
803 gxf->
flags |= 0x00002000;
804 media_info = 'E';
805 } else {
807 gxf->
flags |= 0x00001000;
808 media_info = 'D';
809 }
810 break;
811 default:
813 return -1;
814 }
815 }
816 /* FIXME first 10 audio tracks are 0 to 9 next 22 are A to V */
817 sc->
media_info = media_info<<8 | (
'0'+tracks[media_info]++);
819 }
820
822 return -1;
823
824 if (tcr && vsc)
826
828 gxf->
flags |= 0x200000;
// time code track is non-drop frame
829
831 return ret;
834
836
838 return 0;
839 }
840
842 {
844
847 }
848
850 {
854 int i;
855 int ret;
856
858
862 /* overwrite map, flt and umf packets with new values */
864 return ret;
868 /* update duration in all map packets */
872 return ret;
874 }
875
877
880
881 return 0;
882 }
883
885 {
887 int i;
888 for(i=0; i<size-4 && c!=0x100; i++){
889 c = (c<<8) + buf[i];
892 }
893 return (buf[i+1]>>3)&7;
894 }
895
897 {
902 unsigned field_nb;
903 /* If the video is frame-encoded, the frame numbers shall be represented by
904 * even field numbers.
905 * see SMPTE360M-2004 6.4.2.1.3 Media field number */
908 } else {
911 }
912
927 } else {
930 }
935 } else
940 return 16;
941 }
942
944 {
949 int padding = 0;
950 unsigned packet_start_offset =
avio_tell(pb) / 1024;
951 int ret;
952
955 padding = 4 - pkt->
size % 4;
961
964 int err;
971 return err;
972 }
973 }
976 }
977
979
983 return ret;
985 }
986
987 return 0;
988 }
989
991 {
994 int i, field_nb[2];
996
997 for (i = 0; i < 2; i++) {
1003 field_nb[i] &= ~1; // compare against even field number because audio must be before video
1004 } else
1005 field_nb[i] = pkt[i]->
dts;
// dts are field based
1006 }
1007
1008 return field_nb[1] > field_nb[0] ||
1009 (field_nb[1] == field_nb[0] && sc[1]->
order > sc[0]->
order);
1010 }
1011
1013 {
1015 pkt->
duration = 2;
// enforce 2 fields
1018 }
1019
1023 .extensions = "gxf",
1031 };
void avio_wl16(AVIOContext *s, unsigned int val)
int64_t avio_size(AVIOContext *s)
Get the filesize.
static int gxf_write_header(AVFormatContext *s)
static void flush(AVCodecContext *avctx)
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.
int64_t bit_rate
the average bitrate
static int gxf_write_dv_auxiliary(AVIOContext *pb, AVStream *st)
static int64_t updatePacketSize(AVIOContext *pb, int64_t pos)
static int gxf_write_umf_media_mpeg(AVIOContext *pb, AVStream *st)
static const int GXF_samples_per_frame[]
int index
stream index in AVFormatContext
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
static const AVCodecTag gxf_media_types[]
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
static av_always_inline uint64_t av_double2int(double f)
Reinterpret a double as a 64-bit integer.
int b_per_i_or_p
number of B frames per I frame or P frame
GXFStreamContext timecode_track
uint32_t umf_start_offset
AVOutputFormat ff_gxf_muxer
#define av_assert0(cond)
assert() equivalent, that is always enabled.
void avio_wl32(AVIOContext *s, unsigned int val)
static av_cold int end(AVCodecContext *avctx)
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
uint32_t umf_track_offset
int ff_audio_interleave_init(AVFormatContext *s, const int *samples_per_frame, AVRational time_base)
AVStream ** streams
A list of all streams in the file.
AudioInterleaveContext aic
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
static void gxf_init_timecode_track(GXFStreamContext *sc, GXFStreamContext *vsc)
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
static int interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *in, int flush)
Interleave an AVPacket correctly so it can be muxed.
static int gxf_find_lines_index(AVStream *st)
static int gxf_compare_field_nb(AVFormatContext *s, AVPacket *next, AVPacket *cur)
void avio_wl64(AVIOContext *s, uint64_t val)
int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
AVDictionary * metadata
Metadata that applies to the whole file.
static int64_t updateSize(AVIOContext *pb, int64_t pos)
int ff_audio_rechunk_interleave(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush, int(*get_packet)(AVFormatContext *, AVPacket *, AVPacket *, int), int(*compare_ts)(AVFormatContext *, AVPacket *, AVPacket *))
Rechunk audio PCM packets per AudioInterleaveContext->samples_per_frame and interleave them correctly...
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
static void gxf_write_padding(AVIOContext *pb, int64_t to_pad)
uint32_t umf_media_offset
static int gxf_write_umf_media_audio(AVIOContext *pb, GXFStreamContext *sc)
simple assert() macros that are a bit more flexible than ISO C assert().
static int gxf_write_umf_payload(AVFormatContext *s)
static int gxf_write_umf_material_description(AVFormatContext *s)
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
AVCodecContext * codec
Codec context associated with this stream.
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
static int gxf_write_media_preamble(AVFormatContext *s, AVPacket *pkt, int size)
int seekable
A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
int void avio_flush(AVIOContext *s)
Force flushing of buffered data.
static int gxf_parse_mpeg_frame(GXFStreamContext *sc, const uint8_t *buf, int size)
static int gxf_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush)
char filename[1024]
input or output filename
static int write_trailer(AVFormatContext *s1)
void avio_wb24(AVIOContext *s, unsigned int val)
#define GXF_AUDIO_PACKET_SIZE
static int gxf_init_timecode(AVFormatContext *s, GXFTimecode *tc, const char *tcstr, int fields)
static int gxf_write_map_packet(AVFormatContext *s, int rewrite)
preferred ID for MPEG-1/2 video decoding
unsigned order
interleaving order
static int gxf_write_material_data_section(AVFormatContext *s)
unsigned * flt_entries
offsets of packets /1024, starts after 2nd video field
enum AVMediaType codec_type
int sample_rate
samples per second
AVIOContext * pb
I/O context.
void avio_w8(AVIOContext *s, int b)
static int gxf_write_track_description_section(AVFormatContext *s)
#define GXF_TIMECODE(c, d, h, m, s, f)
Describe the class of an AVClass context structure.
static int gxf_write_eos_packet(AVIOContext *pb)
rational number numerator/denominator
static int gxf_write_trailer(AVFormatContext *s)
static int gxf_write_timecode_auxiliary(AVIOContext *pb, GXFContext *gxf)
static int gxf_write_track_description(AVFormatContext *s, GXFStreamContext *sc, int index)
void avio_wb16(AVIOContext *s, unsigned int val)
static const struct @171 gxf_lines_tab[]
static void gxf_write_packet_header(AVIOContext *pb, GXFPktType type)
static int gxf_write_flt_packet(AVFormatContext *s)
static int gxf_write_umf_media_timecode(AVIOContext *pb, int drop)
static int gxf_write_umf_media_dv(AVIOContext *pb, GXFStreamContext *sc, AVStream *st)
void ff_audio_interleave_close(AVFormatContext *s)
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
uint64_t * map_offsets
offset of map packets
static int gxf_write_umf_track_description(AVFormatContext *s)
int channels
number of audio channels
void * priv_data
Format private data.
static void write_header(FFV1Context *f)
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed...
void avio_wb32(AVIOContext *s, unsigned int val)
static int gxf_write_umf_packet(AVFormatContext *s)
This structure stores compressed data.
static int write_packet(AVFormatContext *s1, AVPacket *pkt)
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
static int gxf_write_umf_media_description(AVFormatContext *s)
static int gxf_write_mpeg_auxiliary(AVIOContext *pb, AVStream *st)
static int gxf_write_packet(AVFormatContext *s, AVPacket *pkt)