Re: [FFmpeg-devel] [PATCH 10/12] lavf/mxfdec: demux s436m as eia608 subtitle track
On Wed, Jul 4, 2018 at 1:50 PM Marton Balint wrote: > > > On Wed, 4 Jul 2018, Baptiste Coudurier wrote: > > > --- > > libavformat/mxfdec.c | 102 +++ > > 1 file changed, 102 insertions(+) > > > > diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c > > index 3f443bbbc9..54e4be7934 100644 > > --- a/libavformat/mxfdec.c > > +++ b/libavformat/mxfdec.c > > @@ -52,6 +52,7 @@ > > #include "libavutil/intreadwrite.h" > > #include "libavutil/parseutils.h" > > #include "libavutil/timecode.h" > > +#include "libavutil/opt.h" > > #include "avformat.h" > > #include "internal.h" > > #include "mxf.h" > > @@ -263,6 +264,7 @@ typedef struct MXFIndexTable { > > } MXFIndexTable; > > > > typedef struct MXFContext { > > +const AVClass *class; /**< Class for private options. */ > > MXFPartition *partitions; > > unsigned partitions_count; > > MXFOP op; > > @@ -287,6 +289,8 @@ typedef struct MXFContext { > > int64_t current_edit_unit; > > int nb_index_tables; > > MXFIndexTable *index_tables; > > +int edit_units_per_packet; ///< how many edit units to read at > a time (PCM, OPAtom) > > This seems unused, probably remained after a merge. (edit_units_per_packet > is now an MXFTrack property). > > > +int eia608_extract; > > } MXFContext; > > > > /* NOTE: klv_offset is not set (-1) for local keys */ > > @@ -449,6 +453,78 @@ static int find_body_sid_by_offset(MXFContext *mxf, > int64_t offset) > > return mxf->partitions[a].body_sid; > > } > > > > +static int mxf_get_eia608_packet(AVFormatContext *s, AVStream *st, > AVPacket *pkt, int64_t length) > > +{ > > +int count = avio_rb16(s->pb); > > +int i, ret; > > + > > +for (i = 0; i < count; i++) { > > +if (length < 6) { > > +av_log(s, AV_LOG_ERROR, "error reading s436m packet > %"PRId64"\n", length); > > +return AVERROR_INVALIDDATA; > > +} > > +int line_num = avio_rb16(s->pb); > > +int wrapping_type = avio_r8(s->pb); > > +int sample_coding = avio_r8(s->pb); > > +int sample_count = avio_rb16(s->pb); > > +av_log(s, AV_LOG_DEBUG, "len %"PRId64" line %d wrap type %d > coding %d count %d\n", > > + length, line_num, wrapping_type, sample_coding, > sample_count); > > +length -= 6 + 8 + sample_count; > > +if (line_num != 9 && line_num != 11) > > +break; > > +if (sample_coding == 7 || sample_coding == 8 || sample_coding > == 9) { > > +av_log(s, AV_LOG_ERROR, "unsupported s436m 10 bit sample > coding\n"); > > +return 0; > > +} > > +if (length < 0) > > +return AVERROR_INVALIDDATA; > > + > > +int array_count = avio_rb32(s->pb); > > +int array_elem_size = avio_rb32(s->pb); > > +av_log(s, AV_LOG_DEBUG, "array count %d elem size %d\n", > array_count, array_elem_size); > > +int did = avio_r8(s->pb); > > +int sdid = avio_r8(s->pb); > > +int data_count = avio_r8(s->pb); > > +av_log(s, AV_LOG_DEBUG, "did %x sdid %x count %d\n", did, sdid, > data_count); > > +if (did != 0x61) > > +break; > > +int cdp_id = avio_rb16(s->pb); > > +int cdp_data_count = avio_r8(s->pb); > > +int cdp_framing_rate = avio_r8(s->pb) >> 4; > > +int cdp_flags = avio_r8(s->pb); > > +int cdp_counter = avio_rb16(s->pb); > > +int cdp_data_section = avio_r8(s->pb); > > +if (cdp_data_section != 0x72) { > > +av_log(s, AV_LOG_ERROR, "wrong cdp data section %x\n", > cdp_data_section); > > +return AVERROR_INVALIDDATA; > > +} > > +int flags = avio_r8(s->pb); > > +int cc_count = flags & 0x1f; > > +av_log(s, AV_LOG_DEBUG, "cdp id %x dcount %d frame rate %d cdp > flags %x flags %x " > > + "cc count %d counter %d section %x\n", cdp_id, > cdp_data_count, cdp_framing_rate, > > + cdp_flags, flags, cc_count, cdp_counter, > cdp_data_section); > > +ret = av_get_packet(s->pb, pkt, cc_count * 3); > > +if (ret < 0) > > +return ret; > > +if (cdp_data_count - 9 - 4 < cc_count * 3) { > > +av_log(s, AV_LOG_ERROR, "wrong cdp size %d cc count %d\n", > data_count, cc_count); > > +return AVERROR_INVALIDDATA; > > +} > > +avio_skip(s->pb, data_count - 9 - 4 - cc_count * 3); > > +int cdp_footer_section = avio_r8(s->pb); > > +if (cdp_footer_section != 0x74) { > > +av_log(s, AV_LOG_ERROR, "wrong cdp footer section %x\n", > cdp_footer_section); > > +return AVERROR_INVALIDDATA; > > +} > > +int cdp_counter2 = avio_rb16(s->pb); > > +int cdp_checksum = avio_r8(s->pb); > > +av_log(s, AV_LOG_DEBUG, "cdp counter %d checksum %x\n", > cdp_counter2, cdp_checksum); > > +break; > > +} > > + > > +return 0; > > +} > > + > > /* XXX: u
Re: [FFmpeg-devel] [PATCH 10/12] lavf/mxfdec: demux s436m as eia608 subtitle track
On Wed, 4 Jul 2018, Baptiste Coudurier wrote: --- libavformat/mxfdec.c | 102 +++ 1 file changed, 102 insertions(+) diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 3f443bbbc9..54e4be7934 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -52,6 +52,7 @@ #include "libavutil/intreadwrite.h" #include "libavutil/parseutils.h" #include "libavutil/timecode.h" +#include "libavutil/opt.h" #include "avformat.h" #include "internal.h" #include "mxf.h" @@ -263,6 +264,7 @@ typedef struct MXFIndexTable { } MXFIndexTable; typedef struct MXFContext { +const AVClass *class; /**< Class for private options. */ MXFPartition *partitions; unsigned partitions_count; MXFOP op; @@ -287,6 +289,8 @@ typedef struct MXFContext { int64_t current_edit_unit; int nb_index_tables; MXFIndexTable *index_tables; +int edit_units_per_packet; ///< how many edit units to read at a time (PCM, OPAtom) This seems unused, probably remained after a merge. (edit_units_per_packet is now an MXFTrack property). +int eia608_extract; } MXFContext; /* NOTE: klv_offset is not set (-1) for local keys */ @@ -449,6 +453,78 @@ static int find_body_sid_by_offset(MXFContext *mxf, int64_t offset) return mxf->partitions[a].body_sid; } +static int mxf_get_eia608_packet(AVFormatContext *s, AVStream *st, AVPacket *pkt, int64_t length) +{ +int count = avio_rb16(s->pb); +int i, ret; + +for (i = 0; i < count; i++) { +if (length < 6) { +av_log(s, AV_LOG_ERROR, "error reading s436m packet %"PRId64"\n", length); +return AVERROR_INVALIDDATA; +} +int line_num = avio_rb16(s->pb); +int wrapping_type = avio_r8(s->pb); +int sample_coding = avio_r8(s->pb); +int sample_count = avio_rb16(s->pb); +av_log(s, AV_LOG_DEBUG, "len %"PRId64" line %d wrap type %d coding %d count %d\n", + length, line_num, wrapping_type, sample_coding, sample_count); +length -= 6 + 8 + sample_count; +if (line_num != 9 && line_num != 11) +break; +if (sample_coding == 7 || sample_coding == 8 || sample_coding == 9) { +av_log(s, AV_LOG_ERROR, "unsupported s436m 10 bit sample coding\n"); +return 0; +} +if (length < 0) +return AVERROR_INVALIDDATA; + +int array_count = avio_rb32(s->pb); +int array_elem_size = avio_rb32(s->pb); +av_log(s, AV_LOG_DEBUG, "array count %d elem size %d\n", array_count, array_elem_size); +int did = avio_r8(s->pb); +int sdid = avio_r8(s->pb); +int data_count = avio_r8(s->pb); +av_log(s, AV_LOG_DEBUG, "did %x sdid %x count %d\n", did, sdid, data_count); +if (did != 0x61) +break; +int cdp_id = avio_rb16(s->pb); +int cdp_data_count = avio_r8(s->pb); +int cdp_framing_rate = avio_r8(s->pb) >> 4; +int cdp_flags = avio_r8(s->pb); +int cdp_counter = avio_rb16(s->pb); +int cdp_data_section = avio_r8(s->pb); +if (cdp_data_section != 0x72) { +av_log(s, AV_LOG_ERROR, "wrong cdp data section %x\n", cdp_data_section); +return AVERROR_INVALIDDATA; +} +int flags = avio_r8(s->pb); +int cc_count = flags & 0x1f; +av_log(s, AV_LOG_DEBUG, "cdp id %x dcount %d frame rate %d cdp flags %x flags %x " + "cc count %d counter %d section %x\n", cdp_id, cdp_data_count, cdp_framing_rate, + cdp_flags, flags, cc_count, cdp_counter, cdp_data_section); +ret = av_get_packet(s->pb, pkt, cc_count * 3); +if (ret < 0) +return ret; +if (cdp_data_count - 9 - 4 < cc_count * 3) { +av_log(s, AV_LOG_ERROR, "wrong cdp size %d cc count %d\n", data_count, cc_count); +return AVERROR_INVALIDDATA; +} +avio_skip(s->pb, data_count - 9 - 4 - cc_count * 3); +int cdp_footer_section = avio_r8(s->pb); +if (cdp_footer_section != 0x74) { +av_log(s, AV_LOG_ERROR, "wrong cdp footer section %x\n", cdp_footer_section); +return AVERROR_INVALIDDATA; +} +int cdp_counter2 = avio_rb16(s->pb); +int cdp_checksum = avio_r8(s->pb); +av_log(s, AV_LOG_DEBUG, "cdp counter %d checksum %x\n", cdp_counter2, cdp_checksum); +break; +} + +return 0; +} + /* XXX: use AVBitStreamFilter */ static int mxf_get_d10_aes3_packet(AVIOContext *pb, AVStream *st, AVPacket *pkt, int64_t length) { @@ -2415,6 +2491,11 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) st->codecpar->codec_type = type; if (container_ul->desc) av_dict_set(&st->metadata, "data_type", container_ul->desc, 0); +if (mxf->eia608_extract && +!strcmp(container_ul->desc, "vbi_vanc_smpte_436M")) { +st->codecpar->cod
[FFmpeg-devel] [PATCH 10/12] lavf/mxfdec: demux s436m as eia608 subtitle track
--- libavformat/mxfdec.c | 102 +++ 1 file changed, 102 insertions(+) diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 3f443bbbc9..54e4be7934 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -52,6 +52,7 @@ #include "libavutil/intreadwrite.h" #include "libavutil/parseutils.h" #include "libavutil/timecode.h" +#include "libavutil/opt.h" #include "avformat.h" #include "internal.h" #include "mxf.h" @@ -263,6 +264,7 @@ typedef struct MXFIndexTable { } MXFIndexTable; typedef struct MXFContext { +const AVClass *class; /**< Class for private options. */ MXFPartition *partitions; unsigned partitions_count; MXFOP op; @@ -287,6 +289,8 @@ typedef struct MXFContext { int64_t current_edit_unit; int nb_index_tables; MXFIndexTable *index_tables; +int edit_units_per_packet; ///< how many edit units to read at a time (PCM, OPAtom) +int eia608_extract; } MXFContext; /* NOTE: klv_offset is not set (-1) for local keys */ @@ -449,6 +453,78 @@ static int find_body_sid_by_offset(MXFContext *mxf, int64_t offset) return mxf->partitions[a].body_sid; } +static int mxf_get_eia608_packet(AVFormatContext *s, AVStream *st, AVPacket *pkt, int64_t length) +{ +int count = avio_rb16(s->pb); +int i, ret; + +for (i = 0; i < count; i++) { +if (length < 6) { +av_log(s, AV_LOG_ERROR, "error reading s436m packet %"PRId64"\n", length); +return AVERROR_INVALIDDATA; +} +int line_num = avio_rb16(s->pb); +int wrapping_type = avio_r8(s->pb); +int sample_coding = avio_r8(s->pb); +int sample_count = avio_rb16(s->pb); +av_log(s, AV_LOG_DEBUG, "len %"PRId64" line %d wrap type %d coding %d count %d\n", + length, line_num, wrapping_type, sample_coding, sample_count); +length -= 6 + 8 + sample_count; +if (line_num != 9 && line_num != 11) +break; +if (sample_coding == 7 || sample_coding == 8 || sample_coding == 9) { +av_log(s, AV_LOG_ERROR, "unsupported s436m 10 bit sample coding\n"); +return 0; +} +if (length < 0) +return AVERROR_INVALIDDATA; + +int array_count = avio_rb32(s->pb); +int array_elem_size = avio_rb32(s->pb); +av_log(s, AV_LOG_DEBUG, "array count %d elem size %d\n", array_count, array_elem_size); +int did = avio_r8(s->pb); +int sdid = avio_r8(s->pb); +int data_count = avio_r8(s->pb); +av_log(s, AV_LOG_DEBUG, "did %x sdid %x count %d\n", did, sdid, data_count); +if (did != 0x61) +break; +int cdp_id = avio_rb16(s->pb); +int cdp_data_count = avio_r8(s->pb); +int cdp_framing_rate = avio_r8(s->pb) >> 4; +int cdp_flags = avio_r8(s->pb); +int cdp_counter = avio_rb16(s->pb); +int cdp_data_section = avio_r8(s->pb); +if (cdp_data_section != 0x72) { +av_log(s, AV_LOG_ERROR, "wrong cdp data section %x\n", cdp_data_section); +return AVERROR_INVALIDDATA; +} +int flags = avio_r8(s->pb); +int cc_count = flags & 0x1f; +av_log(s, AV_LOG_DEBUG, "cdp id %x dcount %d frame rate %d cdp flags %x flags %x " + "cc count %d counter %d section %x\n", cdp_id, cdp_data_count, cdp_framing_rate, + cdp_flags, flags, cc_count, cdp_counter, cdp_data_section); +ret = av_get_packet(s->pb, pkt, cc_count * 3); +if (ret < 0) +return ret; +if (cdp_data_count - 9 - 4 < cc_count * 3) { +av_log(s, AV_LOG_ERROR, "wrong cdp size %d cc count %d\n", data_count, cc_count); +return AVERROR_INVALIDDATA; +} +avio_skip(s->pb, data_count - 9 - 4 - cc_count * 3); +int cdp_footer_section = avio_r8(s->pb); +if (cdp_footer_section != 0x74) { +av_log(s, AV_LOG_ERROR, "wrong cdp footer section %x\n", cdp_footer_section); +return AVERROR_INVALIDDATA; +} +int cdp_counter2 = avio_rb16(s->pb); +int cdp_checksum = avio_r8(s->pb); +av_log(s, AV_LOG_DEBUG, "cdp counter %d checksum %x\n", cdp_counter2, cdp_checksum); +break; +} + +return 0; +} + /* XXX: use AVBitStreamFilter */ static int mxf_get_d10_aes3_packet(AVIOContext *pb, AVStream *st, AVPacket *pkt, int64_t length) { @@ -2415,6 +2491,11 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) st->codecpar->codec_type = type; if (container_ul->desc) av_dict_set(&st->metadata, "data_type", container_ul->desc, 0); +if (mxf->eia608_extract && +!strcmp(container_ul->desc, "vbi_vanc_smpte_436M")) { +st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE; +st->codecpar->codec_id = AV_CODEC_ID_EIA_608; +} } if