summaryrefslogtreecommitdiffstats
path: root/libhb
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2012-06-25 07:56:49 +0000
committerjstebbins <[email protected]>2012-06-25 07:56:49 +0000
commitefbf9c29a90a8590080c98a53a67cb5e98cddb02 (patch)
tree2e2e1748ea3ce9ad24fe7ba8413b43ada2ec764b /libhb
parent7e1d3dc3448805803138cb4fe4ad1e1c8d6f1c85 (diff)
libhb: fix deinterlace fast problem with sources that have <mod8 alignment
avpicture_deinterlace requires that both width and height of the input be 8 pixel aligned. Video buffers already have padding to align horizontally to 16 pixels, but they were not padded vertically. This adds vertical padding. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@4776 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'libhb')
-rw-r--r--libhb/decavcodec.c9
-rw-r--r--libhb/decomb.c45
-rw-r--r--libhb/deinterlace.c6
-rw-r--r--libhb/detelecine.c19
-rw-r--r--libhb/fifo.c13
-rw-r--r--libhb/hb.c128
-rw-r--r--libhb/hb.h1
-rw-r--r--libhb/internal.h20
8 files changed, 155 insertions, 86 deletions
diff --git a/libhb/decavcodec.c b/libhb/decavcodec.c
index 8a236ca4a..875a94c67 100644
--- a/libhb/decavcodec.c
+++ b/libhb/decavcodec.c
@@ -578,13 +578,16 @@ static hb_buffer_t *copy_frame( hb_work_private_t *pv, AVFrame *frame )
{
w = buf->plane[0].stride;
h = buf->plane[0].height;
- dst = copy_plane( dst, frame->data[0], w, frame->linesize[0], h );
+ dst = buf->plane[0].data;
+ copy_plane( dst, frame->data[0], w, frame->linesize[0], h );
w = buf->plane[1].stride;
h = buf->plane[1].height;
- dst = copy_plane( dst, frame->data[1], w, frame->linesize[1], h );
+ dst = buf->plane[1].data;
+ copy_plane( dst, frame->data[1], w, frame->linesize[1], h );
w = buf->plane[2].stride;
h = buf->plane[2].height;
- dst = copy_plane( dst, frame->data[2], w, frame->linesize[2], h );
+ dst = buf->plane[2].data;
+ copy_plane( dst, frame->data[2], w, frame->linesize[2], h );
}
return buf;
}
diff --git a/libhb/decomb.c b/libhb/decomb.c
index 3ce36d23e..40bcb2a6c 100644
--- a/libhb/decomb.c
+++ b/libhb/decomb.c
@@ -133,6 +133,7 @@ typedef struct yadif_thread_arg_s {
struct hb_filter_private_s
{
int width[3];
+ int stride[3];
int height[3];
// Decomb parameters
@@ -370,7 +371,7 @@ void apply_mask( hb_filter_private_t * pv )
apply_mask_line( srcp, mskp, pv->width[plane] );
}
- srcp += pv->pic_out.linesize[plane];
+ srcp += pv->stride[plane];
mskp += pv->ref_stride[plane];
}
}
@@ -394,6 +395,7 @@ static void store_ref( const uint8_t ** pic,
uint8_t * ref = pv->ref[2][i];
int w = pv->width[i];
+ int s = pv->stride[i];
int h = pv->height[i];
int ref_stride = pv->ref_stride[i];
@@ -401,7 +403,7 @@ static void store_ref( const uint8_t ** pic,
for( y = 0; y < h; y++ )
{
memcpy(ref, src, w);
- src = (uint8_t*)src + w;
+ src = (uint8_t*)src + s;
ref = (uint8_t*)ref + ref_stride;
}
}
@@ -1618,7 +1620,7 @@ void yadif_decomb_filter_thread( void *thread_args_v )
int segment, segment_start, segment_stop;
yadif_thread_arg_t *thread_args = thread_args_v;
uint8_t **dst;
- int parity, tff, y, w, h, penultimate, ultimate, ref_stride, is_combed;
+ int parity, tff, y, w, s, h, penultimate, ultimate, ref_stride, is_combed;
pv = thread_args->pv;
segment = thread_args->segment;
@@ -1662,6 +1664,7 @@ void yadif_decomb_filter_thread( void *thread_args_v )
parity = yadif_work->parity;
tff = yadif_work->tff;
w = pv->width[plane];
+ s = pv->stride[plane];
h = pv->height[plane];
penultimate = h - 2;
ultimate = h - 1;
@@ -1683,7 +1686,7 @@ void yadif_decomb_filter_thread( void *thread_args_v )
{
/* This line gets blend filtered, not yadif filtered. */
uint8_t *cur = &pv->ref[1][plane][y*ref_stride];
- uint8_t *dst2 = &dst[plane][y*w];
+ uint8_t *dst2 = &dst[plane][y*s];
/* These will be useful if we ever do temporal blending. */
// uint8_t *prev = &pv->ref[0][plane][y*ref_stride];
// uint8_t *next = &pv->ref[2][plane][y*ref_stride];
@@ -1694,7 +1697,7 @@ void yadif_decomb_filter_thread( void *thread_args_v )
{
/* Just apply vertical cubic interpolation */
uint8_t *cur = &pv->ref[1][plane][y*ref_stride];
- uint8_t *dst2 = &dst[plane][y*w];
+ uint8_t *dst2 = &dst[plane][y*s];
cubic_interpolate_line( dst2, cur, plane, y, pv );
}
@@ -1712,7 +1715,7 @@ void yadif_decomb_filter_thread( void *thread_args_v )
uint8_t *prev = &pv->ref[0][plane][y*ref_stride];
uint8_t *cur = &pv->ref[1][plane][y*ref_stride];
uint8_t *next = &pv->ref[2][plane][y*ref_stride];
- uint8_t *dst2 = &dst[plane][y*w];
+ uint8_t *dst2 = &dst[plane][y*s];
yadif_filter_line( dst2,
prev,
@@ -1726,35 +1729,35 @@ void yadif_decomb_filter_thread( void *thread_args_v )
else if( y == 0 )
{
/* BFF, so y0 = y1 */
- memcpy( &dst[plane][y*w],
+ memcpy( &dst[plane][y*s],
&pv->ref[1][plane][1*ref_stride],
w * sizeof(uint8_t) );
}
else if( y == 1 )
{
/* TFF, so y1 = y0 */
- memcpy( &dst[plane][y*w],
+ memcpy( &dst[plane][y*s],
&pv->ref[1][plane][0],
w * sizeof(uint8_t) );
}
else if( y == penultimate )
{
/* BFF, so penultimate y = ultimate y */
- memcpy( &dst[plane][y*w],
+ memcpy( &dst[plane][y*s],
&pv->ref[1][plane][ultimate*ref_stride],
w * sizeof(uint8_t) );
}
else if( y == ultimate )
{
/* TFF, so ultimate y = penultimate y */
- memcpy( &dst[plane][y*w],
+ memcpy( &dst[plane][y*s],
&pv->ref[1][plane][penultimate*ref_stride],
w * sizeof(uint8_t) );
}
}
else
{
- memcpy( &dst[plane][y*w],
+ memcpy( &dst[plane][y*s],
&pv->ref[1][plane][y*ref_stride],
w * sizeof(uint8_t) );
}
@@ -1838,13 +1841,14 @@ static void yadif_filter( uint8_t ** dst,
uint8_t * dest = dst[i];
int w = pv->width[i];
+ int s = pv->stride[i];
int ref_stride = pv->ref_stride[i];
int y;
for( y = 0; y < pv->height[i]; y++ )
{
memcpy(dest, ref, w);
- dest += w;
+ dest += s;
ref += ref_stride;
}
}
@@ -1888,13 +1892,14 @@ static void yadif_filter( uint8_t ** dst,
uint8_t * dest = dst[i];
int w = pv->width[i];
+ int s = pv->stride[i];
int ref_stride = pv->ref_stride[i];
int y;
for( y = 0; y < pv->height[i]; y++ )
{
memcpy(dest, ref, w);
- dest += w;
+ dest += s;
ref += ref_stride;
}
}
@@ -1913,9 +1918,11 @@ static int hb_decomb_init( hb_filter_object_t * filter,
filter->private_data = calloc( 1, sizeof(struct hb_filter_private_s) );
hb_filter_private_t * pv = filter->private_data;
- pv->width[0] = hb_image_stride( init->pix_fmt, init->width, 0 );
+ pv->width[0] = hb_image_width( init->pix_fmt, init->width, 0 );
+ pv->stride[0] = hb_image_stride( init->pix_fmt, init->width, 0 );
pv->height[0] = hb_image_height( init->pix_fmt, init->height, 0 );
- pv->width[1] = pv->width[2] = hb_image_stride( init->pix_fmt, init->width, 1 );
+ pv->width[1] = pv->width[2] = hb_image_width( init->pix_fmt, init->width, 1 );
+ pv->stride[1] = pv->stride[2] = hb_image_stride( init->pix_fmt, init->width, 1 );
pv->height[1] = pv->height[2] = hb_image_height( init->pix_fmt, init->height, 1 );
build_gamma_lut( pv );
@@ -2005,8 +2012,8 @@ static int hb_decomb_init( hb_filter_object_t * filter,
for( i = 0; i < 3; i++ )
{
int is_chroma = !!i;
- int w = ((pv->width[0] + 31) & (~31))>>is_chroma;
- int h = ((pv->height[0]+6+ 31) & (~31))>>is_chroma;
+ int w = ((init->width + 31) & (~31))>>is_chroma;
+ int h = ((init->height+6+ 31) & (~31))>>is_chroma;
pv->mask[i] = calloc( 1, w*h*sizeof(uint8_t) ) + 3*w;
pv->mask_filtered[i] = calloc( 1, w*h*sizeof(uint8_t) ) + 3*w;
@@ -2016,7 +2023,7 @@ static int hb_decomb_init( hb_filter_object_t * filter,
if( pv->mode & MODE_EEDI2 )
{
/* Allocate half-height eedi2 buffers */
- int height = pv->height[0] / 2;
+ int height = init->height / 2;
for( i = 0; i < 3; i++ )
{
int is_chroma = !!i;
@@ -2030,7 +2037,7 @@ static int hb_decomb_init( hb_filter_object_t * filter,
}
/* Allocate full-height eedi2 buffers */
- height = pv->height[0];
+ height = init->height;
for( i = 0; i < 3; i++ )
{
int is_chroma = !!i;
diff --git a/libhb/deinterlace.c b/libhb/deinterlace.c
index e654817c3..ee410a1cf 100644
--- a/libhb/deinterlace.c
+++ b/libhb/deinterlace.c
@@ -536,8 +536,12 @@ static int hb_deinterlace_work( hb_filter_object_t * filter,
{
hb_avpicture_fill( &pic_out, pv->buf_out[0] );
+ // avpicture_deinterlace requires 8 byte aligned width and height
+ // we have aligned all buffers to 16 byte width and height strides
+ // so use the image stride when deinterlacing
avpicture_deinterlace( &pic_out, &pic_in, pv->buf_out[0]->f.fmt,
- pv->buf_out[0]->f.width, pv->buf_out[0]->f.height );
+ pv->buf_out[0]->plane[0].stride,
+ pv->buf_out[0]->plane[0].height_stride );
pv->buf_out[0]->s = in->s;
hb_buffer_move_subs( pv->buf_out[0], in );
diff --git a/libhb/detelecine.c b/libhb/detelecine.c
index 41b9838f0..96596487c 100644
--- a/libhb/detelecine.c
+++ b/libhb/detelecine.c
@@ -33,6 +33,7 @@ struct pullup_buffer
{
int lock[2];
unsigned char **planes;
+ int *size;
};
struct pullup_field
@@ -593,11 +594,13 @@ static void pullup_alloc_buffer( struct pullup_context * c,
int i;
if( b->planes ) return;
b->planes = calloc( c->nplanes, sizeof(unsigned char *) );
+ b->size = calloc( c->nplanes, sizeof(int) );
for ( i = 0; i < c->nplanes; i++ )
{
- b->planes[i] = malloc(c->h[i]*c->stride[i]);
+ b->size[i] = c->h[i] * c->stride[i];
+ b->planes[i] = malloc(b->size[i]);
/* Deal with idiotic 128=0 for chroma: */
- memset( b->planes[i], c->background[i], c->h[i]*c->stride[i] );
+ memset( b->planes[i], c->background[i], b->size[i] );
}
}
@@ -919,9 +922,9 @@ static int hb_detelecine_work( hb_filter_object_t * filter,
}
/* Copy input buffer into pullup buffer */
- memcpy( buf->planes[0], in->plane[0].data, in->plane[0].size );
- memcpy( buf->planes[1], in->plane[1].data, in->plane[1].size );
- memcpy( buf->planes[2], in->plane[2].data, in->plane[2].size );
+ memcpy( buf->planes[0], in->plane[0].data, buf->size[0] );
+ memcpy( buf->planes[1], in->plane[1].data, buf->size[1] );
+ memcpy( buf->planes[2], in->plane[2].data, buf->size[2] );
/* Submit buffer fields based on buffer flags.
Detelecine assumes BFF when the TFF flag isn't present. */
@@ -1011,9 +1014,9 @@ static int hb_detelecine_work( hb_filter_object_t * filter,
out = hb_video_buffer_init( in->f.width, in->f.height );
/* Copy pullup frame buffer into output buffer */
- memcpy( out->plane[0].data, frame->buffer->planes[0], in->plane[0].size );
- memcpy( out->plane[1].data, frame->buffer->planes[1], in->plane[1].size );
- memcpy( out->plane[2].data, frame->buffer->planes[2], in->plane[2].size );
+ memcpy( out->plane[0].data, frame->buffer->planes[0], frame->buffer->size[0] );
+ memcpy( out->plane[1].data, frame->buffer->planes[1], frame->buffer->size[1] );
+ memcpy( out->plane[2].data, frame->buffer->planes[2], frame->buffer->size[2] );
pullup_release_frame( frame );
diff --git a/libhb/fifo.c b/libhb/fifo.c
index 4859c990a..13f361260 100644
--- a/libhb/fifo.c
+++ b/libhb/fifo.c
@@ -389,7 +389,7 @@ hb_buffer_t * hb_buffer_copy( const hb_buffer_t * src )
static void hb_buffer_init_planes_internal( hb_buffer_t * b, uint8_t * has_plane )
{
uint8_t * plane = b->data;
- int p;
+ int p, tot = 0;
for( p = 0; p < 4; p++ )
{
@@ -397,11 +397,12 @@ static void hb_buffer_init_planes_internal( hb_buffer_t * b, uint8_t * has_plane
{
b->plane[p].data = plane;
b->plane[p].stride = hb_image_stride( b->f.fmt, b->f.width, p );
- b->plane[p].height = hb_image_height( b->f.fmt, b->f.height, p );
+ b->plane[p].height_stride = hb_image_height_stride( b->f.fmt, b->f.height, p );
b->plane[p].width = hb_image_width( b->f.fmt, b->f.width, p );
- b->plane[p].size = hb_image_stride( b->f.fmt, b->f.width, p ) *
- hb_image_height( b->f.fmt, b->f.height, p );
+ b->plane[p].height = hb_image_height( b->f.fmt, b->f.height, p );
+ b->plane[p].size = b->plane[p].stride * b->plane[p].height_stride;
plane += b->plane[p].size;
+ tot += b->plane[p].size;
}
}
}
@@ -440,7 +441,7 @@ hb_buffer_t * hb_frame_buffer_init( int pix_fmt, int width, int height )
if ( has_plane[p] )
{
size += hb_image_stride( pix_fmt, width, p ) *
- hb_image_height( pix_fmt, height, p );
+ hb_image_height_stride( pix_fmt, height, p );
}
}
@@ -476,7 +477,7 @@ void hb_video_buffer_realloc( hb_buffer_t * buf, int width, int height )
if ( has_plane[p] )
{
size += hb_image_stride( buf->f.fmt, width, p ) *
- hb_image_height( buf->f.fmt, height, p );
+ hb_image_height_stride( buf->f.fmt, height, p );
}
}
diff --git a/libhb/hb.c b/libhb/hb.c
index 32c07aa0b..0ad101aaf 100644
--- a/libhb/hb.c
+++ b/libhb/hb.c
@@ -141,8 +141,14 @@ int hb_avpicture_fill( AVPicture *pic, hb_buffer_t *buf )
for( ii = 0; ii < 4; ii++ )
pic->linesize[ii] = buf->plane[ii].stride;
- ret = av_image_fill_pointers( pic->data, buf->f.fmt, buf->f.height,
+ ret = av_image_fill_pointers( pic->data, buf->f.fmt,
+ buf->plane[0].height_stride,
buf->data, pic->linesize );
+ if (ret != buf->size)
+ {
+ hb_error("Internal error hb_avpicture_fill expected %d, got %d",
+ buf->size, ret);
+ }
return ret;
}
@@ -705,6 +711,50 @@ int hb_save_preview( hb_handle_t * h, int title, int preview, hb_buffer_t *buf )
return 0;
}
+hb_buffer_t * hb_read_preview( hb_handle_t * h, int title_idx, int preview )
+{
+ FILE * file;
+ char filename[1024];
+
+ hb_title_t * title = hb_list_item( h->list_title, title_idx - 1);
+ if ( title == NULL )
+ {
+ hb_error( "hb_read_preview: invalid title (%d)", title_idx );
+ return NULL;
+ }
+
+ hb_get_tempory_filename( h, filename, "%d_%d_%d",
+ hb_get_instance_id(h), title_idx, preview );
+
+ file = fopen( filename, "rb" );
+ if( !file )
+ {
+ hb_error( "hb_read_preview: fopen failed (%s)", filename );
+ return NULL;
+ }
+
+ hb_buffer_t * buf;
+ buf = hb_frame_buffer_init( PIX_FMT_YUV420P, title->width, title->height );
+
+ int pp, hh;
+ for( pp = 0; pp < 3; pp++ )
+ {
+ uint8_t *data = buf->plane[pp].data;
+ int stride = buf->plane[pp].stride;
+ int w = buf->plane[pp].width;
+ int h = buf->plane[pp].height;
+
+ for( hh = 0; hh < h; hh++ )
+ {
+ fread( data, w, 1, file );
+ data += stride;
+ }
+ }
+ fclose( file );
+
+ return buf;
+}
+
/**
* Create preview image of desired title a index of picture.
* @param h Handle to hb_handle_t.
@@ -717,53 +767,50 @@ 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;
+ hb_buffer_t * in_buf, * deint_buf = NULL, * preview_buf;
+ uint8_t * 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 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 ) );
- avpicture_fill( &pic_in, buf1, PIX_FMT_YUV420P,
- title->width, title->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 );
+ preview_buf = hb_frame_buffer_init( PIX_FMT_RGB32,
+ job->width, job->height );
+ hb_avpicture_fill( &pic_preview, preview_buf );
// Allocate the AVPicture frames and fill in
memset( filename, 0, 1024 );
- hb_get_tempory_filename( h, filename, "%d_%d_%d",
- h->id, title->index, picture );
-
- file = fopen( filename, "rb" );
- if( !file )
+ in_buf = hb_read_preview( h, title->index, picture );
+ if ( in_buf == NULL )
{
- hb_log( "hb_get_preview: fopen failed" );
return;
}
- fread( buf1, avpicture_get_size( PIX_FMT_YUV420P, title->width, title->height), 1, file );
- fclose( file );
+ hb_avpicture_fill( &pic_in, in_buf );
if( job->deinterlace )
{
// Deinterlace and crop
- avpicture_deinterlace( &pic_deint, &pic_in, PIX_FMT_YUV420P, title->width, title->height );
- av_picture_crop( &pic_crop, &pic_deint, PIX_FMT_YUV420P, job->crop[0], job->crop[2] );
+ // avpicture_deinterlace requires width & height that are 8 byte
+ // alligned. This means the left and bottom edges of the preview
+ // will not get deinterlaced or transfered into the output buffer
+ // by avpicture_deinterlace. So copy the original frame into
+ // the deinterlace buffer so we don't see uninitialized data in
+ // the resulting image.
+ deint_buf = hb_frame_buffer_init( PIX_FMT_YUV420P,
+ title->width, title->height );
+ hb_avpicture_fill( &pic_deint, deint_buf );
+
+ avpicture_deinterlace( &pic_deint, &pic_in, PIX_FMT_YUV420P,
+ in_buf->plane[0].stride, in_buf->plane[0].height_stride );
+
+ av_picture_crop( &pic_crop, &pic_deint, PIX_FMT_YUV420P,
+ job->crop[0], job->crop[2] );
}
else
{
@@ -775,27 +822,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
@@ -805,15 +838,14 @@ 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, pic_preview.data[0] + 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 );
+ hb_buffer_close( &in_buf );
+ hb_buffer_close( &deint_buf );
+ hb_buffer_close( &preview_buf );
}
/**
diff --git a/libhb/hb.h b/libhb/hb.h
index 9f65dca93..a594d93fc 100644
--- a/libhb/hb.h
+++ b/libhb/hb.h
@@ -61,6 +61,7 @@ int hb_detect_comb( hb_buffer_t * buf, int width, int height, int color_equal, i
int hb_save_preview( hb_handle_t * h, int title, int preview,
hb_buffer_t *buf );
+hb_buffer_t * hb_read_preview( hb_handle_t * h, int title_idx, int preview );
void hb_get_preview_by_index( hb_handle_t *, int, int, uint8_t * );
void hb_get_preview( hb_handle_t *, hb_title_t *, int,
uint8_t * );
diff --git a/libhb/internal.h b/libhb/internal.h
index 36d8de4ef..577f6671e 100644
--- a/libhb/internal.h
+++ b/libhb/internal.h
@@ -110,6 +110,7 @@ struct hb_buffer_s
int stride;
int width;
int height;
+ int height_stride;
int size;
} plane[4]; // 3 Color components + alpha
@@ -166,7 +167,9 @@ static inline int hb_image_stride( int pix_fmt, int width, int plane )
int linesize = av_image_get_linesize( pix_fmt, width, plane );
// Make buffer SIMD friendly.
- linesize = MULTIPLE_MOD_UP( linesize, 16 );
+ // Decomb requires stride aligned to 32 bytes
+ // TODO: eliminate extra buffer copies in decomb
+ linesize = MULTIPLE_MOD_UP( linesize, 32 );
return linesize;
}
@@ -183,6 +186,21 @@ static inline int hb_image_width( int pix_fmt, int width, int plane )
return width;
}
+static inline int hb_image_height_stride( int pix_fmt, int height, int plane )
+{
+ const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];
+
+ // Decomb requires 6 extra lines and stride aligned to 32 bytes
+ // TODO: eliminate extra buffer copies in decomb
+ height = MULTIPLE_MOD_UP( height + 6, 32 );
+ if ( plane == 1 || plane == 2 )
+ {
+ height = height >> desc->log2_chroma_h;
+ }
+
+ return height;
+}
+
static inline int hb_image_height( int pix_fmt, int height, int plane )
{
const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt];