From patchwork Wed Jul 4 18:35:12 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baptiste Coudurier X-Patchwork-Id: 9614 Delivered-To: ffmpegpatchwork@gmail.com Received: by 2002:a02:104:0:0:0:0:0 with SMTP id c4-v6csp1079286jad; Wed, 4 Jul 2018 11:36:35 -0700 (PDT) X-Google-Smtp-Source: AAOMgpcLIChou4a9OzVKKw4qnFBU0V7WwmwbFQl4xMsxmkce75x/V7nXJYUEIfrtXp48+O7CJ9U6 X-Received: by 2002:a1c:7c0c:: with SMTP id x12-v6mr2325955wmc.58.1530729395060; Wed, 04 Jul 2018 11:36:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1530729395; cv=none; d=google.com; s=arc-20160816; b=rdA/8VPaoEKGSv5F7nIuy+IkSmpuWPUfBJPgb5iRA5Tps6VSOLeoiP412CcbJE//W+ vz7pv/y2bAsH6/ZScEXtlAesoSMxkKwTb+KpKbQp3G6dwN2CPk5+4V79ruOgtNvKRT+g 8CQ8gRP/0PnmRCg8G78NCDxj2qEfkO5/lVyhdDBRFAND/A2L+VeWn0iSysQJxJxgSxZQ gYvhW9FnGHk77rCEKdtHuopFIWto00aAGZU5SAbCatz0fRQOpKIYm9iVqCDgwbJm69rK LZ8J21ZoRB/2V0CwlADsPaYPk2urYlzNI/XYFScINh6mxCQO5y1VTEPerweV9X8j0bDJ D7Cg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:message-id:date:to:from:dkim-signature :delivered-to:arc-authentication-results; bh=wCl9tofMWE8bovAnEJOkgAQSDmUp4qtzimgud/hcnPo=; b=oy7U7+/qKTN48wBCwTQg0FxHk2AKN9hEOFDgjUbyt1aFEFc1tmRLwjK3cNo/9vIC3R DFdEBVI8ac72/5BeWkURpD14AIhTCMsC6Igz6w1q/c6+OYgCDvYcluRvuvBB1oRGcH00 TABApW0hfPxkga9iBJE5fH6kZsGCziRivLSuDX2Xt3nQH+7SnfxGE/DLPqy5jLwhbTrA HmjoF1SDTdulRTu/lkDqAv93LezaaRwv/GTQGJ7qXyQqBZ01uHAYcjQvQAeX091P3p+P Pf67h0wie7qzMyVw4rz+ctu79aWAAxCqwU7cvbAtGKx4QZbyY6mZTEIAVLLko0YZE4ob oHWQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=lvokq8ZB; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id r6-v6si3665244wro.401.2018.07.04.11.36.34; Wed, 04 Jul 2018 11:36:34 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=lvokq8ZB; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id EF45468AB4E; Wed, 4 Jul 2018 21:35:28 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pf0-f171.google.com (mail-pf0-f171.google.com [209.85.192.171]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C0B4968AB09 for ; Wed, 4 Jul 2018 21:35:21 +0300 (EEST) Received: by mail-pf0-f171.google.com with SMTP id u16-v6so3256629pfh.3 for ; Wed, 04 Jul 2018 11:35:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id; bh=V7PbkyonUpLv+ghx83ca3mhRKT/3uOX7PUUNkn7PKjA=; b=lvokq8ZBLxt0eXzkSb7CmLw8vtCQp/nOUbKVVWPuMM/lpKRPB5GDBU/qa9XaDV28Y9 XOMgWY/h1Uu6KEBlu23+qCiU5xFUfgitc2btNcGuf+WHaLTip5F6zM+sgy1KEc9xaDxs 1Sd2U7RnCfU6CUMhbMs22IZSF8PfMKI/m43C4uMp4iS5tNqI11j6B0JNa9qX8u0Cbucw Q9Dx68KSc/lVnhbCjJIzNlU3Hf4J362JxoBELKyqDdMDMvsVUM1HiyUVgKbIWP+z7uWS 40/glZKOSrYUV7CHbuNxSivgdCANjPPFuvzYlvlagss7pjVpotM3ehQCzWbcNwyfGF4r AtfQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id; bh=V7PbkyonUpLv+ghx83ca3mhRKT/3uOX7PUUNkn7PKjA=; b=QvC/0z8uILhINaRoJkaNapk0ZIQRLvXbU/1khnzX1yeBnUOQPH6hjVaSdENXscS1lM fs1d1ZkhZ+Au/pbtcHgNnquc17CxutHFOtCu0dgER9Hpk8NZyHazBj6oAm3abGAcnxDj N4OK/vLqVV6g5IfwU9gM4o05huFWrmGyPJfqmJBYbikmvEkie3pvBPPdUcIPgrPdy7B+ D22bfMmmgQWPM1couLyqV9IAny+/CL7e/ReUpKqQqLopjNUlIuNwjsRpTA6oQmjKUtlr JaJ6px48D+rqV1uoj7M9jRB+gX7kD0Siu7Csv99StXJgYHlmsaSUHnAFEP/BCQHbG+ym tpfw== X-Gm-Message-State: APt69E2d4vMBiv59jAj+HWavglHj8wJg6GxBuLIhGP+OlP4P2aKxMBqr uiBnr3S/u8eMxu9f/K0B0g7fcA== X-Received: by 2002:a63:3c4a:: with SMTP id i10-v6mr2815975pgn.415.1530729324640; Wed, 04 Jul 2018 11:35:24 -0700 (PDT) Received: from localhost.localdomain (cpe-104-173-251-254.socal.res.rr.com. [104.173.251.254]) by smtp.gmail.com with ESMTPSA id v126-v6sm8591239pgv.39.2018.07.04.11.35.23 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 04 Jul 2018 11:35:24 -0700 (PDT) From: Baptiste Coudurier To: ffmpeg-devel@ffmpeg.org Date: Wed, 4 Jul 2018 11:35:12 -0700 Message-Id: <20180704183514.71654-10-baptiste.coudurier@gmail.com> X-Mailer: git-send-email 2.17.0 (Apple Git-106) Subject: [FFmpeg-devel] [PATCH 10/12] lavf/mxfdec: demux s436m as eia608 subtitle track X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" --- 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 (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; } else { ret = av_get_packet(s->pb, pkt, klv.length); if (ret < 0) @@ -3596,6 +3682,21 @@ static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti return 0; } +static const AVOption options[] = { + { "eia608_extract", "extract eia 608 captions from s436m track", + offsetof(MXFContext, eia608_extract), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, + AV_OPT_FLAG_DECODING_PARAM }, + { NULL }, +}; + +static const AVClass demuxer_class = { + .class_name = "mxf", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, + .category = AV_CLASS_CATEGORY_DEMUXER, +}; + AVInputFormat ff_mxf_demuxer = { .name = "mxf", .long_name = NULL_IF_CONFIG_SMALL("MXF (Material eXchange Format)"), @@ -3606,4 +3707,5 @@ AVInputFormat ff_mxf_demuxer = { .read_packet = mxf_read_packet, .read_close = mxf_read_close, .read_seek = mxf_read_seek, + .priv_class = &demuxer_class, };