X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fmxfenc.c;h=77f60f587446136fcf68784169b69854631347b5;hb=e37741d26a1ef2d07e2ccf4e1bc9699a12576111;hp=a9338f7bc327397f11e6427d5574dd356c3e49f5;hpb=86c92509231f67a2397f0d98530e5dca1720d1f3;p=ffmpeg diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index a9338f7bc32..77f60f58744 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -88,6 +88,7 @@ typedef struct MXFStreamContext { int color_siting; int signal_standard; int h_chroma_sub_sample; + int v_chroma_sub_sample; int temporal_reordering; AVRational aspect_ratio; ///< display aspect ratio int closed_gop; ///< gop is closed, used in mpeg-2 frame parsing @@ -422,6 +423,7 @@ static const MXFLocalTagPair mxf_local_tag_batch[] = { { 0x3C0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x01,0x15,0x02,0x00,0x00,0x00,0x00}}, /* Instance UID */ { 0x3B02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x04,0x00,0x00}}, /* Last Modified Date */ { 0x3B05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x01,0x02,0x01,0x05,0x00,0x00,0x00}}, /* Version */ + { 0x3B07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x01,0x02,0x01,0x04,0x00,0x00,0x00}}, /* Object Model Version */ { 0x3B06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x04,0x00,0x00}}, /* Identifications reference */ { 0x3B03, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x01,0x00,0x00}}, /* Content Storage reference */ { 0x3B09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x03,0x00,0x00,0x00,0x00}}, /* Operational Pattern UL */ @@ -479,20 +481,36 @@ static const MXFLocalTagPair mxf_local_tag_batch[] = { { 0x320D, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x03,0x02,0x05,0x00,0x00,0x00}}, /* Video Line Map */ { 0x3203, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x02,0x02,0x00,0x00,0x00}}, /* Stored Width */ { 0x3202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x02,0x01,0x00,0x00,0x00}}, /* Stored Height */ + { 0x3216, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x03,0x02,0x08,0x00,0x00,0x00}}, /* Stored F2 Offset */ + { 0x3205, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x08,0x00,0x00,0x00}}, /* Sampled Width */ + { 0x3204, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x07,0x00,0x00,0x00}}, /* Sampled Height */ + { 0x3206, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x09,0x00,0x00,0x00}}, /* Sampled X Offset */ + { 0x3207, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0A,0x00,0x00,0x00}}, /* Sampled Y Offset */ { 0x3209, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0C,0x00,0x00,0x00}}, /* Display Width */ { 0x3208, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0B,0x00,0x00,0x00}}, /* Display Height */ + { 0x320A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0D,0x00,0x00,0x00}}, /* Display X offset */ { 0x320B, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0E,0x00,0x00,0x00}}, /* Presentation Y offset */ + { 0x3217, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x03,0x02,0x07,0x00,0x00,0x00}}, /* Display F2 offset */ { 0x320E, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x00,0x00,0x00}}, /* Aspect Ratio */ + { 0x3210, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x02,0x01,0x01,0x01,0x02,0x00}}, /* Transfer characteristic */ + { 0x3213, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x18,0x01,0x02,0x00,0x00,0x00,0x00}}, /* Image Start Offset */ + { 0x3214, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x18,0x01,0x03,0x00,0x00,0x00,0x00}}, /* Image End Offset */ { 0x3201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x06,0x01,0x00,0x00,0x00,0x00}}, /* Picture Essence Coding */ { 0x3212, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x03,0x01,0x06,0x00,0x00,0x00}}, /* Field Dominance (Opt) */ { 0x3215, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x05,0x01,0x13,0x00,0x00,0x00,0x00}}, /* Signal Standard */ // CDCI Picture Essence Descriptor { 0x3301, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x05,0x03,0x0A,0x00,0x00,0x00}}, /* Component Depth */ { 0x3302, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x05,0x00,0x00,0x00}}, /* Horizontal Subsampling */ + { 0x3308, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x05,0x01,0x10,0x00,0x00,0x00}}, /* Vertical Subsampling */ { 0x3303, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x06,0x00,0x00,0x00}}, /* Color Siting */ + { 0x3307, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x18,0x01,0x04,0x00,0x00,0x00,0x00}}, /* Padding Bits */ + { 0x3304, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x03,0x03,0x00,0x00,0x00}}, /* Black Ref level */ + { 0x3305, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x03,0x04,0x00,0x00,0x00}}, /* White Ref level */ + { 0x3306, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x05,0x03,0x05,0x00,0x00,0x00}}, /* Color Range */ // Generic Sound Essence Descriptor { 0x3D02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x02,0x03,0x01,0x04,0x00,0x00,0x00}}, /* Locked/Unlocked */ { 0x3D03, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x01,0x01,0x01,0x00,0x00}}, /* Audio sampling rate */ + { 0x3D04, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x02,0x01,0x01,0x03,0x00,0x00,0x00}}, /* Audio Ref Level */ { 0x3D07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x01,0x01,0x04,0x00,0x00,0x00}}, /* ChannelCount */ { 0x3D01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x02,0x03,0x03,0x04,0x00,0x00,0x00}}, /* Quantization bits */ { 0x3D06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x02,0x04,0x02,0x00,0x00,0x00,0x00}}, /* Sound Essence Compression */ @@ -681,7 +699,7 @@ static void mxf_write_preface(AVFormatContext *s) mxf_write_metadata_key(pb, 0x012f00); PRINT_KEY(s, "preface key", pb->buf_ptr - 16); - klv_encode_ber_length(pb, 130 + 16LL * DESCRIPTOR_COUNT(mxf->essence_container_count)); + klv_encode_ber_length(pb, 138 + 16LL * DESCRIPTOR_COUNT(mxf->essence_container_count)); // write preface set uid mxf_write_local_tag(pb, 16, 0x3C0A); @@ -696,6 +714,10 @@ static void mxf_write_preface(AVFormatContext *s) mxf_write_local_tag(pb, 2, 0x3B05); avio_wb16(pb, 259); // v1.3 + // Object Model Version + mxf_write_local_tag(pb, 4, 0x3B07); + avio_wb32(pb, 1); + // write identification_refs mxf_write_local_tag(pb, 16 + 8, 0x3B06); mxf_write_refs_count(pb, 1); @@ -1122,27 +1144,98 @@ static const UID mxf_aes3_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53, static const UID mxf_cdci_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x28,0x00 }; static const UID mxf_generic_sound_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x42,0x00 }; +static int get_trc(UID ul, enum AVColorTransferCharacteristic trc) +{ + switch (trc){ + case AVCOL_TRC_GAMMA28 : + case AVCOL_TRC_GAMMA22 : + memcpy(ul, ((UID){0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x01,0x00,0x00}), 16); + return 0; + case AVCOL_TRC_BT709 : + case AVCOL_TRC_SMPTE170M : + memcpy(ul, ((UID){0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x02,0x00,0x00}), 16); + return 0; + case AVCOL_TRC_SMPTE240M : + memcpy(ul, ((UID){0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x03,0x00,0x00}), 16); + return 0; + case AVCOL_TRC_BT1361_ECG: + memcpy(ul, ((UID){0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x01,0x05,0x00,0x00}), 16); + return 0; + case AVCOL_TRC_LINEAR : + memcpy(ul, ((UID){0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x06,0x04,0x01,0x01,0x01,0x01,0x06,0x00,0x00}), 16); + return 0; + case AVCOL_TRC_SMPTE428 : + memcpy(ul, ((UID){0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x08,0x04,0x01,0x01,0x01,0x01,0x07,0x00,0x00}), 16); + return 0; + default: + return -1; + } +} + static void mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID key, unsigned size) { MXFStreamContext *sc = st->priv_data; AVIOContext *pb = s->pb; + int stored_width = (st->codecpar->width +15)/16*16; int stored_height = (st->codecpar->height+15)/16*16; int display_height; int f1, f2; - unsigned desc_size = size+8+8+8+8+8+8+8+5+16+4+12+20+5; + unsigned desc_size = size+8+8+8+8+8+8+8+5+16+4+12+20+5 + 5*8 + 6; + UID transfer_ul = {0}; + if (sc->interlaced && sc->field_dominance) desc_size += 5; if (sc->signal_standard) desc_size += 5; + if (sc->interlaced) + desc_size += 8; + if (sc->v_chroma_sub_sample) + desc_size += 8; + if (st->codecpar->color_range != AVCOL_RANGE_UNSPECIFIED) + desc_size += 8 * 3; + if (s->oformat == &ff_mxf_d10_muxer) + desc_size += 8 + 8 + 8; + if (get_trc(transfer_ul, st->codecpar->color_trc) >= 0) + desc_size += 20; mxf_write_generic_desc(s, st, key, desc_size); mxf_write_local_tag(pb, 4, 0x3203); - avio_wb32(pb, st->codecpar->width); + avio_wb32(pb, stored_width); mxf_write_local_tag(pb, 4, 0x3202); avio_wb32(pb, stored_height>>sc->interlaced); + if (s->oformat == &ff_mxf_d10_muxer) { + //Stored F2 Offset + mxf_write_local_tag(pb, 4, 0x3216); + avio_wb32(pb, 0); + + //Image Start Offset + mxf_write_local_tag(pb, 4, 0x3213); + avio_wb32(pb, 0); + + //Image End Offset + mxf_write_local_tag(pb, 4, 0x3214); + avio_wb32(pb, 0); + } + + //Sampled width + mxf_write_local_tag(pb, 4, 0x3205); + avio_wb32(pb, st->codecpar->width); + + //Samples height + mxf_write_local_tag(pb, 4, 0x3204); + avio_wb32(pb, st->codecpar->height>>sc->interlaced); + + //Sampled X Offset + mxf_write_local_tag(pb, 4, 0x3206); + avio_wb32(pb, 0); + + //Sampled Y Offset + mxf_write_local_tag(pb, 4, 0x3207); + avio_wb32(pb, 0); + mxf_write_local_tag(pb, 4, 0x3209); avio_wb32(pb, st->codecpar->width); @@ -1156,10 +1249,20 @@ static void mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID ke mxf_write_local_tag(pb, 4, 0x3208); avio_wb32(pb, display_height>>sc->interlaced); - // presentation Y offset + // display X offset + mxf_write_local_tag(pb, 4, 0x320A); + avio_wb32(pb, 0); + + // display Y offset mxf_write_local_tag(pb, 4, 0x320B); avio_wb32(pb, (st->codecpar->height - display_height)>>sc->interlaced); + if (sc->interlaced) { + //Display F2 Offset + mxf_write_local_tag(pb, 4, 0x3217); + avio_wb32(pb, -((st->codecpar->height - display_height)&1)); + } + // component depth mxf_write_local_tag(pb, 4, 0x3301); avio_wb32(pb, sc->component_depth); @@ -1168,10 +1271,37 @@ static void mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID ke mxf_write_local_tag(pb, 4, 0x3302); avio_wb32(pb, sc->h_chroma_sub_sample); + // vertical subsampling + if (sc->v_chroma_sub_sample) { + mxf_write_local_tag(pb, 4, 0x3308); + avio_wb32(pb, sc->v_chroma_sub_sample); + } + // color siting mxf_write_local_tag(pb, 1, 0x3303); avio_w8(pb, sc->color_siting); + // Padding Bits + mxf_write_local_tag(pb, 2, 0x3307); + avio_wb16(pb, 0); + + if (st->codecpar->color_range != AVCOL_RANGE_UNSPECIFIED) { + int black = 0, + white = (1<component_depth) - 1, + color = (1<component_depth) - 1; + if (st->codecpar->color_range == AVCOL_RANGE_MPEG) { + black = 1 << (sc->component_depth - 4); + white = 235 << (sc->component_depth - 8); + color = (14 << (sc->component_depth - 4)) + 1; + } + mxf_write_local_tag(pb, 4, 0x3304); + avio_wb32(pb, black); + mxf_write_local_tag(pb, 4, 0x3305); + avio_wb32(pb, white); + mxf_write_local_tag(pb, 4, 0x3306); + avio_wb32(pb, color); + } + if (sc->signal_standard) { mxf_write_local_tag(pb, 1, 0x3215); avio_w8(pb, sc->signal_standard); @@ -1208,6 +1338,12 @@ static void mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID ke avio_wb32(pb, sc->aspect_ratio.num); avio_wb32(pb, sc->aspect_ratio.den); + //Transfer characteristic + if (transfer_ul[0]) { + mxf_write_local_tag(pb, 16, 0x3210); + avio_write(pb, transfer_ul, 16); + }; + mxf_write_local_tag(pb, 16, 0x3201); avio_write(pb, *sc->codec_ul, 16); @@ -1255,6 +1391,8 @@ static void mxf_write_generic_sound_common(AVFormatContext *s, AVStream *st, con if (s->oformat == &ff_mxf_opatom_muxer) duration_size = 12; + if (s->oformat == &ff_mxf_d10_muxer) + size += 5; mxf_write_generic_desc(s, st, key, size+duration_size+5+12+8+8); @@ -1272,6 +1410,11 @@ static void mxf_write_generic_sound_common(AVFormatContext *s, AVStream *st, con avio_wb32(pb, st->codecpar->sample_rate); avio_wb32(pb, 1); + if (s->oformat == &ff_mxf_d10_muxer) { + mxf_write_local_tag(pb, 1, 0x3D04); + avio_w8(pb, 0); + } + mxf_write_local_tag(pb, 4, 0x3D07); if (mxf->channel_count == -1) { if (show_warnings && (s->oformat == &ff_mxf_d10_muxer) && (st->codecpar->channels != 4) && (st->codecpar->channels != 8)) @@ -1974,22 +2117,31 @@ static const struct { int frame_size; int profile; uint8_t interlaced; + int long_gop; // 1 or 0 when there are separate UIDs for Long GOP and Intra, -1 when Intra/LGOP detection can be ignored } mxf_h264_codec_uls[] = { - {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x31,0x11,0x01 }, 0, 66, 0 }, // AVC Baseline, Unconstrained Coding - {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x20,0x01 }, 0, 110, 0 }, // AVC High 10 Intra - {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x01 }, 232960, 0, 1 }, // AVC Intra 50 1080i60 - {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x02 }, 281088, 0, 1 }, // AVC Intra 50 1080i50 - {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x03 }, 232960, 0, 0 }, // AVC Intra 50 1080p30 - {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x04 }, 281088, 0, 0 }, // AVC Intra 50 1080p25 - {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x08 }, 116736, 0, 0 }, // AVC Intra 50 720p60 - {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x09 }, 140800, 0, 0 }, // AVC Intra 50 720p50 - {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x30,0x01 }, 0, 122, 0 }, // AVC High 422 Intra - {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x31,0x01 }, 472576, 0, 1 }, // AVC Intra 100 1080i60 - {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x31,0x02 }, 568832, 0, 1 }, // AVC Intra 100 1080i50 - {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x31,0x03 }, 472576, 0, 0 }, // AVC Intra 100 1080p30 - {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x31,0x04 }, 568832, 0, 0 }, // AVC Intra 100 1080p25 - {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x31,0x08 }, 236544, 0, 0 }, // AVC Intra 100 720p60 - {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x31,0x09 }, 284672, 0, 0 }, // AVC Intra 100 720p50 + {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x31,0x11,0x01 }, 0, 66, 0, -1 }, // AVC Baseline, Unconstrained Coding + {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x31,0x20,0x01 }, 0, 77, 0, -1 }, // AVC Main + {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x31,0x30,0x01 }, 0, 88, 0, -1 }, // AVC Extended + {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x31,0x40,0x01 }, 0, 100, 0, -1 }, // AVC High + {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x31,0x50,0x01 }, 0, 110, 0, 1 }, // AVC High 10 + {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x31,0x60,0x01 }, 0, 122, 0, 1 }, // AVC High 422 + {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x31,0x70,0x01 }, 0, 244, 0, 1 }, // AVC High 444 + {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x20,0x01 }, 0, 110, 0, 0 }, // AVC High 10 Intra + {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x01 }, 232960, 0, 1, 0 }, // AVC Intra 50 1080i60 + {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x02 }, 281088, 0, 1, 0 }, // AVC Intra 50 1080i50 + {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x03 }, 232960, 0, 0, 0 }, // AVC Intra 50 1080p30 + {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x04 }, 281088, 0, 0, 0 }, // AVC Intra 50 1080p25 + {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x08 }, 116736, 0, 0, 0 }, // AVC Intra 50 720p60 + {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x21,0x09 }, 140800, 0, 0, 0 }, // AVC Intra 50 720p50 + {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x30,0x01 }, 0, 122, 0, 0 }, // AVC High 422 Intra + {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x31,0x01 }, 472576, 0, 1, 0 }, // AVC Intra 100 1080i60 + {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x31,0x02 }, 568832, 0, 1, 0 }, // AVC Intra 100 1080i50 + {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x31,0x03 }, 472576, 0, 0, 0 }, // AVC Intra 100 1080p30 + {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x31,0x04 }, 568832, 0, 0, 0 }, // AVC Intra 100 1080p25 + {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x31,0x08 }, 236544, 0, 0, 0 }, // AVC Intra 100 720p60 + {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0a,0x04,0x01,0x02,0x02,0x01,0x32,0x31,0x09 }, 284672, 0, 0, 0 }, // AVC Intra 100 720p50 + {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0d,0x04,0x01,0x02,0x02,0x01,0x32,0x40,0x01 }, 0, 244, 0, 0 }, // AVC High 444 Intra + {{ 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0d,0x04,0x01,0x02,0x02,0x01,0x32,0x50,0x01 }, 0, 44, 0, -1 }, // AVC CAVLC 444 }; static int mxf_parse_h264_frame(AVFormatContext *s, AVStream *st, @@ -1997,10 +2149,12 @@ static int mxf_parse_h264_frame(AVFormatContext *s, AVStream *st, { MXFContext *mxf = s->priv_data; MXFStreamContext *sc = st->priv_data; + AVCodecParameters *par = st->codecpar; static const int mxf_h264_num_codec_uls = sizeof(mxf_h264_codec_uls) / sizeof(mxf_h264_codec_uls[0]); const uint8_t *buf = pkt->data; const uint8_t *buf_end = pkt->data + pkt->size; uint32_t state = -1; + int long_gop = 0; // assume intra when there is no SPS header int extra_size = 512; // support AVC Intra files without SPS/PPS header int i, frame_size; uint8_t uid_found; @@ -2015,7 +2169,8 @@ static int mxf_parse_h264_frame(AVFormatContext *s, AVStream *st, --buf; switch (state & 0x1f) { case H264_NAL_SPS: - st->codecpar->profile = buf[1]; + par->profile = buf[1]; + long_gop = buf[2] & 0x10 ? 0 : 1; // constraint_set3_flag signals intra e->flags |= 0x40; break; case H264_NAL_PPS: @@ -2034,25 +2189,27 @@ static int mxf_parse_h264_frame(AVFormatContext *s, AVStream *st, return 1; sc->aspect_ratio = (AVRational){ 16, 9 }; // 16:9 is mandatory for broadcast HD - sc->component_depth = 10; // AVC Intra is always 10 Bit - sc->interlaced = st->codecpar->field_order != AV_FIELD_PROGRESSIVE ? 1 : 0; - if (sc->interlaced) - sc->field_dominance = 1; // top field first is mandatory for AVC Intra + sc->interlaced = par->field_order != AV_FIELD_PROGRESSIVE ? 1 : 0; uid_found = 0; frame_size = pkt->size + extra_size; for (i = 0; i < mxf_h264_num_codec_uls; i++) { if (frame_size == mxf_h264_codec_uls[i].frame_size && sc->interlaced == mxf_h264_codec_uls[i].interlaced) { sc->codec_ul = &mxf_h264_codec_uls[i].uid; + sc->component_depth = 10; // AVC Intra is always 10 Bit + if (sc->interlaced) + sc->field_dominance = 1; // top field first is mandatory for AVC Intra return 1; - } else if (st->codecpar->profile == mxf_h264_codec_uls[i].profile) { + } else if ((mxf_h264_codec_uls[i].profile == par->profile) && + ((mxf_h264_codec_uls[i].long_gop < 0) || + (mxf_h264_codec_uls[i].long_gop == long_gop))) { sc->codec_ul = &mxf_h264_codec_uls[i].uid; uid_found = 1; } } if (!uid_found) { - av_log(s, AV_LOG_ERROR, "AVC Intra 50/100 supported only\n"); + av_log(s, AV_LOG_ERROR, "h264 profile not supported\n"); return 0; } @@ -2232,6 +2389,7 @@ static int mxf_write_header(AVFormatContext *s) if (pix_desc) { sc->component_depth = pix_desc->comp[0].depth; sc->h_chroma_sub_sample = 1 << pix_desc->log2_chroma_w; + sc->v_chroma_sub_sample = 1 << pix_desc->log2_chroma_h; } switch (ff_choose_chroma_location(s, st)) { case AVCHROMA_LOC_TOPLEFT: sc->color_siting = 0; break; @@ -2282,6 +2440,7 @@ static int mxf_write_header(AVFormatContext *s) mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count); sc->signal_standard = 1; + sc->color_siting = 0; } if (mxf->signal_standard >= 0) sc->signal_standard = mxf->signal_standard;