[libdvbpsi-devel] [Git][videolan/libdvbpsi][master] 3 commits: misc/test_chain.c: add chain demux tests
Jean-Paul Saman
gitlab at videolan.org
Mon Feb 19 16:45:18 CET 2018
Jean-Paul Saman pushed to branch master at VideoLAN / libdvbpsi
Commits:
a3e2180b by Jean-Paul Saman at 2018-02-19T16:44:26+01:00
misc/test_chain.c: add chain demux tests
- - - - -
5fecd88a by Jean-Paul Saman at 2018-02-19T16:44:26+01:00
chain: call all additonally attached decoders in dvbpsi_chain_demux_delete()
The function dvbpsi_chain_demux_delete() failed to call p->pf_del() for all
attached decoder. This resulted in leaked decoder memory.
- - - - -
2e65fd5b by Jean-Paul Saman at 2018-02-19T16:44:26+01:00
src/dvbpsi.c: remove empty line
- - - - -
4 changed files:
- misc/Makefile.am
- misc/test_chain.c
- src/chain.c
- src/dvbpsi.c
Changes:
=====================================
misc/Makefile.am
=====================================
--- a/misc/Makefile.am
+++ b/misc/Makefile.am
@@ -15,7 +15,7 @@ gen_pmt_LDFLAGS = -L../src -ldvbpsi
test_chain_SOURCES = test_chain.c
test_chain_CPPFLAGS = -DDVBPSI_DIST
-test_chain_LDFLAGS = -L../src -ldvbpsi
+test_chain_LDFLAGS = -L../src -ldvbpsi -lm
test_dr_SOURCES = test_dr.c
test_dr_CPPFLAGS = -DDVBPSI_DIST
=====================================
misc/test_chain.c
=====================================
--- a/misc/test_chain.c
+++ b/misc/test_chain.c
@@ -24,12 +24,13 @@
*
*****************************************************************************/
-
#include "config.h"
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
+#include <string.h>
+#include <math.h>
#include <assert.h>
#if defined(HAVE_INTTYPES_H)
@@ -38,22 +39,34 @@
#include <stdint.h>
#endif
-/* the libdvbpsi distribution defines DVBPSI_DIST */
+/* The libdvbpsi distribution defines DVBPSI_DIST */
#ifdef DVBPSI_DIST
#include "../src/dvbpsi.h"
+#include "../src/dvbpsi_private.h"
#include "../src/psi.h"
#include "../src/chain.h"
+#include "../src/descriptor.h"
+#include "../src/tables/pat.h"
+#include "../src/tables/pmt.h"
+#include "../src/tables/bat.h"
+#include "../src/descriptors/dr.h"
#else
#include <dvbpsi/dvbpsi.h>
+#include "../src/dvbpsi_private.h"
#include <dvbpsi/psi.h>
#include <dvbpsi/chain.h>
+#include <dvbpsi/descriptor.h>
+#include <dvbpsi/pat.h>
+#include <dvbpsi/pmt.h>
+#include <dvbpsi/bat.h>
+#include <dvbpsi/dr.h>
#endif
#define TEST_PASSED(msg) fprintf(stderr, "test %s -- PASSED\n", (msg));
#define TEST_FAILED(msg) fprintf(stderr, "test %s -- FAILED\n", (msg));
/* debug */
-//#define _TEST_CHAIN_DEBUG
+#define _TEST_CHAIN_DEBUG
#ifdef _TEST_CHAIN_DEBUG /* debug */
static void dvbpsi_decoder_chain_dump(dvbpsi_t *p_dvbpsi)
{
@@ -192,66 +205,459 @@ static bool chain_release_with_extension(dvbpsi_t *p_dvbpsi, const int count)
}
/*****************************************************************************
- * main
+ * CHAIN TESTS
*****************************************************************************/
-#define CHAIN_DECODERS (20)
-int main(int i_argc, char* pa_argv[])
+static int run_chain_test(const int i_decoders)
{
- dvbpsi_t *p_dvbpsi = dvbpsi_new(&message, DVBPSI_MSG_DEBUG);
- if (p_dvbpsi == NULL)
- return 1;
-
- /* Test dvbpsi_decoder_chain_add() */
- if (!chain_add(p_dvbpsi, CHAIN_DECODERS)) {
- TEST_FAILED("dvbpsi_decoder_chain_add");
- goto error;
- }
- TEST_PASSED("dvbpsi_decoder_chain_add");
-
- /* Test dvbpsi_decoder_chain_get() */
- if (!chain_find(p_dvbpsi, CHAIN_DECODERS)) {
- TEST_FAILED("dvbpsi_decoder_chain_get");
- goto error;
- }
- TEST_PASSED("dvbpsi_decoder_chain_get");
-
- /* Test dvbpsi_decoder_chain_add() with table extensions */
- if (!chain_add_table_extension(p_dvbpsi, CHAIN_DECODERS)) {
- TEST_FAILED("dvbpsi_decoder_chain_add with extensions");
- goto error;
- }
- TEST_PASSED("dvbpsi_decoder_chain_add with extensions");
+ dvbpsi_t *p_dvbpsi = dvbpsi_new(&message, DVBPSI_MSG_DEBUG);
+ if (p_dvbpsi == NULL)
+ return 1;
+
+ /* Test dvbpsi_decoder_chain_add() */
+ if (!chain_add(p_dvbpsi, i_decoders)) {
+ TEST_FAILED("dvbpsi_decoder_chain_add");
+ goto error;
+ }
+ TEST_PASSED("dvbpsi_decoder_chain_add");
+
+ /* Test dvbpsi_decoder_chain_get() */
+ if (!chain_find(p_dvbpsi, i_decoders)) {
+ TEST_FAILED("dvbpsi_decoder_chain_get");
+ goto error;
+ }
+ TEST_PASSED("dvbpsi_decoder_chain_get");
+
+ /* Test dvbpsi_decoder_chain_add() with table extensions */
+ if (!chain_add_table_extension(p_dvbpsi, i_decoders)) {
+ TEST_FAILED("dvbpsi_decoder_chain_add with extensions");
+ goto error;
+ }
+ TEST_PASSED("dvbpsi_decoder_chain_add with extensions");
#ifdef _TEST_CHAIN_DEBUG
- dvbpsi_decoder_chain_dump(p_dvbpsi);
+ dvbpsi_decoder_chain_dump(p_dvbpsi);
#endif
- /* Test dvbpsi_decoder_chain_remove() */
- if (!chain_release(p_dvbpsi, CHAIN_DECODERS)) {
- TEST_FAILED("dvbpsi_decoder_chain_remove");
- dvbpsi_delete(p_dvbpsi);
- return 1;
- }
- TEST_PASSED("dvbpsi_decoder_chain_remove");
-
- /* Test dvbpsi_decoder_chain_remove() */
- if (!chain_release_with_extension(p_dvbpsi, CHAIN_DECODERS)) {
- TEST_FAILED("dvbpsi_decoder_chain_remove with extensions");
- dvbpsi_delete(p_dvbpsi);
- return 1;
- }
- TEST_PASSED("dvbpsi_decoder_chain_remove with extensions");
-
- p_dvbpsi->p_decoder = NULL;
- dvbpsi_delete(p_dvbpsi);
- fprintf(stderr, "ALL CHAIN TESTS PASSED\n");
- return 0;
+ /* Test dvbpsi_decoder_chain_remove() */
+ if (!chain_release(p_dvbpsi, i_decoders)) {
+ TEST_FAILED("dvbpsi_decoder_chain_remove");
+ dvbpsi_delete(p_dvbpsi);
+ return 1;
+ }
+ TEST_PASSED("dvbpsi_decoder_chain_remove");
+
+ /* Test dvbpsi_decoder_chain_remove() */
+ if (!chain_release_with_extension(p_dvbpsi, i_decoders)) {
+ TEST_FAILED("dvbpsi_decoder_chain_remove with extensions");
+ dvbpsi_delete(p_dvbpsi);
+ return 1;
+ }
+ TEST_PASSED("dvbpsi_decoder_chain_remove with extensions");
+
+ p_dvbpsi->p_decoder = NULL;
+ dvbpsi_delete(p_dvbpsi);
+ fprintf(stderr, "ALL CHAIN TESTS PASSED\n");
+ return 0;
error:
- /* cleanup */
- if (!chain_release(p_dvbpsi, CHAIN_DECODERS))
- fprintf(stderr, "failed to cleanup after errors\n");
- p_dvbpsi->p_decoder = NULL;
- dvbpsi_delete(p_dvbpsi);
- return 1;
+ /* cleanup */
+ if (!chain_release(p_dvbpsi, i_decoders))
+ fprintf(stderr, "failed to cleanup after errors\n");
+ p_dvbpsi->p_decoder = NULL;
+ dvbpsi_delete(p_dvbpsi);
+ return 1;
+
+}
+
+/*****************************************************************************
+ * CHAIN DEMUX TESTS
+ *****************************************************************************/
+
+/*****************************************************************************
+ * DumpMaxBitrateDescriptor
+ *****************************************************************************/
+static void DumpMaxBitrateDescriptor(dvbpsi_mpeg_max_bitrate_dr_t* bitrate_descriptor)
+{
+ printf("Bitrate: %d\n", bitrate_descriptor->i_max_bitrate);
+}
+
+/*****************************************************************************
+ * DumpSystemClockDescriptor
+ *****************************************************************************/
+static void DumpSystemClockDescriptor(dvbpsi_mpeg_system_clock_dr_t* p_clock_descriptor)
+{
+ printf("External clock: %s, Accuracy: %E\n",
+ p_clock_descriptor->b_external_clock_ref ? "Yes" : "No",
+ p_clock_descriptor->i_clock_accuracy_integer *
+ pow(10.0, -(double)p_clock_descriptor->i_clock_accuracy_exponent));
+}
+
+/*****************************************************************************
+ * DumpStreamIdentifierDescriptor
+ *****************************************************************************/
+static void DumpStreamIdentifierDescriptor(dvbpsi_dvb_stream_identifier_dr_t* p_si_descriptor)
+{
+ printf("Component tag: %d\n",
+ p_si_descriptor->i_component_tag);
+}
+
+/*****************************************************************************
+ * DumpSubtitleDescriptor
+ *****************************************************************************/
+static void DumpSubtitleDescriptor(dvbpsi_dvb_subtitling_dr_t* p_subtitle_descriptor)
+{
+ int a;
+
+ printf("%d subtitles,\n", p_subtitle_descriptor->i_subtitles_number);
+ for (a = 0; a < p_subtitle_descriptor->i_subtitles_number; ++a)
+ {
+ printf(" | %d - lang: %c%c%c, type: %d, cpid: %d, apid: %d\n", a,
+ p_subtitle_descriptor->p_subtitle[a].i_iso6392_language_code[0],
+ p_subtitle_descriptor->p_subtitle[a].i_iso6392_language_code[1],
+ p_subtitle_descriptor->p_subtitle[a].i_iso6392_language_code[2],
+ p_subtitle_descriptor->p_subtitle[a].i_subtitling_type,
+ p_subtitle_descriptor->p_subtitle[a].i_composition_page_id,
+ p_subtitle_descriptor->p_subtitle[a].i_ancillary_page_id);
+ }
+}
+
+/*****************************************************************************
+ * Print_0xb1
+ *****************************************************************************/
+static void Dump0xb11(uint16_t i_ts_id, dvbpsi_descriptor_t* p_descriptor)
+{
+ int i;
+ uint8_t *pdata;
+ unsigned int sub_bouquet_id;
+ int num;
+ unsigned int formater;
+ pdata = p_descriptor->p_data;
+ num = (p_descriptor->i_length-2)/9;
+ sub_bouquet_id = (((unsigned int)pdata[0]&0xff)<<8)|pdata[1];
+ if (sub_bouquet_id != 0xffff)
+ {
+ printf("sub_bouquet_id!=0xffff\n");
+ return;
+ }
+ if (num*9 != p_descriptor->i_length-2)
+ {
+ printf("num of private_services error\n");
+ return;
+ }
+ pdata+=2;
+
+ printf("\nts_id: %d, service_num: %d, service_id list: \n",i_ts_id,num);
+ formater=0;
+ for (i = 0; i < num; i++)
+ {
+ uint16_t service_id = (((uint16_t)pdata[0]&0xff)<<8)|pdata[1];
+ printf("%.4x ", service_id);
+ formater++;
+ if (0 == formater%16)
+ {
+ printf("\n");
+ }
+ pdata+=9;
+ }
+ printf("\r\n");
+}
+
+/*****************************************************************************
+ * DumpDescriptors
+ *****************************************************************************/
+static void DumpDescriptors(const char* str, dvbpsi_descriptor_t* p_descriptor)
+{
+#define SYSTEM_CLOCK_DR 0x0B
+#define MAX_BITRATE_DR 0x0E
+#define STREAM_IDENTIFIER_DR 0x52
+#define SUBTITLING_DR 0x59
+
+ while (p_descriptor)
+ {
+ printf("%s 0x%02x : ", str, p_descriptor->i_tag);
+ switch (p_descriptor->i_tag)
+ {
+ case SYSTEM_CLOCK_DR:
+ DumpSystemClockDescriptor(dvbpsi_decode_mpeg_system_clock_dr(p_descriptor));
+ break;
+ case MAX_BITRATE_DR:
+ DumpMaxBitrateDescriptor(dvbpsi_decode_mpeg_max_bitrate_dr(p_descriptor));
+ break;
+ case STREAM_IDENTIFIER_DR:
+ DumpStreamIdentifierDescriptor(dvbpsi_decode_dvb_stream_identifier_dr(p_descriptor));
+ break;
+ case SUBTITLING_DR:
+ DumpSubtitleDescriptor(dvbpsi_decode_dvb_subtitling_dr(p_descriptor));
+ break;
+ break;
+ default:
+ printf("\"");
+ for(int i = 0; i < p_descriptor->i_length; i++)
+ printf("%c", p_descriptor->p_data[i]);
+ printf("\"\n");
+ }
+ p_descriptor = p_descriptor->p_next;
+ }
+}
+
+/*****************************************************************************
+ * DumpDescriptors_verbose
+ *****************************************************************************/
+static void DumpDescriptors_verbose(uint16_t i_ts_id, dvbpsi_descriptor_t* p_descriptor)
+{
+ while (p_descriptor)
+ {
+ if (0xb1 == p_descriptor->i_tag)
+ {
+ Dump0xb11(i_ts_id,p_descriptor);
+ }
+ p_descriptor = p_descriptor->p_next;
+ }
+}
+
+/*****************************************************************************
+ * DumpBAT_verbose
+ *****************************************************************************/
+static void DumpBAT_verbose(void* p_zero, dvbpsi_bat_t* p_bat)
+{
+ dvbpsi_bat_ts_t* p_ts = p_bat->p_first_ts;
+ while (p_ts)
+ {
+ DumpDescriptors_verbose(p_ts->i_ts_id, p_ts->p_first_descriptor);
+ p_ts = p_ts->p_next;
+ }
+}
+
+/*****************************************************************************
+ * DumpBAT
+ *****************************************************************************/
+static void DumpBAT(void* p_zero, dvbpsi_bat_t* p_bat)
+{
+ dvbpsi_bat_ts_t* p_ts = p_bat->p_first_ts;
+ printf( "\n");
+ printf( "New active BAT(binary dumped)\n");
+ printf( " bouquet_id : %d\n",
+ p_bat->i_extension);
+ printf( " version_number : %d\n",
+ p_bat->i_version);
+ printf( " | ts_id \n");
+ while(p_ts)
+ {
+ printf(" | 0x%02x \n",
+ p_ts->i_ts_id);
+ DumpDescriptors(" | ]", p_ts->p_first_descriptor);
+ p_ts = p_ts->p_next;
+ }
+ printf( "\n");
+ printf( "New active BAT(string dumped)\n");
+ DumpBAT_verbose(p_zero,p_bat);
+ printf("\n");
+ dvbpsi_bat_delete(p_bat);
+}
+
+/*****************************************************************************
+ * DumpPAT
+ *****************************************************************************/
+static void DumpPAT(void* p_zero, dvbpsi_pat_t* p_pat)
+{
+ dvbpsi_pat_program_t* p_program = p_pat->p_first_program;
+ printf( "\n");
+ printf( "New PAT\n");
+ printf( " transport_stream_id : %d\n", p_pat->i_ts_id);
+ printf( " version_number : %d\n", p_pat->i_version);
+ printf( " | program_number @ [NIT|PMT]_PID\n");
+ while (p_program)
+ {
+ printf(" | %14d @ 0x%x (%d)\n",
+ p_program->i_number, p_program->i_pid, p_program->i_pid);
+ p_program = p_program->p_next;
+ }
+ printf( " active : %d\n", p_pat->b_current_next);
+ dvbpsi_pat_delete(p_pat);
+}
+
+/*****************************************************************************
+ * GetTypeName
+ *****************************************************************************/
+static char* GetTypeName(uint8_t type)
+{
+ switch (type)
+ {
+ case 0x00:
+ return "Reserved";
+ case 0x01:
+ return "ISO/IEC 11172 Video";
+ case 0x02:
+ return "ISO/IEC 13818-2 Video";
+ case 0x03:
+ return "ISO/IEC 11172 Audio";
+ case 0x04:
+ return "ISO/IEC 13818-3 Audio";
+ case 0x05:
+ return "ISO/IEC 13818-1 Private Section";
+ case 0x06:
+ return "ISO/IEC 13818-1 Private PES data packets";
+ case 0x07:
+ return "ISO/IEC 13522 MHEG";
+ case 0x08:
+ return "ISO/IEC 13818-1 Annex A DSM CC";
+ case 0x09:
+ return "H222.1";
+ case 0x0A:
+ return "ISO/IEC 13818-6 type A";
+ case 0x0B:
+ return "ISO/IEC 13818-6 type B";
+ case 0x0C:
+ return "ISO/IEC 13818-6 type C";
+ case 0x0D:
+ return "ISO/IEC 13818-6 type D";
+ case 0x0E:
+ return "ISO/IEC 13818-1 auxillary";
+ default:
+ if (type < 0x80)
+ return "ISO/IEC 13818-1 reserved";
+ else
+ return "User Private";
+ }
+}
+
+/*****************************************************************************
+ * DumpPMT
+ *****************************************************************************/
+static void DumpPMT(void* p_zero, dvbpsi_pmt_t* p_pmt)
+{
+ dvbpsi_pmt_es_t* p_es = p_pmt->p_first_es;
+ printf( "\n");
+ printf( "New active PMT\n");
+ printf( " program_number : %d\n",
+ p_pmt->i_program_number);
+ printf( " version_number : %d\n",
+ p_pmt->i_version);
+ printf( " PCR_PID : 0x%x (%d)\n",
+ p_pmt->i_pcr_pid, p_pmt->i_pcr_pid);
+ DumpDescriptors(" ]", p_pmt->p_first_descriptor);
+ printf( " | type @ elementary_PID\n");
+ while (p_es)
+ {
+ printf(" | 0x%02x (%s) @ 0x%x (%d)\n",
+ p_es->i_type, GetTypeName(p_es->i_type),
+ p_es->i_pid, p_es->i_pid);
+ DumpDescriptors(" | ]", p_es->p_first_descriptor);
+ p_es = p_es->p_next;
+ }
+ dvbpsi_pmt_delete(p_pmt);
+}
+
+/*****************************************************************************
+ * NewSubtable
+ *****************************************************************************/
+static void NewSubtable(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_extension,
+ void * p_zero)
+{
+ fprintf(stderr, "Adding subtable %d %d\n", i_table_id, i_extension);
+ switch (i_table_id)
+ {
+ case 0x00: /* PAT */
+ if (!dvbpsi_pat_attach(p_dvbpsi, i_table_id, i_extension, DumpPAT, NULL))
+ fprintf(stderr, "Failed to attach PAT decoder\n");
+ break;
+ case 0x02: /* PMT */
+ if (!dvbpsi_pmt_attach(p_dvbpsi, i_table_id, i_extension, DumpPMT, NULL))
+ fprintf(stderr, "Failed to attach PMT decoder\n");
+ break;
+ case 0x4a: /* BAT */
+ if (!dvbpsi_bat_attach(p_dvbpsi, i_table_id, i_extension, DumpBAT, NULL))
+ fprintf(stderr, "failed to attach BAT subdecoder\n");
+ break;
+ }
+}
+
+/*****************************************************************************
+ * DelSubtable
+ *****************************************************************************/
+static void DelSubtable(dvbpsi_t *p_dvbpsi, uint8_t i_table_id, uint16_t i_extension)
+{
+ fprintf(stderr, "Deleting subtable %d %d\n", i_table_id, i_extension);
+ switch (i_table_id)
+ {
+ case 0x00: dvbpsi_pat_detach(p_dvbpsi, i_table_id, i_extension); break;
+ case 0x02: dvbpsi_pmt_detach(p_dvbpsi, i_table_id, i_extension); break;
+ case 0x4a: dvbpsi_bat_detach(p_dvbpsi, i_table_id, i_extension); break;
+ }
+}
+
+/* */
+static int run_chain_demux_test(void)
+{
+ dvbpsi_t *p_dvbpsi = dvbpsi_new(&message, DVBPSI_MSG_DEBUG);
+ if (p_dvbpsi == NULL)
+ return 1;
+
+ if (!dvbpsi_chain_demux_new(p_dvbpsi, NewSubtable, DelSubtable, NULL))
+ goto error;
+
+ uint8_t pkt[2][188];
+ for (int b = 0; b < 2; b++)
+ memset(pkt[b], 0xff, 188);
+ uint8_t pat_pkt [] = {
+ 0x47, 0x40, 0x00, 0x10, 0x00, 0x00, 0xB0, 0x19, 0x00, 0x01, 0xC0, 0x00,
+ 0x0A, 0x00, 0x00, 0xE0, 0x12, 0x00, 0x01, 0xE0, 0x42, 0x00, 0x02, 0xE0,
+ 0x21, 0x00, 0x03, 0xE0, 0x24, 0x19, 0x0E, 0x7B, 0x40,
+ }; /* PAT */
+ memcpy(pkt[0], pat_pkt, 33);
+ uint8_t pmt_pkt[] = {
+ 0x47, 0x42, 0x12, 0x10, 0x00, 0x02, 0xB0, 0x78, 0x00, 0x0C, 0xC0, 0x00,
+ 0x00, 0xE0, 0x2A, 0xF0, 0x33, 0x0C, 0x1A, 0x61, 0x62, 0x63, 0x64, 0x65,
+ 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
+ 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x2A, 0x0C, 0x6D,
+ 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x02,
+ 0x01, 0x65, 0x00, 0x04, 0x68, 0x69, 0x6A, 0x6B, 0x0C, 0xE0, 0x2A, 0xF0,
+ 0x33, 0x0C, 0x1A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+ 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75,
+ 0x76, 0x77, 0x78, 0x79, 0x7A, 0x2A, 0x0C, 0x6D, 0x6E, 0x6F, 0x70, 0x71,
+ 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x02, 0x01, 0x65, 0x00, 0x04,
+ 0x68, 0x69, 0x6A, 0x6B, 0x05, 0xCB, 0xF0, 0xCA,
+ }; /* PMT */
+ memcpy(pkt[1], pmt_pkt, 128);
+
+ for (int i = 0; i < 2; i++)
+ {
+ uint8_t *p_data = pkt[i];
+ dvbpsi_packet_push(p_dvbpsi, p_data);
+ }
+
+#ifdef _TEST_CHAIN_DEBUG
+ dvbpsi_decoder_chain_dump(p_dvbpsi);
+#endif
+
+ if (!dvbpsi_chain_demux_delete(p_dvbpsi))
+ goto error;
+
+ p_dvbpsi->p_decoder = NULL;
+ dvbpsi_delete(p_dvbpsi);
+ fprintf(stderr, "ALL CHAIN DEMUX TESTS PASSED\n");
+ return 0;
+
+error:
+ /* cleanup */
+ if (!dvbpsi_chain_demux_delete(p_dvbpsi))
+ fprintf(stderr, "Failed to cleanup chain_demux after errors\n");
+ p_dvbpsi->p_decoder = NULL;
+ dvbpsi_delete(p_dvbpsi);
+ return 1;
+
+}
+
+/*****************************************************************************
+ * main
+ *****************************************************************************/
+#define CHAIN_DECODERS (20)
+int main(int i_argc, char* pa_argv[])
+{
+ if (run_chain_test(CHAIN_DECODERS) < 0)
+ return 1;
+ if (run_chain_demux_test() < 0)
+ return 1;
+
+ return 0;
}
=====================================
src/chain.c
=====================================
--- a/src/chain.c
+++ b/src/chain.c
@@ -116,7 +116,11 @@ bool dvbpsi_chain_demux_delete(dvbpsi_t *p_dvbpsi)
dvbpsi_decoder_t *p_demux = p_dvbpsi->p_decoder;
if (!p_demux) return false;
- /* Get first subtable decoder */
+ /*
+ * Get first subtable decoder other then the one added in
+ * dvbpsi_chain_demux_new(). It is deleted as last step
+ * in this function.
+ */
dvbpsi_decoder_t *p = p_demux->p_next;
if (!p) goto out;
@@ -125,12 +129,19 @@ bool dvbpsi_chain_demux_delete(dvbpsi_t *p_dvbpsi)
* which walks the list again. This is a waste of time and needs improvement
* on the mechanism on how to create/delete and attach/detach a subtable decoder.
*/
+ dvbpsi_decoder_t *p_next;
while (p) {
- dvbpsi_decoder_t *p_dec = p;
- p = p_dec->p_next;
- if (p_dec->pf_del)
- p_dec->pf_del(p_dvbpsi, p_dec->i_table_id, p_dec->i_extension);
- else dvbpsi_decoder_delete(p_dec);
+ p_next = p->p_next;
+ if (p_demux->pf_del)
+ p_demux->pf_del(p_dvbpsi, p->i_table_id, p->i_extension);
+ else {
+ /*
+ * Delete decoder even when there is no pf_del() callback,
+ * otherwise memory is leaked.
+ */
+ dvbpsi_decoder_delete(p);
+ }
+ p = p_next;
}
out:
=====================================
src/dvbpsi.c
=====================================
--- a/src/dvbpsi.c
+++ b/src/dvbpsi.c
@@ -234,7 +234,6 @@ void dvbpsi_decoder_delete(dvbpsi_decoder_t *p_decoder)
{
assert(p_decoder);
-
if (p_decoder->p_sections)
{
dvbpsi_DeletePSISections(p_decoder->p_sections);
View it on GitLab: https://code.videolan.org/videolan/libdvbpsi/compare/780756255fa3cee630a5cf90e5c519f2d7293e3e...2e65fd5bd0681a0722c614f0636016307d4b7c6e
---
View it on GitLab: https://code.videolan.org/videolan/libdvbpsi/compare/780756255fa3cee630a5cf90e5c519f2d7293e3e...2e65fd5bd0681a0722c614f0636016307d4b7c6e
You're receiving this email because of your account on code.videolan.org.
More information about the libdvbpsi-devel
mailing list