[MEncoder-users] Segmentation fault when reading certain DVDs

Dave Hill mplayer at davidrhill.com
Mon Mar 30 05:12:50 CEST 2009


Hi,

I have a bug to report along with a proposal for a fix.

I've been getting a segmentation fault when trying to convert some dvds 
to avi.  The most recent case was a copy of a season of The Office that 
I created using k9copy to create an iso from the original and then k3b 
to burn it.  That must have somehow created a non-standard dvd header 
which libdvdread complains about at initialization.  However, this does 
not appear to effect mencoder's ability to read the DVD data.

This is the first pass of a two-pass encode, but it segmentation faults 
at the end.  Here is the output:

[root at dtv-fe mplayer]#  mencoder -ffourcc DIVX -ovc lavc -lavcopts 
vpass=1:turbo:vcodec=mpeg4:vhq:v4mv:vqmin=2:autoaspect:vbitrate=1500 
-alang en -vf scale=640:-2 -af volume=10 -oac mp3lame dvd://4 -endpos 30 
-o /dev/null -of avi
MEncoder SVN-r29105-4.3.2 (C) 2000-2009 MPlayer Team
libdvdread: Using libdvdcss version 1.2.10 for DVD access

*** libdvdread: CHECK_VALUE failed in libdvdread4/ifo_read.c:1263 ***
*** for ptl_mait->nr_of_vtss != 0 ***

*** Zero check failed in libdvdread4/ifo_read.c:1292
    for ptl_mait->countries[i].zero_1 = 0x0024
*** Zero check failed in libdvdread4/ifo_read.c:1293
    for ptl_mait->countries[i].zero_2 = 0x032c
*** Zero check failed in libdvdread4/ifo_read.c:1292
    for ptl_mait->countries[i].zero_1 = 0x0634
*** Zero check failed in libdvdread4/ifo_read.c:1293
    for ptl_mait->countries[i].zero_2 = 0x093c
*** Zero check failed in libdvdread4/ifo_read.c:1292
    for ptl_mait->countries[i].zero_1 = 0x0c44
*** Zero check failed in libdvdread4/ifo_read.c:1293
    for ptl_mait->countries[i].zero_2 = 0x0f4c
*** Zero check failed in libdvdread4/ifo_read.c:1292
    for ptl_mait->countries[i].zero_1 = 0x1254
*** Zero check failed in libdvdread4/ifo_read.c:1293
    for ptl_mait->countries[i].zero_2 = 0x0307

*** libdvdread: CHECK_VALUE failed in libdvdread4/ifo_read.c:1295 ***
*** for ptl_mait->countries[i].pf_ptl_mai_start_byte + 8*2 * 
(ptl_mait->nr_of_vtss + 1) <= ptl_mait->last_byte + 1 ***

libdvdread: Unable to seak PTL_MAIT table.
There are 22 titles on this DVD.
There are 1 angles in this DVD title.

.
.
.
Pos:  30.0s    738f ( 2%) 106.57fps Trem:   4min 235mb  A-V:0.017 [1292:233]
Flushing video frames.
Writing index...
Writing header...
ODML: vprp aspect is 16:9.

Video stream: 1292.172 kbit/s  (161521 B/s)  size: 4850491 bytes  30.030 
secs  738 frames

Audio stream:  233.229 kbit/s  (29153 B/s)  size: 874608 bytes  30.000 secs
Segmentation fault



I downloaded the source, rebuilt with debugging and found the issue.  It 
was crashing at:
Program received signal SIGSEGV, Segmentation fault.
0x0816aebb in ifoFree_PTL_MAIT (ifofile=0x8b1e1a8)
    at libdvdread4/ifo_read.c:1352


The issue was that some of the pointers were being freed earlier (at the 
"Unable to seak PTL_MAIT"), but there was still a reference to that 
freed memory that was being double-freed later.

I wasn't sure where/who to tell about the fix - hopefully, I'm posting 
it to the right place. 

Dave

[root at dtv-fe mplayer]# svn diff libdvdread4/
Index: libdvdread4/ifo_read.c
===================================================================
--- libdvdread4/ifo_read.c    (revision 1168)
+++ libdvdread4/ifo_read.c    (working copy)
@@ -1304,18 +1304,21 @@
       fprintf(stderr, "libdvdread: Unable to seak PTL_MAIT table.\n");
       free(ptl_mait->countries);
       free(ptl_mait);
+      ifofile->ptl_mait = 0;
       return 0;
     }
     info_length = (ptl_mait->nr_of_vtss + 1) * sizeof(pf_level_t);
     pf_temp = (uint16_t *)malloc(info_length);
     if(!pf_temp) {
       free_ptl_mait(ptl_mait, i);
+      ifofile->ptl_mait = 0;
       return 0;
     }
     if(!(DVDReadBytes(ifofile->file, pf_temp, info_length))) {
       fprintf(stderr, "libdvdread: Unable to read PTL_MAIT table.\n");
       free(pf_temp);
       free_ptl_mait(ptl_mait, i);
+      ifofile->ptl_mait = 0;
       return 0;
     }
     for (j = 0; j < ((ptl_mait->nr_of_vtss + 1) * 8); j++) {
@@ -1325,6 +1328,7 @@
     if(!ptl_mait->countries[i].pf_ptl_mai) {
       free(pf_temp);
       free_ptl_mait(ptl_mait, i);
+      ifofile->ptl_mait = 0;
       return 0;
     }
     { /* Transpose the array so we can use C indexing. */
@@ -1349,7 +1353,8 @@
 
   if(ifofile->ptl_mait) {
     for(i = 0; i < ifofile->ptl_mait->nr_of_countries; i++) {
-      free(ifofile->ptl_mait->countries[i].pf_ptl_mai);
+        if (ifofile->ptl_mait->countries[i].pf_ptl_mai)
+            free(ifofile->ptl_mait->countries[i].pf_ptl_mai);
     }
     free(ifofile->ptl_mait->countries);
     free(ifofile->ptl_mait);
[root at dtv-fe mplayer]#



More information about the MEncoder-users mailing list