summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2011-03-11 22:09:18 +0000
committerjstebbins <[email protected]>2011-03-11 22:09:18 +0000
commit4aaed20c697c1a7e8fe7e039cf1949a320758286 (patch)
tree20b74827cd388858f54de02dd26e0b4887eed9e6
parentcfcf5367aeda3ee5c64ab7b79d855e8136799fac (diff)
Fix PAR and height of mpeg-2 1080 content.
mpeg-2 dimensions must be multiples of 16, so the actual coded height is 1088. But there are fields in the sequence header that define the "display" height and width. We were ignoring these which lead to slightly incorrect height and PAR. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@3838 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--libhb/decmpeg2.c104
1 files changed, 46 insertions, 58 deletions
diff --git a/libhb/decmpeg2.c b/libhb/decmpeg2.c
index 6604ac1ea..6f7c8e7e1 100644
--- a/libhb/decmpeg2.c
+++ b/libhb/decmpeg2.c
@@ -257,71 +257,48 @@ static void next_tag( hb_libmpeg2_t *m, hb_buffer_t *buf_es )
}
static hb_buffer_t *hb_copy_frame( hb_job_t *job, int width, int height,
- enum PixelFormat pixfmt,
+ int *crop, enum PixelFormat pixfmt,
uint8_t* y, uint8_t *u, uint8_t *v )
{
- int dst_w = width, dst_h = height;
+ int dst_w, dst_h;
+ int src_w, src_h;
+
+ src_w = width - (crop[2] + crop[3]);
+ src_h = height - (crop[0] + crop[1]);
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 );
- buf->start = -1;
-
- if ( dst_w != width || dst_h != height || pixfmt == PIX_FMT_YUV422P )
- {
- // 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, pixfmt, width, height );
- avpicture_alloc(&out, PIX_FMT_YUV420P, dst_w, dst_h );
-
- int src_wh = width * height;
- if ( pixfmt == PIX_FMT_YUV422P )
- {
- memcpy( in.data[0], y, src_wh );
- memcpy( in.data[1], u, src_wh >> 1 );
- memcpy( in.data[2], v, src_wh >> 1 );
- }
- else
- {
- 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 = hb_sws_get_context( width, height, pixfmt,
- dst_w, dst_h, PIX_FMT_YUV420P,
- SWS_LANCZOS|SWS_ACCURATE_RND);
- sws_scale( context, in.data, in.linesize, 0, height, out.data, out.linesize );
- sws_freeContext( context );
-
- uint8_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.
- uint8_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 );
+ dst_w = src_w;
+ dst_h = src_h;
}
+
+ hb_buffer_t *buf = hb_video_buffer_init( dst_w, dst_h );
+ buf->start = -1;
+
+ AVPicture in, out, pic_crop;
+
+ in.data[0] = y;
+ in.data[1] = u;
+ in.data[2] = v;
+ in.linesize[0] = width;
+ in.linesize[1] = width>>1;
+ in.linesize[2] = width>>1;
+ avpicture_fill( &out, buf->data, PIX_FMT_YUV420P, dst_w, dst_h );
+
+ av_picture_crop( &pic_crop, &in, pixfmt, crop[0], crop[2] );
+
+ // Source and Dest dimensions may be the same. There is no speed
+ // cost to using sws_scale to simply copy the data.
+ struct SwsContext *context = hb_sws_get_context( src_w, src_h, pixfmt,
+ dst_w, dst_h, PIX_FMT_YUV420P,
+ SWS_LANCZOS|SWS_ACCURATE_RND);
+ sws_scale( context, pic_crop.data, pic_crop.linesize, 0, src_h, out.data, out.linesize );
+ sws_freeContext( context );
+
return buf;
}
@@ -383,8 +360,8 @@ static int hb_libmpeg2_decode( hb_libmpeg2_t * m, hb_buffer_t * buf_es,
{
if( !( m->width && m->height && m->rate ) )
{
- m->width = m->info->sequence->width;
- m->height = m->info->sequence->height;
+ m->width = m->info->sequence->display_width;
+ m->height = m->info->sequence->display_height;
m->rate = m->info->sequence->frame_period;
if ( m->aspect_ratio <= 0 && m->height &&
m->info->sequence->pixel_height )
@@ -430,8 +407,19 @@ static int hb_libmpeg2_decode( hb_libmpeg2_t * m, hb_buffer_t * buf_es,
if( m->got_iframe )
{
- buf = hb_copy_frame( m->job, m->info->sequence->width,
+ int crop[4] = {0};
+ if ( m->info->sequence->display_width < m->info->sequence->width )
+ {
+ crop[3] = m->info->sequence->width - m->info->sequence->display_width;
+ }
+ if ( m->info->sequence->display_height < m->info->sequence->height )
+ {
+ crop[1] = m->info->sequence->height - m->info->sequence->display_height;
+ }
+ buf = hb_copy_frame( m->job,
+ m->info->sequence->width,
m->info->sequence->height,
+ crop,
m->pixfmt,
m->info->display_fbuf->buf[0],
m->info->display_fbuf->buf[1],