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
{
*/
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,
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;
}
}
/* 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 )
/* 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;
}
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 );
}
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;