Re: [FFmpeg-devel] [PATCH] mpegts: identify and demux DSMCC-B/MHEG streams

2022-11-28 Thread Scott Theisen

Ping for review.

Thanks in advance,

Scott Theisen

On 11/13/22 18:19, Scott Theisen wrote:

Ping for review.

On 9/17/22 13:08, Scott Theisen wrote:

These changes are from MythTV.
---

The `AV_CODEC_ID`s are probably in the wrong place since these are
data codecs, but that is where they are In MythTV.

There was also a related change to libavformat/demux.c's
avformat_find_stream_info() trying to optimize it for MHEG streams,
but it is unnecessary and was causing FATE to fail.

  libavcodec/codec_desc.c |  12 +++
  libavcodec/codec_id.h   |   6 ++
  libavformat/avformat.h  |   5 +
  libavformat/mpegts.c    | 199 +++-
  libavformat/mpegts.h    |  17 
  5 files changed, 237 insertions(+), 2 deletions(-)

diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 648c518b3c..0e54087863 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -3488,6 +3488,18 @@ static const AVCodecDescriptor 
codec_descriptors[] = {

  .props = AV_CODEC_PROP_TEXT_SUB,
  .profiles  = NULL_IF_CONFIG_SMALL(ff_arib_caption_profiles),
  },
+    {
+    .id    = AV_CODEC_ID_DVB_VBI,
+    .type  = AVMEDIA_TYPE_DATA,
+    .name  = "dvb_vbi",
+    .long_name = NULL_IF_CONFIG_SMALL("dvb teletext"),
+    },
+    {
+    .id    = AV_CODEC_ID_DSMCC_B,
+    .type  = AVMEDIA_TYPE_DATA,
+    .name  = "dsmcc_b",
+    .long_name = NULL_IF_CONFIG_SMALL("DSMCC B"),
+    },
    /* other kind of codecs and pseudo-codecs */
  {
diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h
index bc8226ff07..7e2198a800 100644
--- a/libavcodec/codec_id.h
+++ b/libavcodec/codec_id.h
@@ -559,6 +559,12 @@ enum AVCodecID {
  AV_CODEC_ID_TTML,
  AV_CODEC_ID_ARIB_CAPTION,
  +    /* teletext codecs */
+    AV_CODEC_ID_DVB_VBI,
+
+    /* DSMCC codec */
+    AV_CODEC_ID_DSMCC_B,
+
  /* other specific kind of codecs (generally used for 
attachments) */
  AV_CODEC_ID_FIRST_UNKNOWN = 0x18000,   ///< A dummy ID 
pointing at the start of various fake codecs.

  AV_CODEC_ID_TTF = 0x18000,
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 9d46875cce..664a1afa61 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1117,6 +1117,11 @@ typedef struct AVStream {
   *
   */
  int pts_wrap_bits;
+
+    /* MHEG support */
+    int component_tag; ///< Component tag given in PMT
+    int carousel_id;
+    int data_id;
  } AVStream;
    struct AVCodecParserContext *av_stream_get_parser(const AVStream 
*s);

diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 8a3436f2be..be8edd9e62 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -46,6 +46,15 @@
  #include 
  #endif
  +typedef struct SectionContext {
+    int pid;
+    int stream_type;
+    int new_packet;
+    MpegTSContext *ts;
+    AVFormatContext *stream;
+    AVStream *st;
+} SectionContext;
+
  /* maximum size in which we look for synchronization if
   * synchronization is lost */
  #define MAX_RESYNC_SIZE 65536
@@ -412,6 +421,8 @@ static int discard_pid(MpegTSContext *ts, 
unsigned int pid)

  return !used && discarded;
  }
  +static void mpegts_push_section(MpegTSFilter *filter, const 
uint8_t *section, int section_len);

+
  /**
   *  Assemble PES packets out of TS packets, and then call the 
"section_cb"

   *  function when they are complete.
@@ -438,6 +449,11 @@ static void write_section_data(MpegTSContext 
*ts, MpegTSFilter *tss1,

  tss->section_index += len;
  }
  +    if (tss->section_cb == mpegts_push_section) {
+    SectionContext *sect = tss->opaque;
+    sect->new_packet = 1;
+    }
+
  offset = 0;
  cur_section_buf = tss->section_buf;
  while (cur_section_buf - tss->section_buf < MAX_SECTION_SIZE && 
cur_section_buf[0] != 0xff) {

@@ -798,6 +814,7 @@ static const StreamType ISO_types[] = {
  { 0x02, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG2VIDEO },
  { 0x03, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_MP3    },
  { 0x04, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_MP3    },
+    { 0x0b, AVMEDIA_TYPE_DATA,  AV_CODEC_ID_DSMCC_B    }, /* 
DVB_CAROUSEL_ID */

  { 0x0f, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AAC    },
  { 0x10, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG4  },
  /* Makito encoder sets stream type 0x11 for AAC,
@@ -882,11 +899,20 @@ static const StreamType DESC_types[] = {
  { 0x6a, AVMEDIA_TYPE_AUDIO,    AV_CODEC_ID_AC3  }, /* 
AC-3 descriptor */
  { 0x7a, AVMEDIA_TYPE_AUDIO,    AV_CODEC_ID_EAC3 }, /* 
E-AC-3 descriptor */

  { 0x7b, AVMEDIA_TYPE_AUDIO,    AV_CODEC_ID_DTS  },
+    { 0x13, AVMEDIA_TYPE_DATA, AV_CODEC_ID_DSMCC_B  }, /* 
DVB_CAROUSEL_ID */
+    { 0x45, AVMEDIA_TYPE_DATA, AV_CODEC_ID_DVB_VBI  }, /* 
DVB_VBI_DATA_ID */
+    { 0x46, AVMEDIA_TYPE_DATA, AV_CODEC_ID_DVB_VBI  }, /* 
DVB_VBI_TELETEXT_ID */ //FixMe type subtilte

  { 0x56, 

Re: [FFmpeg-devel] [PATCH] mpegts: identify and demux DSMCC-B/MHEG streams

2022-11-13 Thread Scott Theisen

Ping for review.

On 9/17/22 13:08, Scott Theisen wrote:

These changes are from MythTV.
---

The `AV_CODEC_ID`s are probably in the wrong place since these are
data codecs, but that is where they are In MythTV.

There was also a related change to libavformat/demux.c's
avformat_find_stream_info() trying to optimize it for MHEG streams,
but it is unnecessary and was causing FATE to fail.

  libavcodec/codec_desc.c |  12 +++
  libavcodec/codec_id.h   |   6 ++
  libavformat/avformat.h  |   5 +
  libavformat/mpegts.c| 199 +++-
  libavformat/mpegts.h|  17 
  5 files changed, 237 insertions(+), 2 deletions(-)

diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 648c518b3c..0e54087863 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -3488,6 +3488,18 @@ static const AVCodecDescriptor codec_descriptors[] = {
  .props = AV_CODEC_PROP_TEXT_SUB,
  .profiles  = NULL_IF_CONFIG_SMALL(ff_arib_caption_profiles),
  },
+{
+.id= AV_CODEC_ID_DVB_VBI,
+.type  = AVMEDIA_TYPE_DATA,
+.name  = "dvb_vbi",
+.long_name = NULL_IF_CONFIG_SMALL("dvb teletext"),
+},
+{
+.id= AV_CODEC_ID_DSMCC_B,
+.type  = AVMEDIA_TYPE_DATA,
+.name  = "dsmcc_b",
+.long_name = NULL_IF_CONFIG_SMALL("DSMCC B"),
+},
  
  /* other kind of codecs and pseudo-codecs */

  {
diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h
index bc8226ff07..7e2198a800 100644
--- a/libavcodec/codec_id.h
+++ b/libavcodec/codec_id.h
@@ -559,6 +559,12 @@ enum AVCodecID {
  AV_CODEC_ID_TTML,
  AV_CODEC_ID_ARIB_CAPTION,
  
+/* teletext codecs */

+AV_CODEC_ID_DVB_VBI,
+
+/* DSMCC codec */
+AV_CODEC_ID_DSMCC_B,
+
  /* other specific kind of codecs (generally used for attachments) */
  AV_CODEC_ID_FIRST_UNKNOWN = 0x18000,   ///< A dummy ID pointing 
at the start of various fake codecs.
  AV_CODEC_ID_TTF = 0x18000,
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 9d46875cce..664a1afa61 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1117,6 +1117,11 @@ typedef struct AVStream {
   *
   */
  int pts_wrap_bits;
+
+/* MHEG support */
+int component_tag; ///< Component tag given in PMT
+int carousel_id;
+int data_id;
  } AVStream;
  
  struct AVCodecParserContext *av_stream_get_parser(const AVStream *s);

diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 8a3436f2be..be8edd9e62 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -46,6 +46,15 @@
  #include 
  #endif
  
+typedef struct SectionContext {

+int pid;
+int stream_type;
+int new_packet;
+MpegTSContext *ts;
+AVFormatContext *stream;
+AVStream *st;
+} SectionContext;
+
  /* maximum size in which we look for synchronization if
   * synchronization is lost */
  #define MAX_RESYNC_SIZE 65536
@@ -412,6 +421,8 @@ static int discard_pid(MpegTSContext *ts, unsigned int pid)
  return !used && discarded;
  }
  
+static void mpegts_push_section(MpegTSFilter *filter, const uint8_t *section, int section_len);

+
  /**
   *  Assemble PES packets out of TS packets, and then call the "section_cb"
   *  function when they are complete.
@@ -438,6 +449,11 @@ static void write_section_data(MpegTSContext *ts, 
MpegTSFilter *tss1,
  tss->section_index += len;
  }
  
+if (tss->section_cb == mpegts_push_section) {

+SectionContext *sect = tss->opaque;
+sect->new_packet = 1;
+}
+
  offset = 0;
  cur_section_buf = tss->section_buf;
  while (cur_section_buf - tss->section_buf < MAX_SECTION_SIZE && 
cur_section_buf[0] != 0xff) {
@@ -798,6 +814,7 @@ static const StreamType ISO_types[] = {
  { 0x02, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG2VIDEO },
  { 0x03, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_MP3},
  { 0x04, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_MP3},
+{ 0x0b, AVMEDIA_TYPE_DATA,  AV_CODEC_ID_DSMCC_B}, /* DVB_CAROUSEL_ID */
  { 0x0f, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AAC},
  { 0x10, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG4  },
  /* Makito encoder sets stream type 0x11 for AAC,
@@ -882,11 +899,20 @@ static const StreamType DESC_types[] = {
  { 0x6a, AVMEDIA_TYPE_AUDIO,AV_CODEC_ID_AC3  }, /* AC-3 
descriptor */
  { 0x7a, AVMEDIA_TYPE_AUDIO,AV_CODEC_ID_EAC3 }, /* E-AC-3 
descriptor */
  { 0x7b, AVMEDIA_TYPE_AUDIO,AV_CODEC_ID_DTS  },
+{ 0x13, AVMEDIA_TYPE_DATA, AV_CODEC_ID_DSMCC_B  }, /* 
DVB_CAROUSEL_ID */
+{ 0x45, AVMEDIA_TYPE_DATA, AV_CODEC_ID_DVB_VBI  }, /* 
DVB_VBI_DATA_ID */
+{ 0x46, AVMEDIA_TYPE_DATA, AV_CODEC_ID_DVB_VBI  }, /* 
DVB_VBI_TELETEXT_ID */ //FixMe type subtilte
  { 0x56, AVMEDIA_TYPE_SUBTITLE, AV_CODEC_ID_DVB_TELETEXT },
  { 0x59, AVMEDIA_TYPE_SUBTITLE, AV_CODEC_ID_DVB_SUBTITLE 

[FFmpeg-devel] [PATCH] mpegts: identify and demux DSMCC-B/MHEG streams

2022-09-17 Thread Scott Theisen
These changes are from MythTV.
---

The `AV_CODEC_ID`s are probably in the wrong place since these are
data codecs, but that is where they are In MythTV.

There was also a related change to libavformat/demux.c's
avformat_find_stream_info() trying to optimize it for MHEG streams,
but it is unnecessary and was causing FATE to fail.

 libavcodec/codec_desc.c |  12 +++
 libavcodec/codec_id.h   |   6 ++
 libavformat/avformat.h  |   5 +
 libavformat/mpegts.c| 199 +++-
 libavformat/mpegts.h|  17 
 5 files changed, 237 insertions(+), 2 deletions(-)

diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 648c518b3c..0e54087863 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -3488,6 +3488,18 @@ static const AVCodecDescriptor codec_descriptors[] = {
 .props = AV_CODEC_PROP_TEXT_SUB,
 .profiles  = NULL_IF_CONFIG_SMALL(ff_arib_caption_profiles),
 },
+{
+.id= AV_CODEC_ID_DVB_VBI,
+.type  = AVMEDIA_TYPE_DATA,
+.name  = "dvb_vbi",
+.long_name = NULL_IF_CONFIG_SMALL("dvb teletext"),
+},
+{
+.id= AV_CODEC_ID_DSMCC_B,
+.type  = AVMEDIA_TYPE_DATA,
+.name  = "dsmcc_b",
+.long_name = NULL_IF_CONFIG_SMALL("DSMCC B"),
+},
 
 /* other kind of codecs and pseudo-codecs */
 {
diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h
index bc8226ff07..7e2198a800 100644
--- a/libavcodec/codec_id.h
+++ b/libavcodec/codec_id.h
@@ -559,6 +559,12 @@ enum AVCodecID {
 AV_CODEC_ID_TTML,
 AV_CODEC_ID_ARIB_CAPTION,
 
+/* teletext codecs */
+AV_CODEC_ID_DVB_VBI,
+
+/* DSMCC codec */
+AV_CODEC_ID_DSMCC_B,
+
 /* other specific kind of codecs (generally used for attachments) */
 AV_CODEC_ID_FIRST_UNKNOWN = 0x18000,   ///< A dummy ID pointing at 
the start of various fake codecs.
 AV_CODEC_ID_TTF = 0x18000,
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 9d46875cce..664a1afa61 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1117,6 +1117,11 @@ typedef struct AVStream {
  *
  */
 int pts_wrap_bits;
+
+/* MHEG support */
+int component_tag; ///< Component tag given in PMT
+int carousel_id;
+int data_id;
 } AVStream;
 
 struct AVCodecParserContext *av_stream_get_parser(const AVStream *s);
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 8a3436f2be..be8edd9e62 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -46,6 +46,15 @@
 #include 
 #endif
 
+typedef struct SectionContext {
+int pid;
+int stream_type;
+int new_packet;
+MpegTSContext *ts;
+AVFormatContext *stream;
+AVStream *st;
+} SectionContext;
+
 /* maximum size in which we look for synchronization if
  * synchronization is lost */
 #define MAX_RESYNC_SIZE 65536
@@ -412,6 +421,8 @@ static int discard_pid(MpegTSContext *ts, unsigned int pid)
 return !used && discarded;
 }
 
+static void mpegts_push_section(MpegTSFilter *filter, const uint8_t *section, 
int section_len);
+
 /**
  *  Assemble PES packets out of TS packets, and then call the "section_cb"
  *  function when they are complete.
@@ -438,6 +449,11 @@ static void write_section_data(MpegTSContext *ts, 
MpegTSFilter *tss1,
 tss->section_index += len;
 }
 
+if (tss->section_cb == mpegts_push_section) {
+SectionContext *sect = tss->opaque;
+sect->new_packet = 1;
+}
+
 offset = 0;
 cur_section_buf = tss->section_buf;
 while (cur_section_buf - tss->section_buf < MAX_SECTION_SIZE && 
cur_section_buf[0] != 0xff) {
@@ -798,6 +814,7 @@ static const StreamType ISO_types[] = {
 { 0x02, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG2VIDEO },
 { 0x03, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_MP3},
 { 0x04, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_MP3},
+{ 0x0b, AVMEDIA_TYPE_DATA,  AV_CODEC_ID_DSMCC_B}, /* DVB_CAROUSEL_ID */
 { 0x0f, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AAC},
 { 0x10, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG4  },
 /* Makito encoder sets stream type 0x11 for AAC,
@@ -882,11 +899,20 @@ static const StreamType DESC_types[] = {
 { 0x6a, AVMEDIA_TYPE_AUDIO,AV_CODEC_ID_AC3  }, /* AC-3 
descriptor */
 { 0x7a, AVMEDIA_TYPE_AUDIO,AV_CODEC_ID_EAC3 }, /* E-AC-3 
descriptor */
 { 0x7b, AVMEDIA_TYPE_AUDIO,AV_CODEC_ID_DTS  },
+{ 0x13, AVMEDIA_TYPE_DATA, AV_CODEC_ID_DSMCC_B  }, /* 
DVB_CAROUSEL_ID */
+{ 0x45, AVMEDIA_TYPE_DATA, AV_CODEC_ID_DVB_VBI  }, /* 
DVB_VBI_DATA_ID */
+{ 0x46, AVMEDIA_TYPE_DATA, AV_CODEC_ID_DVB_VBI  }, /* 
DVB_VBI_TELETEXT_ID */ //FixMe type subtilte
 { 0x56, AVMEDIA_TYPE_SUBTITLE, AV_CODEC_ID_DVB_TELETEXT },
 { 0x59, AVMEDIA_TYPE_SUBTITLE, AV_CODEC_ID_DVB_SUBTITLE }, /* subtitling 
descriptor */
 { 0 },
 };
 
+/* component tags */
+static const StreamType