[libdvbpsi-devel] Bugfixes for examples/decode_mpeg.c
Bernhard Ehlers
b-ehlers at gmx.de
Thu Dec 31 12:04:13 CET 2009
Hi,
I'm new to the libdvbpsi and started looking at the example programs.
All but one were working as expected, but decode_mpeg gave me some
headaches.
I used a file with transport stream data and all I got was
"Segmentation fault"
So I had a closer look at the source and found several errors (svn
diff at the end of this mail):
- line 518-523: argument flag for long options should be set
- line 603: filename is in variable filename, not in pa_argv[1]
- line 609 and new code after line 616: give usage message if neither
filename nor ipaddress is used
- line 761: check if p_stream->pmt.handle is set before calling
dvbpsi_DetachPMT.
Otherwise if no PMT was found, the programm aborts.
- all other changes:
The original program expects that ReadPacket and ReadPacketFromSocket
return
i_mtu bytes of data. But ReadPacket give only 188 bytes and the UDP
packets
might be smaller than i_mtu. One way to fix it, is to fiddle with i_mtu.
I choose to change ReadPacket and ReadPacketFromSocket to return the
number
of bytes read (or 0 on EOF or -1 on error).
The program is still not 100% fool proof, but for me that's OK for a
demo program.
The main shortcoming for me is the inability the decode streams with
several programs.
The ts_stream_t struct has room for just one PMT, only the last PMT is
decoded.
Overall I'm very happy with this library, it's mainly the decode_mpeg
demo that
gave me a poor impression at the beginning.
Best regards
Bernhard Ehlers
Index: examples/decode_mpeg.c
===================================================================
--- examples/decode_mpeg.c (revision 187)
+++ examples/decode_mpeg.c (working copy)
@@ -163,7 +163,7 @@
if(i_rc >= 0)
i -= i_rc;
}
- return (i == 0) ? 1 : 0;
+ return (i_rc <= 0) ? i_rc : 188;
}
#ifdef HAVE_SYS_SOCKET_H
@@ -175,7 +175,7 @@
i_rc = read( i_socket, p_dst, i_size );
if( i_rc < 0 ) fprintf( stderr, "READ INTERRUPTED BY SIGNAL\n" );
if( i_rc == 0 ) fprintf( stderr, "READ RETURNS 0\n" );
- return (i_rc <= (int)i_size ) ? 1 : 0;
+ return i_rc;
}
/
*****************************************************************************
@@ -515,12 +515,12 @@
const struct option long_options[] =
{
{ "help", 0, NULL, 'h' },
- { "file", 0, NULL, 'f' },
+ { "file", 1, NULL, 'f' },
#ifdef HAVE_SYS_SOCKET_H
- { "mtu", 0, NULL, 'm' },
- { "port", 0, NULL, 'p' },
- { "udp", 0, NULL, 'u' },
- { "report", 0, NULL, 'r' },
+ { "mtu", 1, NULL, 'm' },
+ { "port", 1, NULL, 'p' },
+ { "udp", 1, NULL, 'u' },
+ { "report", 1, NULL, 'r' },
#endif
{ "verbose", 0, NULL, 'v' },
{ NULL, 0, NULL, 0 }
@@ -545,7 +545,7 @@
uint8_t *p_data = NULL;
ts_stream_t *p_stream = NULL;
- int b_ok = 0;
+ int i_len = 0;
int b_verbose = 0;
/* parser commandline arguments */
@@ -600,13 +600,13 @@
/* initialize */
if( filename )
{
- i_fd = open( pa_argv[1], 0 );
+ i_fd = open( filename, 0 );
p_data = (uint8_t *) malloc( sizeof( uint8_t ) * 188 );
if( !p_data )
goto out_of_memory;
}
#ifdef HAVE_SYS_SOCKET_H
- if( ipaddress )
+ else if( ipaddress )
{
i_fd = create_udp_connection( ipaddress, i_port );
p_data = (uint8_t *) malloc( sizeof( uint8_t ) * i_mtu );
@@ -614,6 +614,12 @@
goto out_of_memory;
}
#endif
+ else
+ {
+ usage( pa_argv[0] );
+ goto error;
+ }
+
p_stream = (ts_stream_t *) malloc( sizeof(ts_stream_t) );
if( !p_stream )
goto out_of_memory;
@@ -621,16 +627,10 @@
/* Read first packet */
if( filename )
- {
- b_ok = ReadPacket( i_fd, p_data );
- i_bytes += 188;
- }
+ i_len = ReadPacket( i_fd, p_data );
#ifdef HAVE_SYS_SOCKET_H
else
- {
- b_ok = ReadPacketFromSocket( i_fd, p_data, i_mtu );
- i_bytes += i_mtu;
- }
+ i_len = ReadPacketFromSocket( i_fd, p_data, i_mtu );
/* print the right report header */
report_Header( i_report );
@@ -638,12 +638,13 @@
/* Enter infinite loop */
p_stream->pat.handle = dvbpsi_AttachPAT( DumpPAT, p_stream );
- while( b_ok )
+ while( i_len > 0 )
{
int i = 0;
vlc_bool_t b_first = VLC_FALSE;
- for( i = 0; i < i_mtu; i += 188 )
+ i_bytes += i_len;
+ for( i = 0; i < i_len; i += 188 )
{
uint8_t *p_tmp = &p_data[i];
uint16_t i_pid = ((uint16_t)(p_tmp[1] & 0x1f) << 8) +
p_tmp[2];
@@ -746,19 +747,14 @@
/* Read next packet */
if( filename )
- {
- b_ok = ReadPacket( i_fd, p_data );
- i_bytes += 188;
- }
+ i_len = ReadPacket( i_fd, p_data );
#ifdef HAVE_SYS_SOCKET_H
else
- {
- b_ok = ReadPacketFromSocket( i_fd, p_data, i_mtu );
- i_bytes += i_mtu;
- }
+ i_len = ReadPacketFromSocket( i_fd, p_data, i_mtu );
#endif
}
- dvbpsi_DetachPMT( p_stream->pmt.handle );
+ if( p_stream->pmt.handle )
+ dvbpsi_DetachPMT( p_stream->pmt.handle );
dvbpsi_DetachPAT( p_stream->pat.handle );
/* clean up */
More information about the libdvbpsi-devel
mailing list