diff options
author | jstebbins <[email protected]> | 2012-06-25 07:49:25 +0000 |
---|---|---|
committer | jstebbins <[email protected]> | 2012-06-25 07:49:25 +0000 |
commit | f08990395ec04f3f5edbe90d3cc38de2e857b47e (patch) | |
tree | 3d8b043f1666f715b8f1b4729ab8ef6271dc9ce1 | |
parent | 63d4e3c48fc1d9ad0925c52afecd9d76d9a39bfb (diff) |
bugfix branch: fix <mod8 problem with preview generation and deinterlace fast
If the source dimensions are less than mod 8 aligned, deinterlace fast
will fail. Since deinterlace fast is used in preview generation, previews
would fail if any deinterlaceing mode is enabled.
This fix copies the source buffer into a buffer that has right and bottom
padding enough to meet the mod 8 requirement.
git-svn-id: svn://svn.handbrake.fr/HandBrake/branches/0.9.x@4775 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r-- | libhb/deinterlace.c | 50 | ||||
-rw-r--r-- | libhb/hb.c | 60 |
2 files changed, 74 insertions, 36 deletions
diff --git a/libhb/deinterlace.c b/libhb/deinterlace.c index bd51e9a77..50ebd7e25 100644 --- a/libhb/deinterlace.c +++ b/libhb/deinterlace.c @@ -582,8 +582,54 @@ int hb_deinterlace_work( hb_buffer_t * buf_in, avpicture_fill( &pv->pic_out, pv->buf_out[0]->data, pix_fmt, width, height ); - avpicture_deinterlace( &pv->pic_out, &pv->pic_in, - pix_fmt, width, height ); + if ( ( width & 7 ) || ( height & 7 ) ) + { + // avpicture_deinterlace requires 8 pixel aligned dimensions + // so we are going to have to do some buffer copying + int aligned_width = ((width + 7) & ~7); + int aligned_height = ((height + 7) & ~7); + uint8_t * buf1, * buf2; + AVPicture pic_in, pic_out; + int i, p; + + buf1 = av_malloc( avpicture_get_size( PIX_FMT_YUV420P, + aligned_width, aligned_height ) ); + buf2 = av_malloc( avpicture_get_size( PIX_FMT_YUV420P, + aligned_width, aligned_height ) ); + avpicture_fill( &pic_in, buf1, PIX_FMT_YUV420P, + aligned_width, aligned_height ); + avpicture_fill( &pic_out, buf2, PIX_FMT_YUV420P, + aligned_width, aligned_height ); + for (p = 0; p < 3; p++) + { + int h = !p ? height : height >> 1; + for (i = 0; i < h; i++) + { + memcpy(pic_in.data[p] + pic_in.linesize[p] * i, + pv->pic_in.data[p] + pv->pic_in.linesize[p] * i, + pv->pic_in.linesize[p]); + } + } + avpicture_deinterlace( &pic_out, &pic_in, + pix_fmt, aligned_width, aligned_height ); + for (p = 0; p < 3; p++) + { + int h = !p ? height : height >> 1; + for (i = 0; i < h; i++) + { + memcpy(pv->pic_out.data[p] + pv->pic_out.linesize[p] * i, + pic_out.data[p] + pic_out.linesize[p] * i, + pv->pic_out.linesize[p]); + } + } + avpicture_free( &pic_in ); + avpicture_free( &pic_out ); + } + else + { + avpicture_deinterlace( &pv->pic_out, &pv->pic_in, + pix_fmt, width, height ); + } hb_buffer_copy_settings( pv->buf_out[0], buf_in ); diff --git a/libhb/hb.c b/libhb/hb.c index efc1d8cc4..7055e5cf7 100644 --- a/libhb/hb.c +++ b/libhb/hb.c @@ -712,29 +712,26 @@ void hb_get_preview( hb_handle_t * h, hb_title_t * title, int picture, hb_job_t * job = title->job; char filename[1024]; FILE * file; - uint8_t * buf1, * buf2, * buf3, * buf4, * pen; + uint8_t * buf1, * buf2, * buf3, * pen; uint32_t swsflags; - AVPicture pic_in, pic_preview, pic_deint, pic_crop, pic_scale; + AVPicture pic_in, pic_preview, pic_deint, pic_crop; struct SwsContext * context; - int i; - int deint_width = ((title->width + 7) >> 3) << 3; - int rgb_width = ((job->width + 7) >> 3) << 3; + int i, p; + int aligned_width = ((title->width + 7) & ~7); + int aligned_height = ((title->height + 7) & ~7); int preview_size; swsflags = SWS_LANCZOS | SWS_ACCURATE_RND; - buf1 = av_malloc( avpicture_get_size( PIX_FMT_YUV420P, title->width, title->height ) ); - buf2 = av_malloc( avpicture_get_size( PIX_FMT_YUV420P, deint_width, title->height ) ); - buf3 = av_malloc( avpicture_get_size( PIX_FMT_YUV420P, rgb_width, job->height ) ); - buf4 = av_malloc( avpicture_get_size( PIX_FMT_RGB32, rgb_width, job->height ) ); + buf1 = av_malloc( avpicture_get_size( PIX_FMT_YUV420P, aligned_width, aligned_height ) ); + buf2 = av_malloc( avpicture_get_size( PIX_FMT_YUV420P, aligned_width, aligned_height ) ); + buf3 = av_malloc( avpicture_get_size( PIX_FMT_RGB32, job->width, job->height ) ); avpicture_fill( &pic_in, buf1, PIX_FMT_YUV420P, - title->width, title->height ); + aligned_width, aligned_height ); avpicture_fill( &pic_deint, buf2, PIX_FMT_YUV420P, - deint_width, title->height ); - avpicture_fill( &pic_scale, buf3, PIX_FMT_YUV420P, - rgb_width, job->height ); - avpicture_fill( &pic_preview, buf4, PIX_FMT_RGB32, - rgb_width, job->height ); + aligned_width, aligned_height ); + avpicture_fill( &pic_preview, buf3, PIX_FMT_RGB32, + job->width, job->height ); // Allocate the AVPicture frames and fill in @@ -750,13 +747,23 @@ void hb_get_preview( hb_handle_t * h, hb_title_t * title, int picture, return; } - fread( buf1, avpicture_get_size( PIX_FMT_YUV420P, title->width, title->height), 1, file ); + for (p = 0; p < 3; p++) + { + int w = !p ? title->width : title->width >> 1; + int h = !p ? title->height : title->height >> 1; + pen = pic_in.data[p]; + for (i = 0; i < h; i++) + { + fread( pen, w, 1, file ); + pen += pic_in.linesize[p]; + } + } fclose( file ); if( job->deinterlace ) { // Deinterlace and crop - avpicture_deinterlace( &pic_deint, &pic_in, PIX_FMT_YUV420P, title->width, title->height ); + avpicture_deinterlace( &pic_deint, &pic_in, PIX_FMT_YUV420P, aligned_width, aligned_height ); av_picture_crop( &pic_crop, &pic_deint, PIX_FMT_YUV420P, job->crop[0], job->crop[2] ); } else @@ -769,27 +776,13 @@ void hb_get_preview( hb_handle_t * h, hb_title_t * title, int picture, context = hb_sws_get_context(title->width - (job->crop[2] + job->crop[3]), title->height - (job->crop[0] + job->crop[1]), PIX_FMT_YUV420P, - job->width, job->height, PIX_FMT_YUV420P, + job->width, job->height, PIX_FMT_RGB32, swsflags); // Scale sws_scale(context, (const uint8_t* const *)pic_crop.data, pic_crop.linesize, 0, title->height - (job->crop[0] + job->crop[1]), - pic_scale.data, pic_scale.linesize); - - // Free context - sws_freeContext( context ); - - // Get preview context - context = hb_sws_get_context(rgb_width, job->height, PIX_FMT_YUV420P, - rgb_width, job->height, PIX_FMT_RGB32, - swsflags); - - // Create preview - sws_scale(context, - (const uint8_t* const *)pic_scale.data, pic_scale.linesize, - 0, job->height, pic_preview.data, pic_preview.linesize); // Free context @@ -799,13 +792,12 @@ void hb_get_preview( hb_handle_t * h, hb_title_t * title, int picture, pen = buffer; for( i = 0; i < job->height; i++ ) { - memcpy( pen, buf4 + preview_size * i, 4 * job->width ); + memcpy( pen, buf3 + preview_size * i, 4 * job->width ); pen += 4 * job->width; } // Clean up avpicture_free( &pic_preview ); - avpicture_free( &pic_scale ); avpicture_free( &pic_deint ); avpicture_free( &pic_in ); } |