rendered paste bodyIndex: libhb/decmpeg2.c===================================================================--- libhb/decmpeg2.c (revision 1612)+++ libhb/decmpeg2.c (working copy)@@ -97,7 +97,11 @@ } else if( state == STATE_SEQUENCE ) {- if( !( m->width && m->height && m->rate ) )+ /* If the stream's dimensions have changed, we need to detect and+ * record so that render.c can adjust its context. */+ if( !( m->width && m->height && m->rate ) ||+ m->width != m->info->sequence->width ||+ m->height != m->info->sequence->height ) { m->width = m->info->sequence->width; m->height = m->info->sequence->height;@@ -140,6 +144,10 @@ { buf = hb_buffer_init( m->width * m->height * 3 / 2 ); data = buf->data;+ + /* The renderer monitors these for changes */+ buf->width = m->width;+ buf->height = m->height; buf->sequence = buf_es->sequence; Index: libhb/render.c===================================================================--- libhb/render.c (revision 1612)+++ libhb/render.c (working copy)@@ -29,6 +29,13 @@ uint64_t total_gained_time; int64_t chapter_time; int chapter_val;++ /* These dimensions will reflect any changes in the stream's dimensions.+ * The alternative to using these would be to use the dimensions in title,+ * but adjusting those willy-nilly would probably be asking for bugs+ * elsewhere. */+ int width;+ int height; }; int renderInit( hb_work_object_t *, hb_job_t * );@@ -64,9 +71,10 @@ (width*height)/4]); } -static void ApplySub( hb_job_t * job, hb_buffer_t * buf,+static void ApplySub( hb_work_private_t * pv, hb_buffer_t * buf, hb_buffer_t ** _sub ) {+ hb_job_t * job = pv->job; hb_buffer_t * sub = *_sub; hb_title_t * title = job->title; int i, j, offset_top, offset_left, margin_top, margin_percent;@@ -88,7 +96,7 @@ * When it won't fit, we center it so we lose as much on both ends. * Otherwise we try to leave a 20px or 2% margin around it. */- margin_top = ( ( title->height - job->crop[0] - job->crop[1] ) *+ margin_top = ( ( pv->height - job->crop[0] - job->crop[1] ) * margin_percent ) / 100; if( margin_top > 20 )@@ -99,14 +107,14 @@ margin_top = 20; } - if( sub->height > title->height - job->crop[0] - job->crop[1] -+ if( sub->height > pv->height - job->crop[0] - job->crop[1] - ( margin_top * 2 ) ) { /* * The subtitle won't fit in the cropped zone, so center * it vertically so we fit in as much as we can. */- offset_top = job->crop[0] + ( title->height - job->crop[0] -+ offset_top = job->crop[0] + ( pv->height - job->crop[0] - job->crop[1] - sub->height ) / 2; } else if( sub->y < job->crop[0] + margin_top )@@ -117,14 +125,14 @@ */ offset_top = job->crop[0] + margin_top; }- else if( sub->y > title->height - job->crop[1] - margin_top - sub->height )+ else if( sub->y > pv->height - job->crop[1] - margin_top - sub->height ) { /* * The subtitle fits in the cropped zone, and is not within the top * margin but is within the bottom margin, so move it to be above * the margin. */- offset_top = title->height - job->crop[1] - margin_top - sub->height;+ offset_top = pv->height - job->crop[1] - margin_top - sub->height; } else {@@ -134,13 +142,13 @@ offset_top = sub->y; } - if( sub->width > title->width - job->crop[2] - job->crop[3] - 40 )- offset_left = job->crop[2] + ( title->width - job->crop[2] -+ if( sub->width > pv->width - job->crop[2] - job->crop[3] - 40 )+ offset_left = job->crop[2] + ( pv->width - job->crop[2] - job->crop[3] - sub->width ) / 2; else if( sub->x < job->crop[2] + 20 ) offset_left = job->crop[2] + 20;- else if( sub->x > title->width - job->crop[3] - 20 - sub->width )- offset_left = title->width - job->crop[3] - 20 - sub->width;+ else if( sub->x > pv->width - job->crop[3] - 20 - sub->width )+ offset_left = pv->width - job->crop[3] - 20 - sub->width; else offset_left = sub->x; @@ -149,15 +157,15 @@ sub_chromaU = alpha + sub->width * sub->height; sub_chromaV = sub_chromaU + sub->width * sub->height; - out = buf->data + offset_top * title->width + offset_left;+ out = buf->data + offset_top * pv->width + offset_left; for( i = 0; i < sub->height; i++ ) {- if( offset_top + i >= 0 && offset_top + i < title->height )+ if( offset_top + i >= 0 && offset_top + i < pv->height ) { for( j = 0; j < sub->width; j++ ) {- if( offset_left + j >= 0 && offset_left + j < title->width )+ if( offset_left + j >= 0 && offset_left + j < pv->width ) { uint8_t *chromaU, *chromaV; @@ -170,10 +178,10 @@ * Set the chroma (colour) based on whether there is * any alpha at all. Don't try to blend with the picture. */- chromaU = getU(buf->data, title->width, title->height,+ chromaU = getU(buf->data, pv->width, pv->height, offset_left+j, offset_top+i); - chromaV = getV(buf->data, title->width, title->height,+ chromaV = getV(buf->data, pv->width, pv->height, offset_left+j, offset_top+i); if( alpha[j] > 0 )@@ -193,12 +201,43 @@ alpha += sub->width; sub_chromaU += sub->width; sub_chromaV += sub->width;- out += title->width;+ out += pv->width; } hb_buffer_close( _sub ); } +/* + * Allow easy reinitialization of the context, should the dimensions change. + */+void render_context_init( hb_work_object_t *w )+{+ hb_work_private_t *pv = w->private_data;+ hb_job_t *job = pv->job;+ + uint32_t swsflags;+ swsflags = SWS_LANCZOS;+ #ifndef __x86_64__+ swsflags |= SWS_ACCURATE_RND;+ #endif /* __x86_64__ */+ + if (pv->context) {+ sws_freeContext(pv->context);+ pv->context = NULL;+ }+ + /* If crop or scale is specified, setup rescale context */+ if( job->crop[0] || job->crop[1] || job->crop[2] || job->crop[3] ||+ job->width != pv->width || job->height != pv->height )+ {+ pv->context = sws_getContext(pv->width - (job->crop[2] + job->crop[3]),+ pv->height - (job->crop[0] + job->crop[1]),+ PIX_FMT_YUV420P,+ job->width, job->height, PIX_FMT_YUV420P,+ swsflags, NULL, NULL, NULL);+ }+}+ int renderWork( hb_work_object_t * w, hb_buffer_t ** buf_in, hb_buffer_t ** buf_out ) {@@ -208,6 +247,19 @@ hb_buffer_t * in = *buf_in, * buf_tmp_in = *buf_in; hb_buffer_t * ivtc_buffer = NULL; + /* + * If new dimensions are detected, we need to initialize, reinitialize, or+ * delete the context. render_context_init() will figure it out.+ */+ if ((in->width || in->height) && + (in->width != pv->width || in->height != pv->height)) {+ if (in->width)+ pv->width = in->width;+ if (in->height)+ pv->height = in->height;+ render_context_init(w);+ }+ if( in->size <= 0 ) { /* If the input buffer is end of stream, send out an empty one@@ -270,8 +322,8 @@ int result = filter->work( buf_tmp_in, &buf_tmp_out, PIX_FMT_YUV420P,- title->width,- title->height,+ pv->width,+ pv->height, filter->private_data ); /*@@ -346,7 +398,7 @@ hb_buffer_t * subtitles = hb_fifo_get( pv->subtitle_queue ); if( subtitles ) {- ApplySub( job, buf_tmp_in, &subtitles );+ ApplySub( pv, buf_tmp_in, &subtitles ); } } @@ -355,7 +407,7 @@ { avpicture_fill( &pv->pic_tmp_in, buf_tmp_in->data, PIX_FMT_YUV420P,- title->width, title->height );+ pv->width, pv->height ); avpicture_fill( &pv->pic_tmp_out, buf_render->data, PIX_FMT_YUV420P,@@ -368,7 +420,7 @@ // Scale pic_crop into pic_render according to the context set up in renderInit sws_scale(pv->context, pv->pic_tmp_crop.data, pv->pic_tmp_crop.linesize,- 0, title->height - (job->crop[0] + job->crop[1]),+ 0, pv->height - (job->crop[0] + job->crop[1]), pv->pic_tmp_out.data, pv->pic_tmp_out.linesize); hb_buffer_copy_settings( buf_render, buf_tmp_in );@@ -542,17 +594,11 @@ /* Get title and title size */ hb_title_t * title = job->title; - /* If crop or scale is specified, setup rescale context */- if( job->crop[0] || job->crop[1] || job->crop[2] || job->crop[3] ||- job->width != title->width || job->height != title->height )- {- pv->context = sws_getContext(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,- swsflags, NULL, NULL, NULL);- }-+ pv->width = title->width;+ pv->height = title->height;+ + render_context_init(w);+ /* Setup FIFO queue for subtitle cache */ pv->subtitle_queue = hb_fifo_init( 8 ); pv->delay_queue = hb_fifo_init( 8 );@@ -587,8 +633,8 @@ if( !filter ) continue; filter->private_data = filter->init( PIX_FMT_YUV420P,- title->width,- title->height,+ pv->width,+ pv->height, filter->settings ); } }