All pastes #840147 Raw Edit

Mine

public diff v1 · immutable
#840147 ·published 2007-12-31 15:12 UTC
rendered paste body
Index: libhb/stream.c===================================================================--- libhb/stream.c	(revision 1154)+++ libhb/stream.c	(working copy)@@ -108,22 +108,75 @@ static void hb_ps_stream_find_audio_ids(hb_stream_t *stream, hb_title_t *title); static off_t align_to_next_packet(FILE* f); -int hb_stream_is_stream_type( char * path )++static inline int check_ps_sync(const uint8_t *buf) {-  if ((strstr(path,".mpg") != NULL) ||-      (strstr(path,".vob") != NULL) || -      (strstr(path, ".VOB") != NULL) ||-      (strstr(path, ".mpeg") != NULL) ||-      (strstr(path,".ts") != NULL) || -      (strstr(path, ".m2t") != NULL) ||-      (strstr(path, ".TS") != NULL))-  {-    return 1;-  }-  else+    // must have a Pack header+    // (note: the operator '&' instead of '&&' is used deliberately for better+    // performance with a multi-issue pipeline.)+    return (buf[0] == 0x00) & (buf[1] == 0x00) & (buf[2] == 0x01) & (buf[3] == 0xba);+}++static inline int check_ts_sync(const uint8_t *buf)+{+    // must have initial sync byte, no scrambling & a legal adaptation ctrl+    return (buf[0] == 0x47) & ((buf[3] >> 6) == 0) & ((buf[3] >> 4) > 0);+}++static inline int have_ts_sync(const uint8_t *buf)+{+    return check_ts_sync(&buf[0*188]) & check_ts_sync(&buf[1*188]) &+           check_ts_sync(&buf[2*188]) & check_ts_sync(&buf[3*188]) &+           check_ts_sync(&buf[4*188]) & check_ts_sync(&buf[5*188]) &+           check_ts_sync(&buf[6*188]) & check_ts_sync(&buf[7*188]);+}++static int hb_stream_check_for_ts(const uint8_t *buf)+{+    // transport streams should have a sync byte every 188 bytes.+    // search the first KB of buf looking for at least 8 consecutive+    // correctly located sync patterns.+    int offset = 0;++    for ( offset = 0; offset < 1024; ++offset )+    {+        if ( have_ts_sync( &buf[offset]) )+            return 1;+    }     return 0; } +static int hb_stream_check_for_ps(const uint8_t *buf)+{+    // program streams should have a Pack header every 2048 bytes.+    // check that we have 4 of these.+    return check_ps_sync(&buf[0*2048]) & check_ps_sync(&buf[1*2048]) &+           check_ps_sync(&buf[2*2048]) & check_ps_sync(&buf[3*2048]);+}++static int hb_stream_get_type(hb_stream_t *stream)+{+    uint8_t buf[2048*4];++    if ( fread(buf, 1, sizeof(buf), stream->file_handle) == sizeof(buf) )+    {+        if ( hb_stream_check_for_ts(buf) != 0 )+        {+            hb_log("file is MPEG Transport Stream");+            stream->stream_type = hb_stream_type_transport;+            hb_ts_stream_init(stream);+            return 1;+        }+        if ( hb_stream_check_for_ps(buf) != 0 )+        {+            hb_log("file is MPEG Program Stream");+            stream->stream_type = hb_stream_type_program;+            return 1;+        }+    }+    return 0;+}+ /***********************************************************************  * hb_stream_open  ***********************************************************************@@ -136,27 +189,20 @@     d = calloc( sizeof( hb_stream_t ), 1 );      /* Open device */-    if( !( d->file_handle = fopen( path, "rb" ) ) )+    if( ( d->file_handle = fopen( path, "rb" ) ) )     {+        d->path = strdup( path );+        if ( hb_stream_get_type( d ) != 0 )+        {+            return d;+        }+        fclose( d->file_handle );+        free( d->path );+    }+    else+    {         hb_log( "hb_stream_open: fopen failed (%s)", path );-        goto fail;     }--    d->path = strdup( path );--	if ( ( strstr(d->path,".ts") != NULL) || ( strstr(d->path,".m2t") != NULL) || ( strstr(d->path,".TS") != NULL) )-	{-		d->stream_type = hb_stream_type_transport;-		hb_ts_stream_init(d);-	}-	else if (( strstr(d->path,".mpg") != NULL) || ( strstr(d->path,".vob") != NULL) || ( strstr(d->path,".mpeg") != NULL) || ( strstr(d->path,".VOB") != NULL))-	{-		d->stream_type = hb_stream_type_program;-	}-	-    return d;--fail:     free( d );     return NULL; }@@ -194,7 +240,7 @@ 			d->ts_packetbuf[i] = NULL; 		} 	}-	+    free( d->path );     free( d );     *_d = NULL; }@@ -277,12 +323,70 @@   return aTitle; } +/*+ * scan the next MB of 'stream' to find the next start packet for+ * the Packetized Elementary Stream associated with TS PID 'pid'.+ */+static const uint8_t *hb_ts_stream_getPEStype(hb_stream_t *stream, uint32_t pid)+{+    static uint8_t buf[188];+    int npack = 100000; // max packets to read++    while (--npack >= 0)+    {+        if (fread(buf, 1, 188, stream->file_handle) != 188)+        {+            hb_log("hb_ts_stream_getPEStype: EOF while searching for PID 0x%x", pid);+            return 0;+        }+        if (buf[0] != 0x47)+        {+            hb_log("hb_ts_stream_getPEStype: lost sync while searching for PID 0x%x", pid);+            align_to_next_packet(stream->file_handle);+            continue;+        }++        /*+         * The PES header is only in TS packets with 'start' set so we check+         * that first then check for the right PID.+         */+        if ((buf[1] & 0x40) == 0 || (buf[1] & 0x1f) != (pid >> 8) ||+            buf[2] != (pid & 0xff))+        {+            // not a start packet or not the pid we want+            continue;+        }++        /* skip over the TS hdr to return a pointer to the PES hdr */+        int udata = 4;+        switch (buf[3] & 0x30)+        {+            case 0x00: // illegal+            case 0x20: // fill packet+                continue;++            case 0x30: // adaptation+                if (buf[4] > 182)+                {+                    hb_log("hb_ts_stream_getPEStype: invalid adaptation field length %d for PID 0x%x", buf[4], pid);+                    continue;+                }+                udata += buf[4] + 1;+                break;+        }+        return &buf[udata];+    }++    /* didn't find it */+    return 0;+}+ /***********************************************************************  * hb_stream_duration  ***********************************************************************  *  **********************************************************************/-void hb_stream_duration(hb_stream_t *stream, hb_title_t *inTitle)+static void hb_stream_duration(hb_stream_t *stream, hb_title_t *inTitle) { 	// VOB Files often have exceedingly unusual PTS values in them - they will progress for a while 	// and then reset without warning ! @@ -297,109 +401,70 @@ 		return; 	} -    unsigned char *buf = (unsigned char *) malloc(4096);-    int done = 0;-    off_t cur_pos;-    int64_t first_pts = 0, last_pts = 0;+    uint64_t first_pts, last_pts;+    const uint8_t *buf;     -    // To calculate the duration we look for the first and last presentation time stamps in the stream for video data-    // and then use the delta-    while (!done)+    // To calculate the duration we get video presentation time stamps+    // at a couple places in the file then use their difference scaled+    // by the ratio of the distance between our measurement points &+    // the size of the file. The issue is that our video file may have+    // chunks from several different program fragments (main feature,+    // commercials, station id, trailers, etc.) all with their on base+    // pts value. We need to difference two pts's from the same program+    // fragment. Since extraneous material is very likely at the beginning+    // and end of the content, for now we take a time stamp from 25%+    // into the file & 75% into the file then double their difference+    // to get the total duration.+    fseeko(stream->file_handle, 0, SEEK_END);+    uint64_t fsize = ftello(stream->file_handle);+    fseeko(stream->file_handle, fsize >> 2, SEEK_SET);+    align_to_next_packet(stream->file_handle);+    buf = hb_ts_stream_getPEStype(stream, stream->ts_video_pids[0]);+    if (buf == NULL)     {-      cur_pos = ftello(stream->file_handle);-      if (fread(buf, 4096, 1, stream->file_handle) == 1)-      {-        int i=0;-        for (i=0; (i <= 4092) && !done; i++)-        {-          if ((buf[i] == 0x00) && (buf[i+1] == 0x00) && (buf[i+2] == 0x01) && (buf[i+3]  == 0xe0))    // Found a Video Stream-          {-              // Now look for a PTS field - we need to make sure we have enough space so we back up a little and read-              // some more data-              fseeko(stream->file_handle, cur_pos + i, SEEK_SET);-              if (fread(buf, 4096, 1, stream->file_handle) == 1)-              {-                  int has_pts             = ( ( buf[7] >> 6 ) & 0x2 ) ? 1 : 0;-                  if (has_pts)-                  {-                    first_pts = ( ( ( (uint64_t) buf[9] >> 1 ) & 0x7 ) << 30 ) +-                          ( buf[10] << 22 ) +-                          ( ( buf[11] >> 1 ) << 15 ) +-                          ( buf[12] << 7 ) +-                          ( buf[13] >> 1 );-                    done = 1;-                  }-                  else-                  {-                    fseeko(stream->file_handle, cur_pos, SEEK_SET);-                    fread(buf, 4096, 1, stream->file_handle);-                  }-              }-          }-        }-      }-      else-        done = 1;    // End of data;+        hb_log("hb_stream_duration: couldn't find video start packet");+        return;     }--    // Now work back from the end of the stream-    fseeko(stream->file_handle,0 ,SEEK_END);-    -    done = 0;-    while (!done)+    if ((buf[7] >> 7) != 1)     {-      // Back up a little-      if (fseeko(stream->file_handle, -4096, SEEK_CUR) < 0)-      {-        done = 1;-        break;-      }-      -      cur_pos = ftello(stream->file_handle);-      if (fread(buf, 4096, 1, stream->file_handle) == 1)-      {-        int i=0;-        for (i=4092; (i >= 0) && !done; i--)-        {-          if ((buf[i] == 0x00) && (buf[i+1] == 0x00) && (buf[i+2] == 0x01) && (buf[i+3] == 0xe0))    // Found a Video Stream-          {-              // Now look for a PTS field - we need to make sure we have enough space so we back up a little and read-              // some more data-              fseeko(stream->file_handle, cur_pos + i, SEEK_SET);-              fread(buf, 1, 4096, stream->file_handle);+        hb_log("hb_stream_duration: no PTS in initial video packet");+        return;+    }+    first_pts = ( ( (uint64_t)buf[9] >> 1 ) & 7 << 30 ) |+                ( (uint64_t)buf[10] << 22 ) |+                ( ( (uint64_t)buf[11] >> 1 ) << 15 ) |+                ( (uint64_t)buf[12] << 7 ) |+                ( (uint64_t)buf[13] >> 1 );+    hb_log("hb_stream_duration: first pts %lld", first_pts); -              int has_pts             = ( ( buf[7] >> 6 ) & 0x2 ) ? 1 : 0;-              if (has_pts)-              {-                last_pts = ( ( ( (uint64_t) buf[9] >> 1 ) & 0x7 ) << 30 ) +-                      ( buf[10] << 22 ) +-                      ( ( buf[11] >> 1 ) << 15 ) +-                      ( buf[12] << 7 ) +-                      ( buf[13] >> 1 );-                -                done = 1;-              }-              else-              {-                // Re Read the original data and carry on (i is still valid in the old buffer)-                fseeko(stream->file_handle, cur_pos, SEEK_SET);-                fread(buf, 4096, 1, stream->file_handle);-              }-          }-        }-        fseeko(stream->file_handle, -4096, SEEK_CUR);   // 'Undo' the last read-      }-      else-        done = 1;    // End of data;+    // now get a pts from a frame near the end of the file.+    fseeko(stream->file_handle, fsize - (fsize >> 2), SEEK_SET);+    align_to_next_packet(stream->file_handle);+    buf = hb_ts_stream_getPEStype(stream, stream->ts_video_pids[0]);+    if (buf == NULL)+    {+        hb_log("hb_stream_duration: couldn't find video end packet");+        return;     }-    free(buf);-    -    int64_t duration = last_pts - first_pts;-    inTitle->duration = duration; //90LL * dvdtime2msec( &d->pgc->playback_time );+    if ((buf[7] >> 7) != 1)+    {+        hb_log("hb_stream_duration: no PTS in final video packet");+        inTitle->duration = 0;+        return;+    }+    last_pts = ( ( (uint64_t)buf[9] >> 1 ) & 7 << 30 ) |+                ( (uint64_t)buf[10] << 22 ) |+                ( ( (uint64_t)buf[11] >> 1 ) << 15 ) |+                ( (uint64_t)buf[12] << 7 ) |+                ( (uint64_t)buf[13] >> 1 );+    hb_log("hb_stream_duration: last pts %lld", last_pts);++    inTitle->duration = (last_pts - first_pts) * 2 + 90000 * 60;     inTitle->hours    = inTitle->duration / 90000 / 3600;     inTitle->minutes  = ( ( inTitle->duration / 90000 ) % 3600 ) / 60;     inTitle->seconds  = ( inTitle->duration / 90000 ) % 60;-    ++    rewind(stream->file_handle); }  /***********************************************************************@@ -521,75 +586,17 @@   return 1; } -/*- * scan the first MB of 'stream' to try and determine the type of the Packetized- * Elementary Stream associated with TS PID 'pid'.- */-static const uint8_t *hb_ts_stream_getPEStype(hb_stream_t *stream, uint32_t pid)-{-    static uint8_t buf[188];-    int npack = 100000; // max packets to read--    fseeko(stream->file_handle, 0, SEEK_SET);-    align_to_next_packet(stream->file_handle);--    while (--npack >= 0)-    {-        if (fread(buf, 1, 188, stream->file_handle) != 188)-        {-            hb_log("hb_ts_stream_getPEStype: EOF while searching for PID 0x%x", pid);-            return 0;-        }-        if (buf[0] != 0x47)-        {-            hb_log("hb_ts_stream_getPEStype: lost sync while searching for PID 0x%x", pid);-            align_to_next_packet(stream->file_handle);-            continue;-        }--        /*-         * The PES header is only in TS packets with 'start' set so we check-         * that first then check for the right PID.-         */-        if ((buf[1] & 0x40) == 0 || (buf[1] & 0x1f) != (pid >> 8) ||-            buf[2] != (pid & 0xff))-        {-            // not a start packet or not the pid we want-            continue;-        }--        /* skip over the TS hdr to return a pointer to the PES hdr */-        int udata = 4;-        switch (buf[3] & 0x30)-        {-            case 0x00: // illegal-            case 0x20: // fill packet-                continue;--            case 0x30: // adaptation-                if (buf[4] > 182)-                {-                    hb_log("hb_ts_stream_getPEStype: invalid adaptation field length %d for PID 0x%x", buf[4], pid);-                    continue;-                }-                udata += buf[4] + 1;-                break;-        }-        return &buf[udata];-    }--    /* didn't find it */-    return 0;-}- static hb_audio_t *hb_ts_stream_set_audio_id_and_codec(hb_stream_t *stream,                                                        int aud_pid_index) {     off_t cur_pos = ftello(stream->file_handle);     hb_audio_t *audio = calloc( sizeof( hb_audio_t ), 1 );-    const uint8_t *buf = hb_ts_stream_getPEStype(stream,-                                            stream->ts_audio_pids[aud_pid_index]);+    const uint8_t *buf; +    fseeko(stream->file_handle, 0, SEEK_SET);+    align_to_next_packet(stream->file_handle);+    buf = hb_ts_stream_getPEStype(stream, stream->ts_audio_pids[aud_pid_index]);+     /* check that we found a PES header */     if (buf && buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x01)     {@@ -1826,29 +1833,19 @@ 		return; 	} 	-	int bytesReadInPacket = 0; 	int curr_write_buffer_index = stream->ps_current_write_buffer_index; 	 	// Write output data until a buffer switch occurs. 	while (curr_write_buffer_index == stream->ps_current_write_buffer_index) 	{-		// Try to read packet..-		int bytesRead;-		if ((bytesRead = fread(buf+bytesReadInPacket, 1, 188-bytesReadInPacket, stream->file_handle)) != 188-bytesReadInPacket)+      if ((fread(buf, 188, 1, stream->file_handle)) != 1) 		{-			if (bytesRead < 0)-				bytesRead = 0;-			bytesReadInPacket += bytesRead;--			// Flush any outstanding output data - we're done here.-			flushbuf(stream);-			break;+            // end of file - we didn't finish filling our ps write buffer+            // so just discard the remainder (the partial buffer is useless)+            hb_log("hb_ts_stream_decode - eof");+            stream->ps_decode_buffer[stream->ps_current_write_buffer_index].len = 0;+         return; 		}-		else-		{-//			curfilepos += bytesRead;-			bytesReadInPacket = 0;-		}  		// Check sync byte 		if ((buf[0] != 0x47) && (buf[0] != 0x72) && (buf[0] != 0x29))@@ -1866,40 +1863,24 @@ 		// Get pid 		int pid = (((buf[1] & 0x1F) << 8) | buf[2]) & 0x1FFF; -		// Skip this block-		if (index_of_pid(pid, stream) < 0)-			continue;-//		if (pid != stream->ts_audio_pids[0] && pid != stream->ts_video_pids[0])-//			continue;- 		// Get the pos and buf - we organize our streams as 'n' video streams then 'm' audio streams-		int index_of_selected_pid = -1;+      int index_of_selected_pid; 		if ((index_of_selected_pid = index_of_video_pid(pid,stream)) < 0) 		{ 			// Not a video PID perhaps audio ? 			if ((index_of_selected_pid = index_of_audio_pid(pid,stream)) < 0) 			{-				hb_log("hb_ts_stream_decode - Unknown pid 0x%x (%d)", pid, pid);+            // not a pid we want 				continue; 			} 			else 			{ 				curstream = stream->ts_number_video_pids + index_of_selected_pid;-				if (curstream > kMaxNumberDecodeStreams)-				{-					hb_log("hb_ts_stream_decode - Too many streams %d", curstream);-					continue;-				} 			} 		} 		else 			curstream = index_of_selected_pid; 		-//		if (pid == stream->ts_video_pids[0])-//			curstream = 0;-//		else-//			curstream = 1;- 		// Get start code 		int start; 		start = (buf[1] & 0x40) != 0;Index: libhb/sync.c===================================================================--- libhb/sync.c	(revision 1154)+++ libhb/sync.c	(working copy)@@ -827,8 +827,8 @@         /*          * Trash the top audio packet to avoid dead lock as we reconverge.          */-        buf = hb_fifo_get( audio->fifo_raw );-        hb_buffer_close( &buf ); +        if ( (buf = hb_fifo_get( audio->fifo_raw ) ) != NULL)+            hb_buffer_close( &buf );     }      if( NeedSilence( w, audio ) )Index: libhb/internal.h===================================================================--- libhb/internal.h	(revision 1154)+++ libhb/internal.h	(working copy)@@ -133,14 +133,12 @@ int          hb_dvd_is_break( hb_dvd_t * d ); void         hb_dvd_close( hb_dvd_t ** ); -int         hb_stream_is_stream_type( char * path); hb_stream_t * hb_stream_open( char * path ); void		 hb_stream_close( hb_stream_t ** ); hb_title_t * hb_stream_title_scan( hb_stream_t *); int          hb_stream_read( hb_stream_t *, hb_buffer_t *); int          hb_stream_seek( hb_stream_t *, float ); void		 hb_stream_update_audio( hb_stream_t *, hb_audio_t *);-void		 hb_stream_set_selected_audio_pid_index(hb_stream_t *, int);  /***********************************************************************  * Work objectsIndex: libhb/scan.c===================================================================--- libhb/scan.c	(revision 1154)+++ libhb/scan.c	(working copy)@@ -70,19 +70,14 @@             }         }     }+    else if ( (data->stream = hb_stream_open (data->path)) != NULL )+    {+        hb_list_add( data->list_title, hb_stream_title_scan( data->stream ) );+    }     else     {-        if ( hb_stream_is_stream_type(data->path) )-        {-          hb_log( "scan: trying to open as MPEG-2 Stream");-		  data->stream = hb_stream_open (data->path);-          hb_list_add( data->list_title, hb_stream_title_scan( data->stream ) );-        }-        else-        {-            hb_log( "scan: unrecognized file type" );-            return;-        }+        hb_log( "scan: unrecognized file type" );+        return;     }      for( i = 0; i < hb_list_count( data->list_title ); )Index: macosx/Controller.mm===================================================================--- macosx/Controller.mm	(revision 1154)+++ macosx/Controller.mm	(working copy)@@ -1081,8 +1081,8 @@                 returnCode: (int) returnCode contextInfo: (void *) contextInfo {     /* we convert the sender content of contextInfo back into a variable called sender-    * mostly just for consistency for evaluation later-    */+     * mostly just for consistency for evaluation later+     */     id sender = (id)contextInfo;     /* User selected a file to open */ 	if( returnCode == NSOKButton )@@ -1093,17 +1093,17 @@         NSString *sourceDirectory = [scanPath stringByDeletingLastPathComponent];         [[NSUserDefaults standardUserDefaults] setObject:sourceDirectory forKey:@"LastSourceDirectory"];         /* we order out sheet, which is the browse window as we need to open-            * the title selection sheet right away-            */+         * the title selection sheet right away+         */         [sheet orderOut: self];                  if (sender == fOpenSourceTitleMMenu)         {             /* We put the chosen source path in the source display text field for the-            * source title selection sheet in which the user specifies the specific title to be-            * scanned  as well as the short source name in fSrcDsplyNameTitleScan just for display-            * purposes in the title panel-            */+             * source title selection sheet in which the user specifies the specific title to be+             * scanned  as well as the short source name in fSrcDsplyNameTitleScan just for display+             * purposes in the title panel+             */             /* Full Path */             [fScanSrcTitlePathField setStringValue: [NSString stringWithFormat:@"%@", scanPath]];             NSString *displayTitlescanSourceName;@@ -1111,7 +1111,7 @@             if ([[scanPath lastPathComponent] isEqualToString: @"VIDEO_TS"])             {                 /* If VIDEO_TS Folder is chosen, choose its parent folder for the source display name -                we have to use the title->dvd value so we get the proper name of the volume if a physical dvd is the source*/+                 we have to use the title->dvd value so we get the proper name of the volume if a physical dvd is the source*/                 displayTitlescanSourceName = [NSString stringWithFormat:[[scanPath stringByDeletingLastPathComponent] lastPathComponent]];             }             else@@ -1122,15 +1122,56 @@             /* we set the source display name in the title selection dialogue */             [fSrcDsplyNameTitleScan setStringValue: [NSString stringWithFormat:@"%@", displayTitlescanSourceName]];             /* We show the actual sheet where the user specifies the title to be scanned -                * as we are going to do a title specific scan-                */+             * as we are going to do a title specific scan+             */             [self showSourceTitleScanPanel:NULL];         }         else         {             /* We are just doing a standard full source scan, so we specify "0" to libhb */             NSString *path = [[sheet filenames] objectAtIndex: 0];-            [self performScan:path scanTitleNum:0];   +            +            /* We check to see if the chosen file at path is a package */+            if ([[NSWorkspace sharedWorkspace] isFilePackageAtPath:path])+            {+                fprintf( stdout, "MacGui: Trying to open a package\n");+                /* We check to see if this is an .eyetv package */+                if ([[path pathExtension] isEqualToString: @"eyetv"])+                {+                    fprintf( stdout, "MacGui: Trying to open eyetv package\n");+                    /* We're looking at an EyeTV package - try to open its enclosed+                     .mpg media file */+                    NSString *mpgname;+                    int n = [[path stringByAppendingString: @"/"]+                             completePathIntoString: &mpgname caseSensitive: NO+                             matchesIntoArray: nil+                             filterTypes: [NSArray arrayWithObject: @"mpg"]];+                    if (n > 0)+                    {+                        /* Found an mpeg inside the eyetv package, make it our scan path +                        and call performScan on the enclosed mpeg */+                        path = mpgname;+                        fprintf( stdout, "MacGui: found mpeg in eyetv package\n");+                        [self performScan:path scanTitleNum:0];+                    }+                    else+                    {+                        /* We did not find an mpeg file in our package, so we do not call performScan */+                        fprintf( stdout, "MacGui: no valid mpeg in eyetv package\n");+                    }+                }+                else+                {+                    /* The package is not an eyetv package, so we do not call performScan */+                    fprintf( stdout, "MacGui: Unable to open package\n");+                }+            }+            else+            {+                /* path is not a package, so we call perform scan directly on our file */+                [self performScan:path scanTitleNum:0];+            }+                     }              }@@ -1251,6 +1292,12 @@                 we have to use the title->dvd value so we get the proper name of the volume if a physical dvd is the source*/                 sourceDisplayName = [NSString stringWithFormat:[[[NSString stringWithUTF8String: title->dvd] stringByDeletingLastPathComponent] lastPathComponent]];             }+            else if ([[NSString stringWithUTF8String: title->dvd] rangeOfString: @".eyetv/"].length != 0)+            {+                /* Use the name of the EyeTV package instead of the media file */+                sourceDisplayName = [NSString stringWithFormat: @"%@",+                                     [[[[NSString stringWithUTF8String: title->dvd] stringByDeletingLastPathComponent] lastPathComponent] stringByDeletingPathExtension]];+            }             else             {                 /* if not the VIDEO_TS Folder, we can assume the chosen folder is the source name */