diff mbox series

[FFmpeg-devel] avformat/mpegts: set data broadcast streams as such

Message ID 20220404095312.21140-1-jeebjp@gmail.com
State New
Headers show
Series [FFmpeg-devel] avformat/mpegts: set data broadcast streams as such | expand

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 fail Make fate failed
andriy/make_aarch64_jetson success Make finished
andriy/make_fate_aarch64_jetson fail Make fate failed
andriy/make_armv7_RPi4 success Make finished
andriy/make_fate_armv7_RPi4 fail Make fate failed

Commit Message

Jan Ekström April 4, 2022, 9:53 a.m. UTC
From: Jan Ekström <jan.ekstrom@24i.com>

Additionally, they should not be probed, as this is essentially
various types of binary data.

Signed-off-by: Jan Ekström <jan.ekstrom@24i.com>
---
 libavformat/mpegts.c                        | 48 +++++++++++++++++++++
 tests/fate/mpegts.mak                       |  3 ++
 tests/ref/fate/mpegts-probe-sdt-data-stream | 14 ++++++
 3 files changed, 65 insertions(+)
 create mode 100644 tests/ref/fate/mpegts-probe-sdt-data-stream

Comments

Jan Ekström April 4, 2022, 9:56 a.m. UTC | #1
On Mon, Apr 4, 2022 at 12:53 PM Jan Ekström <jeebjp@gmail.com> wrote:
>
> From: Jan Ekström <jan.ekstrom@24i.com>
>
> Additionally, they should not be probed, as this is essentially
> various types of binary data.
>
> Signed-off-by: Jan Ekström <jan.ekstrom@24i.com>
> ---

The test file referenced with this sort of signaling is available at:

https://megumin.fushizen.eu/samples/2022-02-04-radio_with_data_stream/mpegts_sdt_data_stream.ts

Jan
TADANO Tokumei April 4, 2022, 4:04 p.m. UTC | #2
As I posted a patch on Apr. 3rd, you should use "desc_end" rather than "p_end"
for get16() or get8() to parse each descriptor.

On 2022/04/04 18:53, Jan Ekström wrote:
> From: Jan Ekström <jan.ekstrom@24i.com>
> 
> Additionally, they should not be probed, as this is essentially
> various types of binary data.
> 
> Signed-off-by: Jan Ekström <jan.ekstrom@24i.com>
> ---
>   libavformat/mpegts.c                        | 48 +++++++++++++++++++++
>   tests/fate/mpegts.mak                       |  3 ++
>   tests/ref/fate/mpegts-probe-sdt-data-stream | 14 ++++++
>   3 files changed, 65 insertions(+)
>   create mode 100644 tests/ref/fate/mpegts-probe-sdt-data-stream
> 
> diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
> index da77b50669..3788faf848 100644
> --- a/libavformat/mpegts.c
> +++ b/libavformat/mpegts.c
> @@ -2512,6 +2512,13 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
>               }
>           }
>           p = desc_list_end;
> +
> +        if (!ts->pkt && (stream_type >= 0x80 && stream_type <= 0xFF) &&
> +            st->codecpar->codec_id == AV_CODEC_ID_NONE)
> +            // if we are reading headers, and still have a user private stream
> +            // with no proper codec set, do not stop reading at PMT. Data
> +            // streams are marked within SDT.
> +            ts->stop_parse = 0;
>       }
>   
>       if (!ts->pids[pcr_pid])
> @@ -2691,6 +2698,7 @@ static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
>       if (val < 0)
>           return;
>       for (;;) {
> +        struct Program *program = NULL;
>           sid = get16(&p, p_end);
>           if (sid < 0)
>               break;
> @@ -2704,6 +2712,15 @@ static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
>           desc_list_end  = p + desc_list_len;
>           if (desc_list_end > p_end)
>               break;
> +
> +        program = get_program(ts, sid);
> +
> +        if (!ts->pkt && program && program->pmt_found)
> +            // if during header reading we have already received a PMT for
> +            // this program and now have received an SDT for it, stop further
> +            // reading at this point.
> +            ts->stop_parse = 2;
> +
>           for (;;) {
>               desc_tag = get8(&p, desc_list_end);
>               if (desc_tag < 0)
> @@ -2736,6 +2753,37 @@ static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
>                   av_free(name);
>                   av_free(provider_name);
>                   break;
> +            case 0x64: /* ETSI data broadcast descriptor; EN 300 468 6.2.11 */
> +                {
> +                    AVStream *st  = NULL;
> +                    FFStream *sti = NULL;
> +
> +                    uint16_t data_broadcast_id = get16(&p, p_end); // TS 101 162

s/p_end/desc_end/

> +                    uint8_t  component_tag     = get8(&p, p_end);

s/p_end/desc_end/

> +                    if (!component_tag)
> +                        // no stream mapping according to component_tag
> +                        break;
> +
> +                    av_log(ts->stream, AV_LOG_TRACE,
> +                           "data broadcast id: %d, component tag: %d\n",
> +                           data_broadcast_id, component_tag);
> +
> +                    if (!program)
> +                        break;
> +
> +                    st = find_matching_stream(ts, 0, sid, component_tag + 1, 0,
> +                                              program);
> +                    if (!st)
> +                        break;
> +
> +                    sti = ffstream(st);
> +
> +                    st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
> +                    st->codecpar->codec_id   = AV_CODEC_ID_BIN_DATA;
> +                    sti->request_probe = sti->need_parsing = 0;
> +                    sti->need_context_update = 1;
> +                    break;
> +                }
>               default:
>                   break;
>               }
> diff --git a/tests/fate/mpegts.mak b/tests/fate/mpegts.mak
> index bbcbfc47b2..ae21ee87d0 100644
> --- a/tests/fate/mpegts.mak
> +++ b/tests/fate/mpegts.mak
> @@ -19,6 +19,9 @@ FATE_MPEGTS_PROBE-$(call DEMDEC, MPEGTS) += fate-mpegts-probe-pmt-merge
>   fate-mpegts-probe-pmt-merge: SRC = $(TARGET_SAMPLES)/mpegts/pmtchange.ts
>   fate-mpegts-probe-pmt-merge: CMD = run $(PROBE_CODEC_NAME_COMMAND) -merge_pmt_versions 1 -i "$(SRC)"
>   
> +FATE_MPEGTS_PROBE-$(call DEMDEC, MPEGTS, MP2) += fate-mpegts-probe-sdt-data-stream
> +fate-mpegts-probe-sdt-data-stream: SRC = $(TARGET_SAMPLES)/mpegts/mpegts_sdt_data_stream.ts
> +fate-mpegts-probe-sdt-data-stream: CMD = run $(PROBE_CODEC_NAME_COMMAND) -i "$(SRC)"
>   
>   FATE_SAMPLES_FFPROBE += $(FATE_MPEGTS_PROBE-yes)
>   
> diff --git a/tests/ref/fate/mpegts-probe-sdt-data-stream b/tests/ref/fate/mpegts-probe-sdt-data-stream
> new file mode 100644
> index 0000000000..0b8e90962f
> --- /dev/null
> +++ b/tests/ref/fate/mpegts-probe-sdt-data-stream
> @@ -0,0 +1,14 @@
> +[PROGRAM]
> +[STREAM]
> +codec_name=mp2
> +[/STREAM]
> +[STREAM]
> +codec_name=bin_data
> +[/STREAM]
> +[/PROGRAM]
> +[STREAM]
> +codec_name=mp2
> +[/STREAM]
> +[STREAM]
> +codec_name=bin_data
> +[/STREAM]
TADANO Tokumei April 4, 2022, 4:16 p.m. UTC | #3
... and, it is better to check broken packet.

On 2022/04/05 1:04, TADANO Tokumei wrote:
> As I posted a patch on Apr. 3rd, you should use "desc_end" rather than "p_end"
> for get16() or get8() to parse each descriptor.
> 
> On 2022/04/04 18:53, Jan Ekström wrote:
>> From: Jan Ekström <jan.ekstrom@24i.com>
>>
>> Additionally, they should not be probed, as this is essentially
>> various types of binary data.
>>
>> Signed-off-by: Jan Ekström <jan.ekstrom@24i.com>
>> ---
>>   libavformat/mpegts.c                        | 48 +++++++++++++++++++++
>>   tests/fate/mpegts.mak                       |  3 ++
>>   tests/ref/fate/mpegts-probe-sdt-data-stream | 14 ++++++
>>   3 files changed, 65 insertions(+)
>>   create mode 100644 tests/ref/fate/mpegts-probe-sdt-data-stream
>>
>> diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
>> index da77b50669..3788faf848 100644
>> --- a/libavformat/mpegts.c
>> +++ b/libavformat/mpegts.c
>> @@ -2512,6 +2512,13 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
>>               }
>>           }
>>           p = desc_list_end;
>> +
>> +        if (!ts->pkt && (stream_type >= 0x80 && stream_type <= 0xFF) &&
>> +            st->codecpar->codec_id == AV_CODEC_ID_NONE)
>> +            // if we are reading headers, and still have a user private stream
>> +            // with no proper codec set, do not stop reading at PMT. Data
>> +            // streams are marked within SDT.
>> +            ts->stop_parse = 0;
>>       }
>>       if (!ts->pids[pcr_pid])
>> @@ -2691,6 +2698,7 @@ static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
>>       if (val < 0)
>>           return;
>>       for (;;) {
>> +        struct Program *program = NULL;
>>           sid = get16(&p, p_end);
>>           if (sid < 0)
>>               break;
>> @@ -2704,6 +2712,15 @@ static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
>>           desc_list_end  = p + desc_list_len;
>>           if (desc_list_end > p_end)
>>               break;
>> +
>> +        program = get_program(ts, sid);
>> +
>> +        if (!ts->pkt && program && program->pmt_found)
>> +            // if during header reading we have already received a PMT for
>> +            // this program and now have received an SDT for it, stop further
>> +            // reading at this point.
>> +            ts->stop_parse = 2;
>> +
>>           for (;;) {
>>               desc_tag = get8(&p, desc_list_end);
>>               if (desc_tag < 0)
>> @@ -2736,6 +2753,37 @@ static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
>>                   av_free(name);
>>                   av_free(provider_name);
>>                   break;
>> +            case 0x64: /* ETSI data broadcast descriptor; EN 300 468 6.2.11 */
>> +                {
>> +                    AVStream *st  = NULL;
>> +                    FFStream *sti = NULL;
>> +
>> +                    uint16_t data_broadcast_id = get16(&p, p_end); // TS 101 162
> 
> s/p_end/desc_end/
                         if (data_broadcast_id < 0)
                             break;

> 
>> +                    uint8_t  component_tag     = get8(&p, p_end);
> 
> s/p_end/desc_end/
> 
>> +                    if (!component_tag)
                         if (component_tag <= 0)

>> +                        // no stream mapping according to component_tag
>> +                        break;
>> +
>> +                    av_log(ts->stream, AV_LOG_TRACE,
>> +                           "data broadcast id: %d, component tag: %d\n",
>> +                           data_broadcast_id, component_tag);
>> +
>> +                    if (!program)
>> +                        break;
>> +
>> +                    st = find_matching_stream(ts, 0, sid, component_tag + 1, 0,
>> +                                              program);
>> +                    if (!st)
>> +                        break;
>> +
>> +                    sti = ffstream(st);
>> +
>> +                    st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
>> +                    st->codecpar->codec_id   = AV_CODEC_ID_BIN_DATA;
>> +                    sti->request_probe = sti->need_parsing = 0;
>> +                    sti->need_context_update = 1;
>> +                    break;
>> +                }
>>               default:
>>                   break;
>>               }
>> diff --git a/tests/fate/mpegts.mak b/tests/fate/mpegts.mak
>> index bbcbfc47b2..ae21ee87d0 100644
>> --- a/tests/fate/mpegts.mak
>> +++ b/tests/fate/mpegts.mak
>> @@ -19,6 +19,9 @@ FATE_MPEGTS_PROBE-$(call DEMDEC, MPEGTS) += fate-mpegts-probe-pmt-merge
>>   fate-mpegts-probe-pmt-merge: SRC = $(TARGET_SAMPLES)/mpegts/pmtchange.ts
>>   fate-mpegts-probe-pmt-merge: CMD = run $(PROBE_CODEC_NAME_COMMAND) -merge_pmt_versions 1 -i "$(SRC)"
>> +FATE_MPEGTS_PROBE-$(call DEMDEC, MPEGTS, MP2) += fate-mpegts-probe-sdt-data-stream
>> +fate-mpegts-probe-sdt-data-stream: SRC = $(TARGET_SAMPLES)/mpegts/mpegts_sdt_data_stream.ts
>> +fate-mpegts-probe-sdt-data-stream: CMD = run $(PROBE_CODEC_NAME_COMMAND) -i "$(SRC)"
>>   FATE_SAMPLES_FFPROBE += $(FATE_MPEGTS_PROBE-yes)
>> diff --git a/tests/ref/fate/mpegts-probe-sdt-data-stream b/tests/ref/fate/mpegts-probe-sdt-data-stream
>> new file mode 100644
>> index 0000000000..0b8e90962f
>> --- /dev/null
>> +++ b/tests/ref/fate/mpegts-probe-sdt-data-stream
>> @@ -0,0 +1,14 @@
>> +[PROGRAM]
>> +[STREAM]
>> +codec_name=mp2
>> +[/STREAM]
>> +[STREAM]
>> +codec_name=bin_data
>> +[/STREAM]
>> +[/PROGRAM]
>> +[STREAM]
>> +codec_name=mp2
>> +[/STREAM]
>> +[STREAM]
>> +codec_name=bin_data
>> +[/STREAM]
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
TADANO Tokumei April 4, 2022, 4:31 p.m. UTC | #4
Ah, the variables should be int.

On 2022/04/05 1:16, TADANO Tokumei wrote:
> ... and, it is better to check broken packet.
> 
> On 2022/04/05 1:04, TADANO Tokumei wrote:
>> As I posted a patch on Apr. 3rd, you should use "desc_end" rather than "p_end"
>> for get16() or get8() to parse each descriptor.
>>
>> On 2022/04/04 18:53, Jan Ekström wrote:
>>> From: Jan Ekström <jan.ekstrom@24i.com>
>>>
>>> Additionally, they should not be probed, as this is essentially
>>> various types of binary data.
>>>
>>> Signed-off-by: Jan Ekström <jan.ekstrom@24i.com>
>>> ---
>>>   libavformat/mpegts.c                        | 48 +++++++++++++++++++++
>>>   tests/fate/mpegts.mak                       |  3 ++
>>>   tests/ref/fate/mpegts-probe-sdt-data-stream | 14 ++++++
>>>   3 files changed, 65 insertions(+)
>>>   create mode 100644 tests/ref/fate/mpegts-probe-sdt-data-stream
>>>
>>> diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
>>> index da77b50669..3788faf848 100644
>>> --- a/libavformat/mpegts.c
>>> +++ b/libavformat/mpegts.c
>>> @@ -2512,6 +2512,13 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
>>>               }
>>>           }
>>>           p = desc_list_end;
>>> +
>>> +        if (!ts->pkt && (stream_type >= 0x80 && stream_type <= 0xFF) &&
>>> +            st->codecpar->codec_id == AV_CODEC_ID_NONE)
>>> +            // if we are reading headers, and still have a user private stream
>>> +            // with no proper codec set, do not stop reading at PMT. Data
>>> +            // streams are marked within SDT.
>>> +            ts->stop_parse = 0;
>>>       }
>>>       if (!ts->pids[pcr_pid])
>>> @@ -2691,6 +2698,7 @@ static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
>>>       if (val < 0)
>>>           return;
>>>       for (;;) {
>>> +        struct Program *program = NULL;
>>>           sid = get16(&p, p_end);
>>>           if (sid < 0)
>>>               break;
>>> @@ -2704,6 +2712,15 @@ static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
>>>           desc_list_end  = p + desc_list_len;
>>>           if (desc_list_end > p_end)
>>>               break;
>>> +
>>> +        program = get_program(ts, sid);
>>> +
>>> +        if (!ts->pkt && program && program->pmt_found)
>>> +            // if during header reading we have already received a PMT for
>>> +            // this program and now have received an SDT for it, stop further
>>> +            // reading at this point.
>>> +            ts->stop_parse = 2;
>>> +
>>>           for (;;) {
>>>               desc_tag = get8(&p, desc_list_end);
>>>               if (desc_tag < 0)
>>> @@ -2736,6 +2753,37 @@ static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
>>>                   av_free(name);
>>>                   av_free(provider_name);
>>>                   break;
>>> +            case 0x64: /* ETSI data broadcast descriptor; EN 300 468 6.2.11 */
>>> +                {
>>> +                    AVStream *st  = NULL;
>>> +                    FFStream *sti = NULL;
>>> +
>>> +                    uint16_t data_broadcast_id = get16(&p, p_end); // TS 101 162
>>
>> s/p_end/desc_end/
                          int data_broadcast_id = get16(&p, desc_end);

>                          if (data_broadcast_id < 0)
>                              break;
> 
>>
>>> +                    uint8_t  component_tag     = get8(&p, p_end);
>>
>> s/p_end/desc_end/
                          int component_tag     = get8(&p, desc_end);

>>
>>> +                    if (!component_tag)
>                          if (component_tag <= 0)
> 
>>> +                        // no stream mapping according to component_tag
>>> +                        break;
>>> +
>>> +                    av_log(ts->stream, AV_LOG_TRACE,
>>> +                           "data broadcast id: %d, component tag: %d\n",
>>> +                           data_broadcast_id, component_tag);
>>> +
>>> +                    if (!program)
>>> +                        break;
>>> +
>>> +                    st = find_matching_stream(ts, 0, sid, component_tag + 1, 0,
>>> +                                              program);
>>> +                    if (!st)
>>> +                        break;
>>> +
>>> +                    sti = ffstream(st);
>>> +
>>> +                    st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
>>> +                    st->codecpar->codec_id   = AV_CODEC_ID_BIN_DATA;
>>> +                    sti->request_probe = sti->need_parsing = 0;
>>> +                    sti->need_context_update = 1;
>>> +                    break;
>>> +                }
>>>               default:
>>>                   break;
>>>               }
>>> diff --git a/tests/fate/mpegts.mak b/tests/fate/mpegts.mak
>>> index bbcbfc47b2..ae21ee87d0 100644
>>> --- a/tests/fate/mpegts.mak
>>> +++ b/tests/fate/mpegts.mak
>>> @@ -19,6 +19,9 @@ FATE_MPEGTS_PROBE-$(call DEMDEC, MPEGTS) += fate-mpegts-probe-pmt-merge
>>>   fate-mpegts-probe-pmt-merge: SRC = $(TARGET_SAMPLES)/mpegts/pmtchange.ts
>>>   fate-mpegts-probe-pmt-merge: CMD = run $(PROBE_CODEC_NAME_COMMAND) -merge_pmt_versions 1 -i "$(SRC)"
>>> +FATE_MPEGTS_PROBE-$(call DEMDEC, MPEGTS, MP2) += fate-mpegts-probe-sdt-data-stream
>>> +fate-mpegts-probe-sdt-data-stream: SRC = $(TARGET_SAMPLES)/mpegts/mpegts_sdt_data_stream.ts
>>> +fate-mpegts-probe-sdt-data-stream: CMD = run $(PROBE_CODEC_NAME_COMMAND) -i "$(SRC)"
>>>   FATE_SAMPLES_FFPROBE += $(FATE_MPEGTS_PROBE-yes)
>>> diff --git a/tests/ref/fate/mpegts-probe-sdt-data-stream b/tests/ref/fate/mpegts-probe-sdt-data-stream
>>> new file mode 100644
>>> index 0000000000..0b8e90962f
>>> --- /dev/null
>>> +++ b/tests/ref/fate/mpegts-probe-sdt-data-stream
>>> @@ -0,0 +1,14 @@
>>> +[PROGRAM]
>>> +[STREAM]
>>> +codec_name=mp2
>>> +[/STREAM]
>>> +[STREAM]
>>> +codec_name=bin_data
>>> +[/STREAM]
>>> +[/PROGRAM]
>>> +[STREAM]
>>> +codec_name=mp2
>>> +[/STREAM]
>>> +[STREAM]
>>> +codec_name=bin_data
>>> +[/STREAM]
>> _______________________________________________
>> ffmpeg-devel mailing list
>> ffmpeg-devel@ffmpeg.org
>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>
>> To unsubscribe, visit link above, or email
>> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Jan Ekström April 4, 2022, 9:24 p.m. UTC | #5
On Mon, Apr 4, 2022 at 7:04 PM TADANO Tokumei <aimingoff@pc.nifty.jp> wrote:
>
> As I posted a patch on Apr. 3rd, you should use "desc_end" rather than "p_end"
> for get16() or get8() to parse each descriptor.
>

Yes, I had noticed and planned to look into those patches, but did not
have the time to do that yet.

Also FYI, this mailing list utilizes bottom posting, not top posting.

Jan
Jan Ekström April 4, 2022, 9:35 p.m. UTC | #6
On Mon, Apr 4, 2022 at 7:32 PM TADANO Tokumei <aimingoff@pc.nifty.jp> wrote:
>
> Ah, the variables should be int.
>
> On 2022/04/05 1:16, TADANO Tokumei wrote:
> > ... and, it is better to check broken packet.
> >

Yes. I guess I'll swap those for ints, although I like having the
original unsigned sizes :) .

I think alternatively it could be checked whether there is enough data
before hand, since the only error seems to be if there is not enough
data available. In this case it would be three bytes I think, 16+8
bits.

Jan
diff mbox series

Patch

diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index da77b50669..3788faf848 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -2512,6 +2512,13 @@  static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
             }
         }
         p = desc_list_end;
+
+        if (!ts->pkt && (stream_type >= 0x80 && stream_type <= 0xFF) &&
+            st->codecpar->codec_id == AV_CODEC_ID_NONE)
+            // if we are reading headers, and still have a user private stream
+            // with no proper codec set, do not stop reading at PMT. Data
+            // streams are marked within SDT.
+            ts->stop_parse = 0;
     }
 
     if (!ts->pids[pcr_pid])
@@ -2691,6 +2698,7 @@  static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
     if (val < 0)
         return;
     for (;;) {
+        struct Program *program = NULL;
         sid = get16(&p, p_end);
         if (sid < 0)
             break;
@@ -2704,6 +2712,15 @@  static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
         desc_list_end  = p + desc_list_len;
         if (desc_list_end > p_end)
             break;
+
+        program = get_program(ts, sid);
+
+        if (!ts->pkt && program && program->pmt_found)
+            // if during header reading we have already received a PMT for
+            // this program and now have received an SDT for it, stop further
+            // reading at this point.
+            ts->stop_parse = 2;
+
         for (;;) {
             desc_tag = get8(&p, desc_list_end);
             if (desc_tag < 0)
@@ -2736,6 +2753,37 @@  static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len
                 av_free(name);
                 av_free(provider_name);
                 break;
+            case 0x64: /* ETSI data broadcast descriptor; EN 300 468 6.2.11 */
+                {
+                    AVStream *st  = NULL;
+                    FFStream *sti = NULL;
+
+                    uint16_t data_broadcast_id = get16(&p, p_end); // TS 101 162
+                    uint8_t  component_tag     = get8(&p, p_end);
+                    if (!component_tag)
+                        // no stream mapping according to component_tag
+                        break;
+
+                    av_log(ts->stream, AV_LOG_TRACE,
+                           "data broadcast id: %d, component tag: %d\n",
+                           data_broadcast_id, component_tag);
+
+                    if (!program)
+                        break;
+
+                    st = find_matching_stream(ts, 0, sid, component_tag + 1, 0,
+                                              program);
+                    if (!st)
+                        break;
+
+                    sti = ffstream(st);
+
+                    st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
+                    st->codecpar->codec_id   = AV_CODEC_ID_BIN_DATA;
+                    sti->request_probe = sti->need_parsing = 0;
+                    sti->need_context_update = 1;
+                    break;
+                }
             default:
                 break;
             }
diff --git a/tests/fate/mpegts.mak b/tests/fate/mpegts.mak
index bbcbfc47b2..ae21ee87d0 100644
--- a/tests/fate/mpegts.mak
+++ b/tests/fate/mpegts.mak
@@ -19,6 +19,9 @@  FATE_MPEGTS_PROBE-$(call DEMDEC, MPEGTS) += fate-mpegts-probe-pmt-merge
 fate-mpegts-probe-pmt-merge: SRC = $(TARGET_SAMPLES)/mpegts/pmtchange.ts
 fate-mpegts-probe-pmt-merge: CMD = run $(PROBE_CODEC_NAME_COMMAND) -merge_pmt_versions 1 -i "$(SRC)"
 
+FATE_MPEGTS_PROBE-$(call DEMDEC, MPEGTS, MP2) += fate-mpegts-probe-sdt-data-stream
+fate-mpegts-probe-sdt-data-stream: SRC = $(TARGET_SAMPLES)/mpegts/mpegts_sdt_data_stream.ts
+fate-mpegts-probe-sdt-data-stream: CMD = run $(PROBE_CODEC_NAME_COMMAND) -i "$(SRC)"
 
 FATE_SAMPLES_FFPROBE += $(FATE_MPEGTS_PROBE-yes)
 
diff --git a/tests/ref/fate/mpegts-probe-sdt-data-stream b/tests/ref/fate/mpegts-probe-sdt-data-stream
new file mode 100644
index 0000000000..0b8e90962f
--- /dev/null
+++ b/tests/ref/fate/mpegts-probe-sdt-data-stream
@@ -0,0 +1,14 @@ 
+[PROGRAM]
+[STREAM]
+codec_name=mp2
+[/STREAM]
+[STREAM]
+codec_name=bin_data
+[/STREAM]
+[/PROGRAM]
+[STREAM]
+codec_name=mp2
+[/STREAM]
+[STREAM]
+codec_name=bin_data
+[/STREAM]