All pastes #1093056 Raw Edit

patch for chapter location speci

public text v1 · immutable
#1093056 ·published 2008-08-05 02:24 UTC
rendered paste body
Index: test/test.c
===================================================================
--- test/test.c	(revision 1601)
+++ test/test.c	(working copy)
@@ -318,11 +318,17 @@
     for( i = 0; i < hb_list_count( title->list_chapter ); i++ )
     {
         chapter = hb_list_item( title->list_chapter, i );
-        fprintf( stderr, "    + %d: cells %d->%d, %d blocks, duration "
-                 "%02d:%02d:%02d\n", chapter->index,
-                 chapter->cell_start, chapter->cell_end,
-                 chapter->block_count, chapter->hours, chapter->minutes,
-                 chapter->seconds );
+	if (chapter->use_frame)
+	    fprintf( stderr, "    + %d: frame=%lld, duration "
+		     "%02d:%02d:%02d\n", chapter->index,
+		     chapter->frame, chapter->hours, chapter->minutes,
+		     chapter->seconds );
+	else
+	    fprintf( stderr, "    + %d: cells %d->%d, %d blocks, duration "
+		     "%02d:%02d:%02d\n", chapter->index,
+		     chapter->cell_start, chapter->cell_end,
+		     chapter->block_count, chapter->hours, chapter->minutes,
+		     chapter->seconds );
     }
     fprintf( stderr, "  + audio tracks:\n" );
     for( i = 0; i < hb_list_count( title->list_audio ); i++ )
@@ -452,18 +458,6 @@
             /* Set job settings */
             job   = title->job;
 
-            PrintTitleInfo( title );
-
-            if( chapter_start && chapter_end )
-            {
-                job->chapter_start = MAX( job->chapter_start,
-                                          chapter_start );
-                job->chapter_end   = MIN( job->chapter_end,
-                                          chapter_end );
-                job->chapter_end   = MAX( job->chapter_start,
-                                          job->chapter_end );
-            }
-
             if (preset)
             {
                 fprintf( stderr, "+ Using preset: %s", preset_name);
@@ -719,6 +713,12 @@
                     int row = 0;
                     int chapter = 0;
 
+		    /* extract chapter 1 as see if it was a stream, if
+		       so we need to allocate a chapter for each row
+		       of the marker file. */
+		    hb_chapter_t* chapter1 = hb_list_item( job->title->list_chapter, 0);
+		    int alloc_chapters = (chapter1 && chapter1->use_frame);
+
                     fprintf( stderr, "Reading chapter markers from file %s\n", marker_file );
 
                     if( file == NULL )
@@ -740,8 +740,17 @@
                             /* We have a chapter name */
                             if( cell->cell_col == 1 && row == cell->cell_row )
                             {
-                                /* If we have a valid chapter, copy the string an terminate it */
-                                if( chapter >= job->chapter_start && chapter <= job->chapter_end )
+			        /* if the chapter in the marker file doesn't yet exist, add one */
+				if (alloc_chapters && !hb_list_item( job->title->list_chapter, chapter - 1)) {
+				    hb_chapter_t * new_chapter_p;
+				    new_chapter_p = calloc( sizeof( hb_chapter_t ), 1 );
+				    new_chapter_p->index = chapter;
+				    hb_list_add( job->title->list_chapter, new_chapter_p );
+				}
+
+                                /* If we have a valid chapter, copy the string an terminate it.
+				   NOTE: if allocating chapters the chapter_start and chapter_end are not yet valid. */
+			        if( alloc_chapters || (chapter >= job->chapter_start && chapter <= job->chapter_end) )
                                 {
                                     hb_chapter_t * chapter_s;
 
@@ -751,11 +760,79 @@
                                 }
                             }
 
+                            /* We have a chapter frame location --
+			       this value will be ignored if not for a
+			       ffmpeg or transport stream */
+                            if( cell->cell_col == 2 && row == cell->cell_row )
+                            {
+                                /* If we have a valid chapter, record the frame number.
+				   NOTE: if allocating chapters the chapter_start and chapter_end are not yet valid. */
+			        if( alloc_chapters || (chapter >= job->chapter_start && chapter <= job->chapter_end) )
+                                {
+                                    hb_chapter_t * chapter_s;
 
+                                    chapter_s = hb_list_item( job->title->list_chapter, chapter - 1);
+                                    chapter_s->frame = atoi( cell->cell_text );
+				    chapter_s->use_frame = 1;
+                                }
+                            }
+
+
                             hb_dispose_cell( cell );
                         }
 
                         hb_close_csv_file( file );
+
+			if (alloc_chapters) {
+			    /* if we were allocating chapters as we went, we have some cleanup to do */
+			    /* we need to fill in the duration information, the total title duration 
+			       is in chapter 1 from the title scan */
+			  
+			    /* precalculate the amount of duration used by each from from the fps */
+			    uint64_t duration_per_frame = 90000LL * job->title->rate_base / job->title->rate;
+
+			    /* setup the loop with chapter 1 */
+			    hb_chapter_t* last_chapter_p = hb_list_item( job->title->list_chapter, 0);
+			    uint64_t rem_duration = last_chapter_p->duration/*title duration*/;
+			    int number_of_chapters = hb_list_count(job->title->list_chapter);
+			    int chapter;
+			    int seconds;
+
+			    for(chapter = 2; chapter <= number_of_chapters ; chapter++)
+			    {
+			        /* get next chapter */
+				hb_chapter_t * chapter_p;
+				chapter_p = hb_list_item( job->title->list_chapter, chapter - 1);
+
+				/* calculate duration used by previous chapter */
+				last_chapter_p->duration = (chapter_p->frame - last_chapter_p->frame) * duration_per_frame;
+
+				/* keep track of whats still left */
+				rem_duration -= last_chapter_p->duration;
+
+				/* make the pretty version of duration */
+				seconds = ( last_chapter_p->duration + 45000 ) / 90000;
+				last_chapter_p->hours    = seconds / 3600;
+				last_chapter_p->minutes  = ( seconds % 3600 ) / 60;
+				last_chapter_p->seconds  = seconds % 60;
+
+				/* keep previous chapter around to fill in next */
+				last_chapter_p = chapter_p;
+			    }
+
+			    /* final chapter goes for rem_duration */
+			    last_chapter_p->duration = rem_duration;
+			    seconds                  = ( rem_duration + 45000 ) / 90000;
+			    last_chapter_p->hours    = seconds / 3600;
+			    last_chapter_p->minutes  = ( seconds % 3600 ) / 60;
+			    last_chapter_p->seconds  = seconds % 60;
+
+			    /* setup the chapter_start/end correctly
+			       now that we know how many chapters
+			       there are */
+			    job->chapter_start = 1;
+			    job->chapter_end   = number_of_chapters;
+			}
                     }
                 }
                 else
@@ -775,6 +852,18 @@
                 }
 			}
 
+            PrintTitleInfo( title );
+
+            if( chapter_start && chapter_end )
+            {
+                job->chapter_start = MAX( job->chapter_start,
+                                          chapter_start );
+                job->chapter_end   = MIN( job->chapter_end,
+                                          chapter_end );
+                job->chapter_end   = MAX( job->chapter_start,
+                                          job->chapter_end );
+            }
+
             if( crop[0] >= 0 && crop[1] >= 0 &&
                 crop[2] >= 0 && crop[3] >= 0 )
             {
Index: libhb/stream.c
===================================================================
--- libhb/stream.c	(revision 1601)
+++ libhb/stream.c	(working copy)
@@ -101,6 +101,8 @@
     int     last_error_count;   /* # errors at last error message */
     int     packetsize;         /* Transport Stream packet size */
 
+    int     last_chapter;       /* chapter number of last seen chapter */
+
     int64_t ts_lastpcr;         /* the last pcr we found in the TS stream */
     int64_t ts_nextpcr;         /* the next pcr to put in a PS packet */
 
@@ -176,10 +178,11 @@
 /***********************************************************************
  * Local prototypes
  **********************************************************************/
+static int hb_stream_chapter_start( hb_stream_t *stream );
 static void hb_stream_duration(hb_stream_t *stream, hb_title_t *inTitle);
 static void hb_ts_stream_init(hb_stream_t *stream);
 static void hb_ts_stream_find_pids(hb_stream_t *stream);
-static int hb_ts_stream_decode(hb_stream_t *stream, uint8_t *obuf);
+static int hb_ts_stream_decode(hb_stream_t *stream, hb_buffer_t *b);
 static void hb_ts_stream_reset(hb_stream_t *stream);
 static hb_audio_t *hb_ts_stream_set_audio_id_and_codec(hb_stream_t *stream,
                                                        int aud_pid_index);
@@ -612,6 +615,7 @@
     // One Chapter
     hb_chapter_t * chapter;
     chapter = calloc( sizeof( hb_chapter_t ), 1 );
+    chapter->use_frame = 1;
     chapter->index = 1;
     chapter->duration = aTitle->duration;
     chapter->hours = aTitle->hours;
@@ -1021,7 +1025,7 @@
         }
         return 1;
     }
-    return hb_ts_stream_decode( src_stream, b->data );
+    return hb_ts_stream_decode( src_stream, b );
 }
 
 /***********************************************************************
@@ -2045,8 +2049,9 @@
  ***********************************************************************
  *
  **********************************************************************/
-static int hb_ts_stream_decode( hb_stream_t *stream, uint8_t *obuf )
+static int hb_ts_stream_decode( hb_stream_t *stream, hb_buffer_t *b )
 {
+    uint8_t* obuf = b->data;
     /*
      * stash the output buffer pointer in our stream so we don't have to
      * pass it & its original value to everything we call.
@@ -2186,6 +2191,7 @@
                     stream->ts_foundfirst[0] = 1;
                 }
                 ++stream->frames;
+		b->new_chap = hb_stream_chapter_start(stream);
             }
 			else if ( ! stream->ts_foundfirst[curstream] )
             {
@@ -2500,6 +2506,7 @@
     // One Chapter
     hb_chapter_t * chapter;
     chapter = calloc( sizeof( hb_chapter_t ), 1 );
+    chapter->use_frame = 1;
     chapter->index = 1;
     chapter->duration = title->duration;
     chapter->hours = title->hours;
@@ -2546,6 +2553,33 @@
     return (int64_t)( (double)pts * conv_factor );
 }
 
+static int hb_stream_chapter_start( hb_stream_t *stream )
+{
+    /* only look for chapter start if not scanning */
+    if (stream->title) {
+      int chapter = stream->last_chapter + 1;
+      hb_chapter_t * chapter_p;
+      chapter_p = hb_list_item( stream->title->list_chapter, chapter - 1);      
+
+      /* just in case we somehow missed the frame for a chapter walk
+	 forward until we are in the right place */
+      while (chapter_p->frame < stream->frames) {
+	  ++chapter;
+	  ++stream->last_chapter;
+	  chapter_p = hb_list_item( stream->title->list_chapter, chapter - 1);
+      }
+
+      /* return this chapter if we just read the start frame */
+      if (chapter_p->frame == stream->frames) {
+	hb_log("start of chapter %d read", chapter);
+	stream->last_chapter = chapter;
+	return chapter;
+      }
+    }
+
+    return 0;
+}
+
 static int ffmpeg_read( hb_stream_t *stream, hb_buffer_t *buf )
 {
     AVPacket pkt;
@@ -2568,6 +2602,10 @@
                   av_q2d(stream->ffmpeg_ic->streams[pkt.stream_index]->time_base)*90000. );
     buf->renderOffset = av_to_hb_pts( pkt.pts,
                   av_q2d(stream->ffmpeg_ic->streams[pkt.stream_index]->time_base)*90000. );
+
+    ++stream->frames;
+    buf->new_chap = hb_stream_chapter_start(stream);
+
     av_free_packet( &pkt );
     return 1;
 }
Index: libhb/common.h
===================================================================
--- libhb/common.h	(revision 1601)
+++ libhb/common.h	(working copy)
@@ -390,6 +390,12 @@
     int      block_end;
     int      block_count;
 
+    /* 1 if chapter is a bogus chapter for the full title (see
+       stream.c), or frame location specified in marker file */
+    int      use_frame;
+    /* chapter location specified from marker file */
+    uint64_t frame;
+
     /* Visual-friendly duration */
     int      hours;
     int      minutes;