Re: [FFmpeg-devel] [PATCH 10/12] lavf/mxfdec: demux s436m as eia608 subtitle track

2018-10-12 Thread Baptiste Coudurier
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

2018-07-04 Thread Marton Balint



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

2018-07-04 Thread Baptiste Coudurier
---
 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