[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