OSDN Git Service

Leave video tracks on the 90KHz MPEG timebase so we don't end up with constantly...
[handbrake-jp/handbrake-jp-git.git] / libhb / render.c
index eead0a7..5c7809d 100644 (file)
@@ -5,9 +5,7 @@
    It may be used under the terms of the GNU General Public License. */
 
 #include "hb.h"
-
-#include "ffmpeg/avcodec.h"
-#include "ffmpeg/swscale.h"
+#include "hbffmpeg.h"
 
 struct hb_work_private_s
 {
@@ -55,13 +53,13 @@ hb_work_object_t hb_render =
  */
 static uint8_t *getU(uint8_t *data, int width, int height, int x, int y)
 {
-    return(&data[(((y/2) * (width/2)) + (x/2)) + (width*height)]);
+    return(&data[(y>>1) * ((width+1)>>1) + (x>>1) + width*height]);
 }
 
 static uint8_t *getV(uint8_t *data, int width, int height, int x, int y)
 {
-    return(&data[(((y/2) * (width/2)) + (x/2)) + (width*height) +
-                 (width*height)/4]);
+    int w2 = (width+1) >> 1, h2 = (height+1) >> 1;
+    return(&data[(y>>1) * w2 + (x>>1) + width*height + w2*h2]);
 }
 
 static void ApplySub( hb_job_t * job, hb_buffer_t * buf,
@@ -208,13 +206,46 @@ int renderWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
     hb_buffer_t * in = *buf_in, * buf_tmp_in = *buf_in;
     hb_buffer_t * ivtc_buffer = NULL;
 
-    if(!in->data)
+    if( in->size <= 0 )
     {
+        hb_buffer_t *head = NULL, *tail = NULL, *next;
+        int counter = 2;
+
         /* If the input buffer is end of stream, send out an empty one
-         * to the next stage as well. Note that this will result in us
-         * losing the current contents of the delay queue.
-         */
-        *buf_out = job->indepth_scan? NULL : hb_buffer_init(0);
+         * to the next stage as well. To avoid losing the contents of
+         * the delay queue connect the buffers in the delay queue in 
+         * the correct order, and add the end of stream buffer to the
+         * end.
+         */     
+        while( next = hb_fifo_get( pv->delay_queue ) )
+        {
+            
+            /* We can't use the given time stamps. Previous frames
+               might already have been extended, throwing off the
+               raw values fed to render.c. Instead, their
+               stop and start times are stored in arrays.
+               The 4th cached frame will be the to use.
+               If it needed its duration extended to make up
+               lost time, it will have happened above. */
+            next->start = pv->last_start[counter];
+            next->stop = pv->last_stop[counter--];
+            
+            if( !head && !tail )
+            {
+                head = tail = next;
+            } else {
+                tail->next = next;
+                tail = next;
+            }
+        }
+        if( tail )
+        {
+            tail->next = in;
+            *buf_out = head;
+        } else {
+            *buf_out = in;
+        }     
+        *buf_in = NULL;
         return HB_WORK_DONE;
     }
 
@@ -247,7 +278,7 @@ int renderWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
     }
 
     /* Setup render buffer */
-    hb_buffer_t * buf_render = hb_buffer_init( 3 * job->width * job->height / 2 );
+    hb_buffer_t * buf_render = hb_video_buffer_init( job->width, job->height );
 
     /* Apply filters */
     if( job->filters )
@@ -310,7 +341,6 @@ int renderWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
                     /* Pop the frame's subtitle and dispose of it. */
                     hb_buffer_t * subtitles = hb_fifo_get( pv->subtitle_queue );
                     hb_buffer_close( &subtitles );
-
                     buf_tmp_in = NULL;
                     break;
                 }
@@ -412,7 +442,7 @@ int renderWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
 
     if( job->vfr )
     {
-        if( hb_fifo_size( pv->delay_queue ) >= 3 )
+        if( hb_fifo_size( pv->delay_queue ) >= 4 )
         {
             *buf_out = hb_fifo_get( pv->delay_queue );
         }
@@ -533,10 +563,7 @@ int renderInit( hb_work_object_t * w, hb_job_t * job )
     w->private_data = pv;
     uint32_t    swsflags;
 
-    swsflags = SWS_LANCZOS;
-#ifndef __x86_64__
-    swsflags |= SWS_ACCURATE_RND;
-#endif  /* __x86_64__ */
+    swsflags = SWS_LANCZOS | SWS_ACCURATE_RND;
 
     /* Get title and title size */
     hb_title_t * title = job->title;