+static hb_buffer_t *hb_copy_frame( hb_job_t *job, int width, int height,
+ uint8_t* y, uint8_t *u, uint8_t *v )
+{
+ int dst_w = width, dst_h = height;
+ if ( job )
+ {
+ dst_w = job->title->width;
+ dst_h = job->title->height;
+ }
+ int dst_wh = dst_w * dst_h;
+ hb_buffer_t *buf = hb_video_buffer_init( dst_w, dst_h );
+
+ if ( dst_w != width || dst_h != height )
+ {
+ // we're encoding and the frame dimensions don't match the title dimensions -
+ // rescale & matte Y, U, V into our output buf.
+ AVPicture in, out;
+ avpicture_alloc(&in, PIX_FMT_YUV420P, width, height );
+ avpicture_alloc(&out, PIX_FMT_YUV420P, dst_w, dst_h );
+
+ int src_wh = width * height;
+ memcpy( in.data[0], y, src_wh );
+ memcpy( in.data[1], u, src_wh >> 2 );
+ memcpy( in.data[2], v, src_wh >> 2 );
+ struct SwsContext *context = sws_getContext( width, height, PIX_FMT_YUV420P,
+ dst_w, dst_h, PIX_FMT_YUV420P,
+ SWS_LANCZOS|SWS_ACCURATE_RND,
+ NULL, NULL, NULL );
+ sws_scale( context, in.data, in.linesize, 0, height, out.data, out.linesize );
+ sws_freeContext( context );
+
+ u_int8_t *data = buf->data;
+ memcpy( data, out.data[0], dst_wh );
+ data += dst_wh;
+ // U & V planes are 1/4 the size of Y plane.
+ dst_wh >>= 2;
+ memcpy( data, out.data[1], dst_wh );
+ data += dst_wh;
+ memcpy( data, out.data[2], dst_wh );
+
+ avpicture_free( &out );
+ avpicture_free( &in );
+ }
+ else
+ {
+ // we're scanning or the frame dimensions match the title's dimensions
+ // so we can do a straight copy.
+ u_int8_t *data = buf->data;
+ memcpy( data, y, dst_wh );
+ data += dst_wh;
+ // U & V planes are 1/4 the size of Y plane.
+ dst_wh >>= 2;
+ memcpy( data, u, dst_wh );
+ data += dst_wh;
+ memcpy( data, v, dst_wh );
+ }
+ return buf;
+}
+