| @@ -83,6 +83,7 @@ typedef struct MXFStreamContext { | |||
| UID track_essence_element_key; | |||
| int index; ///< index in mxf_essence_container_uls table | |||
| const UID *codec_ul; | |||
| const UID *container_ul; | |||
| int order; ///< interleaving order if dts are equal | |||
| int interlaced; ///< whether picture is interlaced | |||
| int field_dominance; ///< tff=1, bff=2 | |||
| @@ -135,16 +136,6 @@ enum ULIndex { | |||
| INDEX_D10_525_60_30_VIDEO, | |||
| INDEX_D10_525_60_30_AUDIO, | |||
| INDEX_DV, | |||
| INDEX_DV25_525_60, | |||
| INDEX_DV25_625_50, | |||
| INDEX_DV25_525_60_IEC, | |||
| INDEX_DV25_625_50_IEC, | |||
| INDEX_DV50_525_60, | |||
| INDEX_DV50_625_50, | |||
| INDEX_DV100_1080_60, | |||
| INDEX_DV100_1080_50, | |||
| INDEX_DV100_720_60, | |||
| INDEX_DV100_720_50, | |||
| INDEX_DNXHD, | |||
| INDEX_JPEG2000, | |||
| INDEX_H264, | |||
| @@ -242,64 +233,11 @@ static const MXFContainerEssenceEntry mxf_essence_container_uls[] = { | |||
| { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 }, | |||
| { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, | |||
| mxf_write_generic_sound_desc }, | |||
| // DV Unknown | |||
| // DV | |||
| { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x7F,0x01 }, | |||
| { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 }, | |||
| { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x00,0x00,0x00 }, | |||
| mxf_write_cdci_desc }, | |||
| // DV25 525/60 | |||
| { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x40,0x01 }, | |||
| { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 }, | |||
| { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x01,0x00 }, | |||
| mxf_write_cdci_desc }, | |||
| // DV25 625/50 | |||
| { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x41,0x01 }, | |||
| { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 }, | |||
| { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x02,0x00 }, | |||
| mxf_write_cdci_desc }, | |||
| // IEC DV25 525/60 | |||
| { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x01,0x01 }, | |||
| { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 }, | |||
| { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x01,0x00 }, | |||
| mxf_write_cdci_desc }, | |||
| // IEC DV25 625/50 | |||
| { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x02,0x01 }, | |||
| { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 }, | |||
| { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x01,0x02,0x00 }, | |||
| mxf_write_cdci_desc }, | |||
| // DV50 525/60 | |||
| { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x50,0x01 }, | |||
| { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 }, | |||
| { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x03,0x00 }, | |||
| mxf_write_cdci_desc }, | |||
| // DV50 625/50 | |||
| { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x51,0x01 }, | |||
| { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 }, | |||
| { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x04,0x00 }, | |||
| mxf_write_cdci_desc }, | |||
| // DV100 1080/60 | |||
| { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x60,0x01 }, | |||
| { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 }, | |||
| { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x05,0x00 }, | |||
| mxf_write_cdci_desc }, | |||
| // DV100 1080/50 | |||
| { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x61,0x01 }, | |||
| { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 }, | |||
| { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x06,0x00 }, | |||
| mxf_write_cdci_desc }, | |||
| // DV100 720/60 | |||
| { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x62,0x01 }, | |||
| { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 }, | |||
| { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x07,0x00 }, | |||
| mxf_write_cdci_desc }, | |||
| // DV100 720/50 | |||
| { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x63,0x01 }, | |||
| { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 }, | |||
| { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x08,0x00 }, | |||
| mxf_write_cdci_desc }, | |||
| // DNxHD | |||
| { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 }, | |||
| { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 }, | |||
| @@ -690,7 +628,7 @@ static void mxf_write_essence_container_refs(AVFormatContext *s) | |||
| // check first track of essence container type and only write it once | |||
| if (sc->track_essence_element_key[15] != 0) | |||
| continue; | |||
| avio_write(pb, mxf_essence_container_uls[sc->index].container_ul, 16); | |||
| avio_write(pb, *sc->container_ul, 16); | |||
| if (c->essence_container_count == 1) | |||
| break; | |||
| } | |||
| @@ -1100,7 +1038,7 @@ static void mxf_write_multi_descriptor(AVFormatContext *s) | |||
| ul = multiple_desc_ul; | |||
| else { | |||
| MXFStreamContext *sc = s->streams[0]->priv_data; | |||
| ul = mxf_essence_container_uls[sc->index].container_ul; | |||
| ul = *sc->container_ul; | |||
| } | |||
| avio_write(pb, ul, 16); | |||
| @@ -1144,7 +1082,7 @@ static int64_t mxf_write_generic_desc(AVFormatContext *s, AVStream *st, const UI | |||
| } | |||
| mxf_write_local_tag(pb, 16, 0x3004); | |||
| avio_write(pb, mxf_essence_container_uls[sc->index].container_ul, 16); | |||
| avio_write(pb, *sc->container_ul, 16); | |||
| return pos; | |||
| } | |||
| @@ -2156,13 +2094,38 @@ static int mxf_parse_dnxhd_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt | |||
| return 1; | |||
| } | |||
| static const struct { | |||
| const UID container_ul; | |||
| const UID codec_ul; | |||
| } mxf_dv_uls[] = { | |||
| { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x01,0x01 }, // IEC DV25 525/60 | |||
| { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x01,0x01,0x00 } }, | |||
| { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x02,0x01 }, // IEC DV25 626/50 | |||
| { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x01,0x02,0x00 } }, | |||
| { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x40,0x01 }, // DV25 525/60 | |||
| { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x01,0x00 }, }, | |||
| { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x41,0x01 }, // DV25 625/50 | |||
| { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x02,0x00 }, }, | |||
| { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x50,0x01 }, // DV50 525/60 | |||
| { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x03,0x00 }, }, | |||
| { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x51,0x01 }, // DV50 625/50 | |||
| { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x04,0x00 }, }, | |||
| { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x60,0x01 }, // DV100 1080/60 | |||
| { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x05,0x00 }, }, | |||
| { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x61,0x01 }, // DV100 1080/50 | |||
| { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x06,0x00 }, }, | |||
| { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x62,0x01 }, // DV100 720/60 | |||
| { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x07,0x00 }, }, | |||
| { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x63,0x01 }, // DV100 720/50 | |||
| { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x08,0x00 }, }, | |||
| }; | |||
| static int mxf_parse_dv_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt) | |||
| { | |||
| MXFContext *mxf = s->priv_data; | |||
| MXFStreamContext *sc = st->priv_data; | |||
| uint8_t *vs_pack, *vsc_pack; | |||
| int ul_index, stype, pal; | |||
| const AVDVProfile *profile; | |||
| int apt, ul_index, stype, pal; | |||
| if (mxf->header_written) | |||
| return 1; | |||
| @@ -2171,8 +2134,7 @@ static int mxf_parse_dv_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt) | |||
| if (pkt->size < 120000) | |||
| return -1; | |||
| profile = av_dv_frame_profile(NULL, pkt->data, pkt->size); | |||
| apt = pkt->data[4] & 0x7; | |||
| vs_pack = pkt->data + 80*5 + 48; | |||
| vsc_pack = pkt->data + 80*5 + 53; | |||
| stype = vs_pack[3] & 0x1f; | |||
| @@ -2191,28 +2153,29 @@ static int mxf_parse_dv_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt) | |||
| switch (stype) { | |||
| case 0x18: // DV100 720p | |||
| ul_index = INDEX_DV100_720_50 + pal; | |||
| ul_index = 8+pal; | |||
| if (sc->interlaced) { | |||
| av_log(s, AV_LOG_ERROR, "source marked as interlaced but codec profile is progressive\n"); | |||
| sc->interlaced = 0; | |||
| } | |||
| break; | |||
| case 0x14: // DV100 1080i | |||
| ul_index = INDEX_DV100_1080_50 + pal; | |||
| ul_index = 6+pal; | |||
| break; | |||
| case 0x04: // DV50 | |||
| ul_index = INDEX_DV50_525_60 + pal; | |||
| ul_index = 4+pal; | |||
| break; | |||
| default: // DV25 | |||
| if (profile && profile->pix_fmt == AV_PIX_FMT_YUV420P && pal) { | |||
| ul_index = INDEX_DV25_525_60_IEC + pal; | |||
| break; | |||
| if (!apt) { // IEC | |||
| ul_index = 0+pal; | |||
| } else { | |||
| ul_index = 2+pal; | |||
| } | |||
| ul_index = INDEX_DV25_525_60 + pal; | |||
| } | |||
| sc->index = ul_index; | |||
| sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul; | |||
| sc->container_ul = &mxf_dv_uls[ul_index].container_ul; | |||
| sc->codec_ul = &mxf_dv_uls[ul_index].codec_ul; | |||
| sc->frame_size = pkt->size; | |||
| return 1; | |||
| @@ -2685,6 +2648,7 @@ static int mxf_write_header(AVFormatContext *s) | |||
| } | |||
| sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul; | |||
| sc->container_ul = &mxf_essence_container_uls[sc->index].container_ul; | |||
| memcpy(sc->track_essence_element_key, mxf_essence_container_uls[sc->index].element_ul, 15); | |||
| sc->track_essence_element_key[15] = present[sc->index]; | |||
| @@ -2706,7 +2670,7 @@ static int mxf_write_header(AVFormatContext *s) | |||
| MXFStreamContext *sc = s->streams[i]->priv_data; | |||
| // update element count | |||
| sc->track_essence_element_key[13] = present[sc->index]; | |||
| if (!memcmp(sc->track_essence_element_key, mxf_essence_container_uls[15].element_ul, 13)) // DV | |||
| if (!memcmp(sc->track_essence_element_key, mxf_essence_container_uls[INDEX_DV].element_ul, 13)) // DV | |||
| sc->order = (0x15 << 24) | AV_RB32(sc->track_essence_element_key+13); | |||
| else | |||
| sc->order = AV_RB32(sc->track_essence_element_key+12); | |||
| @@ -2765,7 +2729,7 @@ static void mxf_write_system_item(AVFormatContext *s) | |||
| avio_write(pb, multiple_desc_ul, 16); | |||
| else { | |||
| MXFStreamContext *sc = s->streams[0]->priv_data; | |||
| avio_write(pb, mxf_essence_container_uls[sc->index].container_ul, 16); | |||
| avio_write(pb, *sc->container_ul, 16); | |||
| } | |||
| avio_w8(pb, 0); | |||
| avio_wb64(pb, 0); | |||