- PMT generator;

  - example (gen_pmt);
  - fixed a non-null pointer in 'descriptor.c';
  - cosmetic changes;
  - generators review and comments.
parent c2f3a9d7
......@@ -11,5 +11,5 @@ C: bozo
D: main structure
D: PSI section gathering
D: PAT decoder/generator
D: PMT decoder
D: PMT decoder/generator
## Process this file with automake to produce Makefile.in
noinst_PROGRAMS = gen_crc gen_pat
noinst_PROGRAMS = gen_crc gen_pat gen_pmt
gen_crc_SOURCES = gen_crc.c
gen_pat_SOURCES = gen_pat.c
gen_pat_LDFLAGS = -L../src -ldvbpsi
gen_pmt_SOURCES = gen_pmt.c
gen_pmt_LDFLAGS = -L../src -ldvbpsi
......@@ -74,16 +74,19 @@ RANLIB = @RANLIB@
STRIP = @STRIP@
VERSION = @VERSION@
noinst_PROGRAMS = gen_crc gen_pat
noinst_PROGRAMS = gen_crc gen_pat gen_pmt
gen_crc_SOURCES = gen_crc.c
gen_pat_SOURCES = gen_pat.c
gen_pat_LDFLAGS = -L../src -ldvbpsi
gen_pmt_SOURCES = gen_pmt.c
gen_pmt_LDFLAGS = -L../src -ldvbpsi
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../src/config.h
CONFIG_CLEAN_FILES =
noinst_PROGRAMS = gen_crc$(EXEEXT) gen_pat$(EXEEXT)
noinst_PROGRAMS = gen_crc$(EXEEXT) gen_pat$(EXEEXT) gen_pmt$(EXEEXT)
PROGRAMS = $(noinst_PROGRAMS)
......@@ -98,6 +101,9 @@ gen_crc_LDFLAGS =
gen_pat_OBJECTS = gen_pat.$(OBJEXT)
gen_pat_LDADD = $(LDADD)
gen_pat_DEPENDENCIES =
gen_pmt_OBJECTS = gen_pmt.$(OBJEXT)
gen_pmt_LDADD = $(LDADD)
gen_pmt_DEPENDENCIES =
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
......@@ -110,9 +116,9 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP_ENV = --best
DEP_FILES = .deps/gen_crc.P .deps/gen_pat.P
SOURCES = $(gen_crc_SOURCES) $(gen_pat_SOURCES)
OBJECTS = $(gen_crc_OBJECTS) $(gen_pat_OBJECTS)
DEP_FILES = .deps/gen_crc.P .deps/gen_pat.P .deps/gen_pmt.P
SOURCES = $(gen_crc_SOURCES) $(gen_pat_SOURCES) $(gen_pmt_SOURCES)
OBJECTS = $(gen_crc_OBJECTS) $(gen_pat_OBJECTS) $(gen_pmt_OBJECTS)
all: all-redirect
.SUFFIXES:
......@@ -180,6 +186,10 @@ gen_pat$(EXEEXT): $(gen_pat_OBJECTS) $(gen_pat_DEPENDENCIES)
@rm -f gen_pat$(EXEEXT)
$(LINK) $(gen_pat_LDFLAGS) $(gen_pat_OBJECTS) $(gen_pat_LDADD) $(LIBS)
gen_pmt$(EXEEXT): $(gen_pmt_OBJECTS) $(gen_pmt_DEPENDENCIES)
@rm -f gen_pmt$(EXEEXT)
$(LINK) $(gen_pmt_LDFLAGS) $(gen_pmt_OBJECTS) $(gen_pmt_LDADD) $(LIBS)
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP)
......
/*****************************************************************************
* gen_pmt.c: PMT generator
*----------------------------------------------------------------------------
* (c)2001-2002 VideoLAN
* $Id: gen_pmt.c,v 1.1 2002/01/09 11:22:26 bozo Exp $
*
* Authors: Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*----------------------------------------------------------------------------
*
*****************************************************************************/
#include "config.h"
#include <stdio.h>
/* the libdvbpsi distribution defines DVBPSI_DIST */
#ifdef DVBPSI_DIST
#include "../src/dvbpsi.h"
#include "../src/psi.h"
#include "../src/descriptor.h"
#include "../src/pmt.h"
#else
#include <dvbpsi/dvbpsi.h>
#include <dvbpsi/psi.h>
#include <dvbpsi/descriptor.h>
#include <dvbpsi/pmt.h>
#endif
/*****************************************************************************
* writePSI
*****************************************************************************/
void writePSI(uint8_t* p_packet, dvbpsi_psi_section_t* p_section)
{
p_packet[0] = 0x47;
while(p_section)
{
uint8_t* p_pos_in_ts;
uint8_t* p_byte = p_section->p_data;
uint8_t* p_end = p_section->p_payload_end
+ (p_section->b_syntax_indicator ? 4 : 0);
p_packet[1] |= 0x40;
p_packet[3] = (p_packet[3] & 0x0f) | 0x10;
p_packet[4] = 0x00; /* pointer_field */
p_pos_in_ts = p_packet + 5;
while((p_pos_in_ts < p_packet + 188) && (p_byte < p_end))
*(p_pos_in_ts++) = *(p_byte++);
while(p_pos_in_ts < p_packet + 188)
*(p_pos_in_ts++) = 0xff;
fwrite(p_packet, 1, 188, stdout);
p_packet[3] = (p_packet[3] + 1) & 0x0f;
while(p_byte < p_end)
{
p_packet[1] &= 0xbf;
p_packet[3] = (p_packet[3] & 0x0f) | 0x10;
p_pos_in_ts = p_packet + 4;
while((p_pos_in_ts < p_packet + 188) && (p_byte < p_end))
*(p_pos_in_ts++) = *(p_byte++);
while(p_pos_in_ts < p_packet + 188)
*(p_pos_in_ts++) = 0xff;
fwrite(p_packet, 1, 188, stdout);
p_packet[3] = (p_packet[3] + 1) & 0x0f;
}
p_section = p_section->p_next;
}
}
/*****************************************************************************
* main
*****************************************************************************/
int main(int i_argc, char* pa_argv[])
{
uint8_t packet[188];
char data[] = "abcdefghijklmnopqrstuvwxyz";
dvbpsi_pmt_t pmt;
dvbpsi_pmt_es_t* p_es;
dvbpsi_psi_section_t* p_section1, * p_section2;
dvbpsi_psi_section_t* p_section3, * p_section4;
dvbpsi_psi_section_t* p_section5, * p_section6;
/* PMT generation */
dvbpsi_InitPMT(&pmt, 12, 0, 0, 42);
dvbpsi_PMTAddDescriptor(&pmt, 12, 26, data);
dvbpsi_PMTAddDescriptor(&pmt, 42, 12, data + 12);
dvbpsi_PMTAddDescriptor(&pmt, 2, 1, data + 4);
dvbpsi_PMTAddDescriptor(&pmt, 0, 4, data + 7);
p_es = dvbpsi_PMTAddES(&pmt, 12, 42);
dvbpsi_PMTESAddDescriptor(p_es, 12, 26, data);
dvbpsi_PMTESAddDescriptor(p_es, 42, 12, data + 12);
dvbpsi_PMTESAddDescriptor(p_es, 2, 1, data + 4);
dvbpsi_PMTESAddDescriptor(p_es, 0, 4, data + 7);
p_section1 = dvbpsi_GenPMTSections(&pmt);
pmt.b_current_next = 1;
p_section2 = dvbpsi_GenPMTSections(&pmt);
pmt.i_version = 1;
pmt.b_current_next = 0;
p_section3 = dvbpsi_GenPMTSections(&pmt);
pmt.b_current_next = 1;
p_section4 = dvbpsi_GenPMTSections(&pmt);
pmt.i_version = 2;
pmt.b_current_next = 0;
p_section5 = dvbpsi_GenPMTSections(&pmt);
pmt.b_current_next = 1;
p_section6 = dvbpsi_GenPMTSections(&pmt);
/* TS packets generation */
packet[0] = 0x47;
packet[1] = 0x02;
packet[2] = 0x12;
packet[3] = 0x00;
writePSI(packet, p_section1);
writePSI(packet, p_section2);
writePSI(packet, p_section3);
writePSI(packet, p_section4);
writePSI(packet, p_section5);
writePSI(packet, p_section6);
dvbpsi_DeletePSISection(p_section1);
dvbpsi_DeletePSISection(p_section2);
dvbpsi_DeletePSISection(p_section3);
dvbpsi_DeletePSISection(p_section4);
dvbpsi_DeletePSISection(p_section5);
dvbpsi_DeletePSISection(p_section6);
dvbpsi_EmptyPMT(&pmt);
return 0;
}
......@@ -2,7 +2,7 @@
* descriptor.c: descriptors functions
*----------------------------------------------------------------------------
* (c)2001-2002 VideoLAN
* $Id: descriptor.c,v 1.2 2002/01/07 18:44:03 bozo Exp $
* $Id: descriptor.c,v 1.3 2002/01/09 11:22:26 bozo Exp $
*
* Authors: Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr>
*
......@@ -54,6 +54,7 @@ dvbpsi_descriptor_t* dvbpsi_NewDescriptor(uint8_t i_tag, uint8_t i_length,
p_descriptor->i_tag = i_tag;
p_descriptor->i_length = i_length;
memcpy(p_descriptor->p_data, p_data, i_length);
p_descriptor->p_next = NULL;
}
else
{
......
......@@ -2,7 +2,7 @@
* pat.c: PAT decoder/generator
*----------------------------------------------------------------------------
* (c)2001-2002 VideoLAN
* $Id: pat.c,v 1.2 2002/01/07 19:35:45 bozo Exp $
* $Id: pat.c,v 1.3 2002/01/09 11:22:26 bozo Exp $
*
* Authors: Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr>
*
......@@ -352,26 +352,29 @@ dvbpsi_psi_section_t* dvbpsi_GenPATSections(dvbpsi_pat_t* p_pat,
{
dvbpsi_psi_section_t* p_result = dvbpsi_NewPSISection(1024);
dvbpsi_psi_section_t* p_current = p_result;
dvbpsi_psi_section_t* p_prev = p_result;
dvbpsi_psi_section_t* p_prev;
dvbpsi_pat_program_t* p_program = p_pat->p_first_program;
int i_count = 0;
/* A PAT section can carry up to 253 programs */
if((i_max_pps <= 0) || (i_max_pps > 253))
i_max_pps = 253;
p_current->i_table_id = 0;
p_current->b_syntax_indicator = 1;
p_current->b_private_indicator = 0;
p_current->i_length = 9;
p_current->i_length = 9; /* header + CRC_32 */
p_current->i_extension = p_pat->i_ts_id;
p_current->i_version = p_pat->i_version;
p_current->b_current_next = p_pat->b_current_next;
p_current->i_number = 0;
p_current->p_payload_end += 8;
p_current->p_payload_end += 8; /* just after the header */
p_current->p_payload_start = p_current->p_payload_end;
/* PAT programs */
while(p_program != NULL)
{
/* New section if needed */
if(++i_count > i_max_pps)
{
p_prev = p_current;
......@@ -382,25 +385,29 @@ dvbpsi_psi_section_t* dvbpsi_GenPATSections(dvbpsi_pat_t* p_pat,
p_current->i_table_id = 0;
p_current->b_syntax_indicator = 1;
p_current->b_private_indicator = 0;
p_current->i_length = 9;
p_current->i_length = 9; /* header + CRC_32 */
p_current->i_extension = p_pat->i_ts_id;
p_current->i_version = p_pat->i_version;
p_current->b_current_next = p_pat->b_current_next;
p_current->i_number = p_prev->i_number + 1;
p_current->p_payload_end += 8;
p_current->p_payload_end += 8; /* just after the header */
p_current->p_payload_start = p_current->p_payload_end;
}
p_current->p_payload_end[0] = (p_program->i_number >> 8) & 0xff;
p_current->p_payload_end[1] = p_program->i_number & 0xff;
p_current->p_payload_end[2] = (p_program->i_pid >> 8) & 0xff;
p_current->p_payload_end[3] = p_program->i_pid & 0xff;
/* p_payload_end is where the program begins */
p_current->p_payload_end[0] = p_program->i_number >> 8;
p_current->p_payload_end[1] = p_program->i_number;
p_current->p_payload_end[2] = (p_program->i_pid >> 8) | 0xe0;
p_current->p_payload_end[3] = p_program->i_pid;
/* Increase length by 4 */
p_current->p_payload_end += 4;
p_current->i_length += 4;
p_program = p_program->p_next;
}
/* Finalization */
p_prev = p_result;
while(p_prev != NULL)
{
......
......@@ -2,7 +2,7 @@
* pmt.c: PMT decoder/generator
*----------------------------------------------------------------------------
* (c)2001-2002 VideoLAN
* $Id: pmt.c,v 1.2 2002/01/07 19:35:45 bozo Exp $
* $Id: pmt.c,v 1.3 2002/01/09 11:22:26 bozo Exp $
*
* Authors: Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr>
*
......@@ -447,3 +447,188 @@ void dvbpsi_DecodePMTSection(dvbpsi_decoder_t* p_decoder,
dvbpsi_DeletePSISection(p_section);
}
/*****************************************************************************
* dvbpsi_GenPMTSections
*****************************************************************************
* Generate PMT sections based on the dvbpsi_pmt_t structure.
*****************************************************************************/
dvbpsi_psi_section_t* dvbpsi_GenPMTSections(dvbpsi_pmt_t* p_pmt)
{
dvbpsi_psi_section_t* p_result = dvbpsi_NewPSISection(1024);
dvbpsi_psi_section_t* p_current = p_result;
dvbpsi_psi_section_t* p_prev;
dvbpsi_descriptor_t* p_descriptor = p_pmt->p_first_descriptor;
dvbpsi_pmt_es_t* p_es = p_pmt->p_first_es;
uint16_t i_info_length;
p_current->i_table_id = 0x02;
p_current->b_syntax_indicator = 1;
p_current->b_private_indicator = 0;
p_current->i_length = 13; /* header + CRC_32 */
p_current->i_extension = p_pmt->i_program_number;
p_current->i_version = p_pmt->i_version;
p_current->b_current_next = p_pmt->b_current_next;
p_current->i_number = 0;
p_current->p_payload_end += 12; /* just after the header */
p_current->p_payload_start = p_current->p_data + 8;
/* PCR_PID */
p_current->p_data[8] = (p_pmt->i_pcr_pid >> 8) | 0xe0;
p_current->p_data[9] = p_pmt->i_pcr_pid;
/* PMT descriptors */
while(p_descriptor != NULL)
{
/* New section if needed */
/* written_data_length + descriptor_length + 2 > 1024 - CRC_32_length */
if( (p_current->p_payload_end - p_current->p_data)
+ p_descriptor->i_length > 1018)
{
/* program_info_length */
i_info_length = (p_current->p_payload_end - p_current->p_data) - 12;
p_current->p_data[10] = (i_info_length >> 8) | 0xf0;
p_current->p_data[11] = i_info_length;
p_prev = p_current;
p_current = dvbpsi_NewPSISection(1024);
p_prev->p_next = p_current;
p_current->i_table_id = 0x02;
p_current->b_syntax_indicator = 1;
p_current->b_private_indicator = 0;
p_current->i_length = 13; /* header + CRC_32 */
p_current->i_extension = p_pmt->i_program_number;
p_current->i_version = p_pmt->i_version;
p_current->b_current_next = p_pmt->b_current_next;
p_current->i_number = p_prev->i_number + 1;
p_current->p_payload_end += 12; /* just after the header */
p_current->p_payload_start = p_current->p_data + 8;
/* PCR_PID */
p_current->p_data[8] = (p_pmt->i_pcr_pid >> 8) | 0xe0;
p_current->p_data[9] = p_pmt->i_pcr_pid;
}
/* p_payload_end is where the descriptor begins */
p_current->p_payload_end[0] = p_descriptor->i_tag;
p_current->p_payload_end[1] = p_descriptor->i_length;
memcpy(p_current->p_payload_end + 2,
p_descriptor->p_data,
p_descriptor->i_length);
/* Increase length by descriptor_length + 2 */
p_current->p_payload_end += p_descriptor->i_length + 2;
p_current->i_length += p_descriptor->i_length + 2;
p_descriptor = p_descriptor->p_next;
}
/* program_info_length */
i_info_length = (p_current->p_payload_end - p_current->p_data) - 12;
p_current->p_data[10] = (i_info_length >> 8) | 0xf0;
p_current->p_data[11] = i_info_length;
/* PMT ESs */
while(p_es != NULL)
{
uint8_t* p_es_start = p_current->p_payload_end;
uint16_t i_es_length = 5;
/* Can the current section carry all the descriptors ? */
p_descriptor = p_es->p_first_descriptor;
while( (p_descriptor != NULL)
&& ((p_es_start - p_current->p_data) + i_es_length <= 1020))
{
i_es_length += p_descriptor->i_length + 2;
}
/* If _no_ and the current section isn't empty and an empty section
may carry one more descriptor
then create a new section */
if( (p_descriptor != NULL)
&& (p_es_start - p_current->p_data != 12)
&& (i_es_length <= 1008))
{
/* will put more descriptors in an empty section */
DVBPSI_DEBUG("PMT generator",
"create a new section to carry more ES descriptors");
p_prev = p_current;
p_current = dvbpsi_NewPSISection(1024);
p_prev->p_next = p_current;
p_current->i_table_id = 0x02;
p_current->b_syntax_indicator = 1;
p_current->b_private_indicator = 0;
p_current->i_length = 13; /* header + CRC_32 */
p_current->i_extension = p_pmt->i_program_number;
p_current->i_version = p_pmt->i_version;
p_current->b_current_next = p_pmt->b_current_next;
p_current->i_number = p_prev->i_number + 1;
p_current->p_payload_end += 12; /* just after the header */
p_current->p_payload_start = p_current->p_data + 8;
/* PCR_PID */
p_current->p_data[8] = (p_pmt->i_pcr_pid >> 8) | 0xe0;
p_current->p_data[9] = p_pmt->i_pcr_pid;
/* program_info_length */
i_info_length = 0;
p_current->p_data[10] = 0xf0;
p_current->p_data[11] = 0x00;
p_es_start = p_current->p_payload_end;
}
/* p_es_start is where the ES begins */
p_es_start[0] = p_es->i_type;
p_es_start[1] = (p_es->i_pid >> 8) | 0xe0;
p_es_start[2] = p_es->i_pid;
/* Increase the length by 5 */
p_current->p_payload_end += 5;
p_current->i_length += 5;
/* ES descriptors */
p_descriptor = p_es->p_first_descriptor;
while( (p_descriptor != NULL)
&& ( (p_current->p_payload_end - p_current->p_data)
+ p_descriptor->i_length <= 1018))
{
/* p_payload_end is where the descriptor begins */
p_current->p_payload_end[0] = p_descriptor->i_tag;
p_current->p_payload_end[1] = p_descriptor->i_length;
memcpy(p_current->p_payload_end + 2,
p_descriptor->p_data,
p_descriptor->i_length);
/* Increase length by descriptor_length + 2 */
p_current->p_payload_end += p_descriptor->i_length + 2;
p_current->i_length += p_descriptor->i_length + 2;
p_descriptor = p_descriptor->p_next;
}
if(p_descriptor != NULL)
DVBPSI_ERROR("PMT generator", "unable to carry all the ES descriptors");
/* ES_info_length */
i_es_length = p_current->p_payload_end - p_es_start - 5;
p_es_start[3] = (i_es_length >> 8) | 0xf0;
p_es_start[4] = i_es_length;
p_es = p_es->p_next;
}
/* Finalization */
p_prev = p_result;
while(p_prev != NULL)
{
p_prev->i_last_number = p_current->i_number;
dvbpsi_BuildPSISection(p_prev);
p_prev = p_prev->p_next;
}
return p_result;
}
......@@ -2,7 +2,7 @@
* pmt.h: PMT structures
*----------------------------------------------------------------------------
* (c)2001-2002 VideoLAN
* $Id: pmt.h,v 1.1 2002/01/07 18:30:35 bozo Exp $
* $Id: pmt.h,v 1.2 2002/01/09 11:22:26 bozo Exp $
*
* Authors: Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr>
*
......@@ -153,6 +153,14 @@ dvbpsi_descriptor_t* dvbpsi_PMTESAddDescriptor(dvbpsi_pmt_es_t* p_es,
uint8_t* p_data);
/*****************************************************************************
* dvbpsi_GenPMTSections
*****************************************************************************
* Generate PMT sections based on the dvbpsi_pmt_t structure.
*****************************************************************************/
dvbpsi_psi_section_t* dvbpsi_GenPMTSections(dvbpsi_pmt_t* p_pmt);
#else
#error "Multiple inclusions of pmt.h"
#endif
......
......@@ -2,7 +2,7 @@
* psi.c: common PSI functions
*----------------------------------------------------------------------------
* (c)2001-2002 VideoLAN
* $Id: psi.c,v 1.1 2002/01/07 18:30:35 bozo Exp $
* $Id: psi.c,v 1.2 2002/01/09 11:22:26 bozo Exp $
*
* Authors: Arnaud de Bossoreille de Ribou <bozo@via.ecp.fr>
*
......@@ -211,7 +211,7 @@ int dvbpsi_ValidPSISection(dvbpsi_psi_section_t* p_section)
else
{
DVBPSI_ERROR_ARG("misc PSI",
"Bad CRC_32 (0x%08x) !!!!!!!!!!!!!!!!!!!!", i_crc);
"Bad CRC_32 (0x%08x) !!!", i_crc);
return 0;
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment