[FFmpeg-devel] [PATCH 10/12] lavf/mxfdec: demux s436m as eia608 subtitle track
Marton Balint
cus at passwd.hu
Wed Jul 4 23:50:19 EEST 2018
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->codec_type = AVMEDIA_TYPE_SUBTITLE;
> + st->codecpar->codec_id = AV_CODEC_ID_EIA_608;
> + }
> }
> if (descriptor->extradata) {
> if (!ff_alloc_extradata(st->codecpar, descriptor->extradata_size)) {
> @@ -3356,6 +3437,11 @@ static int mxf_read_packet_old(AVFormatContext *s, AVPacket *pkt)
> av_log(s, AV_LOG_ERROR, "error reading D-10 aes3 frame\n");
> return ret;
> }
> + } else if (mxf->eia608_extract &&
> + s->streams[index]->codecpar->codec_id == AV_CODEC_ID_EIA_608) {
> + ret = mxf_get_eia608_packet(s, s->streams[index], pkt, klv.length);
> + if (ret < 0)
> + return ret;
After my clip wrapped patches this probably needs to be:
if (ret < 0) {
mxf->current_klv_data = (KLVPacket){{0}};
return ret;
}
Thanks,
Marton
More information about the ffmpeg-devel
mailing list