[vlc-commits] test: add PES assembly tests

Francois Cartegnie git at videolan.org
Thu Jan 23 21:12:54 CET 2020


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Fri Jan 17 17:59:27 2020 +0100| [cef77e6f7f0d47df92e3ca609da07916dc44a3fa] | committer: Francois Cartegnie

test: add PES assembly tests

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=cef77e6f7f0d47df92e3ca609da07916dc44a3fa
---

 test/Makefile.am            |  10 +-
 test/modules/demux/ts_pes.c | 270 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 279 insertions(+), 1 deletion(-)

diff --git a/test/Makefile.am b/test/Makefile.am
index bc47d07af7..6d373bcb8e 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -40,7 +40,10 @@ check_PROGRAMS = \
 	test_modules_packetizer_mpegvideo \
 	test_modules_keystore \
 	test_modules_demux_dashuri \
-	test_modules_demux_timestamps_filter
+	test_modules_demux_timestamps_filter \
+	test_modules_demux_ts_pes \
+	$(NULL)
+
 if ENABLE_SOUT
 check_PROGRAMS += test_modules_tls
 endif
@@ -158,6 +161,11 @@ test_modules_tls_LDADD = $(LIBVLCCORE) $(LIBVLC)
 test_modules_demux_dashuri_SOURCES = modules/demux/dashuri.cpp
 test_modules_demux_timestamps_filter_LDADD = $(LIBVLCCORE) $(LIBVLC)
 test_modules_demux_timestamps_filter_SOURCES = modules/demux/timestamps_filter.c
+test_modules_demux_ts_pes_LDADD = $(LIBVLCCORE) $(LIBVLC)
+test_modules_demux_ts_pes_SOURCES = modules/demux/ts_pes.c \
+				../modules/demux/mpeg/ts_pes.c \
+				../modules/demux/mpeg/ts_pes.h
+
 
 checkall:
 	$(MAKE) check_PROGRAMS="$(check_PROGRAMS) $(EXTRA_PROGRAMS)" check
diff --git a/test/modules/demux/ts_pes.c b/test/modules/demux/ts_pes.c
new file mode 100644
index 0000000000..1e694e0eaa
--- /dev/null
+++ b/test/modules/demux/ts_pes.c
@@ -0,0 +1,270 @@
+/*****************************************************************************
+ * ts_pes.c: MPEG PES assembly tests
+ *****************************************************************************
+ * Copyright (C) 2020 VideoLabs, VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <vlc_common.h>
+#include <vlc_block.h>
+
+#include "../../../modules/demux/mpeg/ts_streams.h"
+#include "../../../modules/demux/mpeg/ts_pid_fwd.h"
+#include "../../../modules/demux/mpeg/ts_streams_private.h"
+#include "../../../modules/demux/mpeg/ts_pes.h"
+
+#include "../../libvlc/test.h"
+
+static void Parse(vlc_object_t *obj, void *priv, block_t *data)
+{
+    VLC_UNUSED(obj);
+    block_t **pp_append = (block_t **) priv;
+    fprintf(stderr, "recv: ");
+    data = block_ChainGather(data);
+    for(size_t i=0; i<data->i_buffer; i++)
+        fprintf(stderr, "%2.2x ", data->p_buffer[i]);
+    fprintf(stderr, "\n");
+    block_ChainAppend(pp_append, data);
+}
+
+#define RESET do {\
+    block_ChainRelease(output);\
+    output = NULL;\
+    block_ChainRelease(pes.gather.p_data);\
+    memset(&pes, 0, sizeof(pes));\
+    pes.transport = TS_TRANSPORT_PES;\
+    pes.gather.pp_last = &pes.gather.p_data;\
+    } while(0)
+
+#define ASSERT(a) do {\
+    if(!(a)) { RESET; \
+        fprintf(stderr, "failed line %d\n", __LINE__); \
+        return 1; } \
+    } while(0)
+
+#define PKT_FROMSZ(a, b) do {\
+    pkt = block_Alloc(sizeof(a) + b);\
+    ASSERT(pkt);\
+    memcpy(pkt->p_buffer, a, sizeof(a));\
+    for(size_t i=1; i<1+b;i++)\
+        pkt->p_buffer[sizeof(a) + i] = i % 0xFF;\
+} while(0)
+
+#define PKT_FROM(a) PKT_FROMSZ(a, 0)
+
+int main()
+{
+    block_t *pkt;
+    block_t *output = NULL;
+    int outputcount = 0;
+    size_t outputsize = 0;
+
+    test_init();
+
+    ts_pes_parse_callback cb =
+    {
+        .p_obj = NULL,
+        .priv = &output,
+        .pf_parse = Parse
+    };
+
+    ts_stream_t pes;
+    memset(&pes, 0, sizeof(pes));
+    pes.transport = TS_TRANSPORT_PES;
+    pes.gather.pp_last = &pes.gather.p_data;
+
+    /* General case, aligned payloads */
+    /* payload == 0 */
+    const uint8_t aligned0[] = {
+        0x00, 0x00, 0x01, 0xe0, 0x00, 0x03, 0x80, 0x00, 0x00,
+    };
+    PKT_FROM(aligned0);
+    ASSERT(ts_pes_Gather(&cb, &pes, pkt, true, true));
+    ASSERT(output);
+    block_ChainProperties(output, &outputcount, &outputsize, NULL);
+    ASSERT(outputcount == 1);
+    ASSERT(outputsize == 6+3);
+    ASSERT(!memcmp(aligned0, output->p_buffer, outputsize));
+    RESET;
+    /* no output if not unit start */
+    PKT_FROM(aligned0);
+    ASSERT(!ts_pes_Gather(&cb, &pes, pkt, false, true));
+    ASSERT(!output);
+    RESET;
+    /* no output if not unit start */
+    PKT_FROM(aligned0);
+    pkt->i_buffer = 1;
+    ASSERT(!ts_pes_Gather(&cb, &pes, pkt, false, true));
+    ASSERT(!output);
+    RESET;
+
+    /* payload == 6 */
+    const uint8_t aligned1[] = {
+        0x00, 0x00, 0x01, 0xe0, 0x00, 0x09, 0x80, 0x00, 0x00,
+        0xAA, 0xBB, 0xAA, 0xBB, 0xAA, 0xBB,
+    };
+    PKT_FROM(aligned1);
+    ASSERT(ts_pes_Gather(&cb, &pes, pkt, true, true));
+    ASSERT(output);
+    block_ChainProperties(output, &outputcount, &outputsize, NULL);
+    ASSERT(outputcount == 1);
+    ASSERT(outputsize == 6+3+6);
+    ASSERT(!memcmp(aligned1, output->p_buffer, outputsize));
+    RESET;
+    /* no output if not unit start */
+    PKT_FROM(aligned1);
+    ASSERT(!ts_pes_Gather(&cb, &pes, pkt, false, true));
+    ASSERT(!output);
+    RESET;
+
+    /* payload == 30, uncomplete */
+    PKT_FROM(aligned1);
+    SetWBE(&pkt->p_buffer[4], 30);
+    ASSERT(!ts_pes_Gather(&cb, &pes, pkt, true, true));
+    ASSERT(!output);
+    RESET;
+
+    /* packets assembly, payload > 188 - 6 - 4 */
+    PKT_FROMSZ(aligned1, 188-sizeof(aligned1));
+    SetWBE(&pkt->p_buffer[4], 250);
+    ASSERT(!ts_pes_Gather(&cb, &pes, pkt, true, true));
+    ASSERT(!output);
+    ASSERT(pes.gather.i_data_size == 256);
+    PKT_FROMSZ(aligned1, 188-sizeof(aligned1));
+    ASSERT(ts_pes_Gather(&cb, &pes, pkt, false, true));
+    ASSERT(output);
+    block_ChainProperties(output, &outputcount, &outputsize, NULL);
+    ASSERT(outputcount == 1);
+    ASSERT(outputsize == 256);
+    RESET;
+
+    /* no packets assembly from unit start */
+    PKT_FROMSZ(aligned1, 188-sizeof(aligned1));
+    SetWBE(&pkt->p_buffer[4], 250);
+    ASSERT(!ts_pes_Gather(&cb, &pes, pkt, true, true));
+    ASSERT(!output);
+    ASSERT(pes.gather.i_data_size == 256);
+    PKT_FROMSZ(aligned1, 188-sizeof(aligned1));
+    ASSERT(ts_pes_Gather(&cb, &pes, pkt, true, true));
+    ASSERT(output);
+    block_ChainProperties(output, &outputcount, &outputsize, NULL);
+    ASSERT(outputcount == 2);
+    RESET;
+
+    /* packets assembly, payload undef, use next sync code from another payload undef */
+    PKT_FROMSZ(aligned1, 188-sizeof(aligned1));
+    SetWBE(&pkt->p_buffer[4], 0);
+    ASSERT(!ts_pes_Gather(&cb, &pes, pkt, true, true));
+    ASSERT(!output);
+    ASSERT(pes.gather.i_data_size == 0);
+    PKT_FROMSZ(aligned1, 188-sizeof(aligned1));
+    SetWBE(&pkt->p_buffer[4], 0);
+    ASSERT(ts_pes_Gather(&cb, &pes, pkt, true, true));
+    ASSERT(output);
+    block_ChainProperties(output, &outputcount, &outputsize, NULL);
+    ASSERT(outputcount == 1);
+    ASSERT(outputsize == 188);
+    RESET;
+
+    /* packets assembly, payload undef, use next sync code from fixed size */
+    PKT_FROMSZ(aligned1, 188-sizeof(aligned1));
+    SetWBE(&pkt->p_buffer[4], 0);
+    ASSERT(!ts_pes_Gather(&cb, &pes, pkt, true, true));
+    ASSERT(!output);
+    ASSERT(pes.gather.i_data_size == 0);
+    PKT_FROMSZ(aligned1, 188-sizeof(aligned1));
+    ASSERT(ts_pes_Gather(&cb, &pes, pkt, true, true));
+    ASSERT(output);
+    block_ChainProperties(output, &outputcount, &outputsize, NULL);
+    ASSERT(outputcount == 2); /* secondary */
+    RESET;
+
+    /* packets assembly, payload undef, use next sync code from fixed size but uncomplete */
+    PKT_FROMSZ(aligned1, 188-sizeof(aligned1));
+    SetWBE(&pkt->p_buffer[4], 0);
+    ASSERT(!ts_pes_Gather(&cb, &pes, pkt, true, true));
+    ASSERT(!output);
+    ASSERT(pes.gather.i_data_size == 0);
+    PKT_FROM(aligned1);
+    pkt->i_buffer = 6;
+    ASSERT(ts_pes_Gather(&cb, &pes, pkt, true, true));
+    ASSERT(output);
+    block_ChainProperties(output, &outputcount, &outputsize, NULL);
+    ASSERT(outputcount == 1); /* can't output */
+    PKT_FROM(aligned1);
+    ASSERT(ts_pes_Gather(&cb, &pes, pkt, false, true)); /* add data for last output */
+    ASSERT(output); /* output */
+    RESET;
+
+    const uint8_t aligned2[] = {
+        0x00, 0x00, 0x01, 0xe0, 0x00, 0x03, 0x80, 0x00, 0x00,
+
+        0x00, 0x00, 0x01, 0xe0, 0x00, 0x07, 0x80, 0x00, 0x00,  /* PES 0xdb header */
+        0x00, 0x01, 0x02, 0x03,                                /* PES payload */
+
+        0x00, 0x00, 0x01, 0xe0, 0x00, 0x07, 0x80, 0x00, 0x00,  /* PES 0xdb header */
+        0xAA, 0xBB, 0xCC, 0xDD,                                /* PES payload */
+    };
+
+    /* If the payload_unit_start_indicator is set to '1', then one and only one
+     * PES packet starts in this transport stream packet. */
+    PKT_FROM(aligned2);
+    ASSERT(ts_pes_Gather(&cb, &pes, pkt, true, true));
+    ASSERT(output);
+    block_ChainProperties(output, &outputcount, &outputsize, NULL);
+    ASSERT(outputcount == 1);
+    RESET;
+
+    /* Broken PUSI tests */
+    pes.b_broken_PUSI_conformance = true;
+    PKT_FROM(aligned2);
+    ASSERT(ts_pes_Gather(&cb, &pes, pkt, true, true));
+    ASSERT(output);
+    block_ChainProperties(output, &outputcount, &outputsize, NULL);
+    ASSERT(outputcount == 3);
+    RESET;
+
+    pes.b_broken_PUSI_conformance = true;
+    PKT_FROM(aligned2);
+    pkt->p_buffer[0] = 0xFF;
+    ASSERT(ts_pes_Gather(&cb, &pes, pkt, true, true));
+    ASSERT(output);
+    block_ChainProperties(output, &outputcount, &outputsize, NULL);
+    ASSERT(outputcount == 2);
+    RESET;
+
+    for(int split=12; split>9; split--)
+    {
+        pes.b_broken_PUSI_conformance = true;
+        PKT_FROM(aligned2);
+        pkt->i_buffer = split;
+        ASSERT(ts_pes_Gather(&cb, &pes, pkt, true, true));
+        ASSERT(output);
+
+        PKT_FROM(aligned2);
+        pkt->p_buffer += split;
+        pkt->i_buffer -= split;
+        ASSERT(ts_pes_Gather(&cb, &pes, pkt, true, true));
+        ASSERT(output);
+
+        RESET;
+    }
+
+    return 0;
+}



More information about the vlc-commits mailing list