mpeg4: support frame parameter changes with frame-mt
Adds a flag context_reinit to MpegEncContext to relieable keep track of frame parameter changes which require a context reinitialization. This is required for broken inputs which change the frame size but error out before the context can be reinitialized.
This commit is contained in:
		@@ -434,13 +434,6 @@ retry:
 | 
				
			|||||||
    if (ret < 0){
 | 
					    if (ret < 0){
 | 
				
			||||||
        av_log(s->avctx, AV_LOG_ERROR, "header damaged\n");
 | 
					        av_log(s->avctx, AV_LOG_ERROR, "header damaged\n");
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
    } else if ((s->width  != avctx->coded_width  ||
 | 
					 | 
				
			||||||
                s->height != avctx->coded_height ||
 | 
					 | 
				
			||||||
                (s->width  + 15) >> 4 != s->mb_width ||
 | 
					 | 
				
			||||||
                (s->height + 15) >> 4 != s->mb_height) &&
 | 
					 | 
				
			||||||
               (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))) {
 | 
					 | 
				
			||||||
        av_log_missing_feature(s->avctx, "Width/height/bit depth/chroma idc changing with threads is", 0);
 | 
					 | 
				
			||||||
        return AVERROR_PATCHWELCOME;   // width / height changed during parallelized decoding
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    avctx->has_b_frames= !s->low_delay;
 | 
					    avctx->has_b_frames= !s->low_delay;
 | 
				
			||||||
@@ -577,21 +570,29 @@ retry:
 | 
				
			|||||||
        /* FIXME: By the way H263 decoder is evolving it should have */
 | 
					        /* FIXME: By the way H263 decoder is evolving it should have */
 | 
				
			||||||
        /* an H263EncContext                                         */
 | 
					        /* an H263EncContext                                         */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (   s->width  != avctx->coded_width
 | 
					    if (!avctx->coded_width || !avctx->coded_height) {
 | 
				
			||||||
        || s->height != avctx->coded_height) {
 | 
					 | 
				
			||||||
        /* H.263 could change picture size any time */
 | 
					 | 
				
			||||||
        ParseContext pc= s->parse_context; //FIXME move these demuxng hack to avformat
 | 
					        ParseContext pc= s->parse_context; //FIXME move these demuxng hack to avformat
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        s->parse_context.buffer=0;
 | 
					        s->parse_context.buffer=0;
 | 
				
			||||||
        ff_MPV_common_end(s);
 | 
					        ff_MPV_common_end(s);
 | 
				
			||||||
        s->parse_context= pc;
 | 
					        s->parse_context= pc;
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (!s->context_initialized) {
 | 
					 | 
				
			||||||
        avcodec_set_dimensions(avctx, s->width, s->height);
 | 
					        avcodec_set_dimensions(avctx, s->width, s->height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        goto retry;
 | 
					        goto retry;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (s->width  != avctx->coded_width  ||
 | 
				
			||||||
 | 
					        s->height != avctx->coded_height ||
 | 
				
			||||||
 | 
					        s->context_reinit) {
 | 
				
			||||||
 | 
					        /* H.263 could change picture size any time */
 | 
				
			||||||
 | 
					        s->context_reinit = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        avcodec_set_dimensions(avctx, s->width, s->height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((ret = ff_MPV_common_frame_size_change(s)))
 | 
				
			||||||
 | 
					            return ret;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if((s->codec_id==AV_CODEC_ID_H263 || s->codec_id==AV_CODEC_ID_H263P || s->codec_id == AV_CODEC_ID_H263I))
 | 
					    if((s->codec_id==AV_CODEC_ID_H263 || s->codec_id==AV_CODEC_ID_H263P || s->codec_id == AV_CODEC_ID_H263I))
 | 
				
			||||||
        s->gob_index = ff_h263_get_gob_height(s);
 | 
					        s->gob_index = ff_h263_get_gob_height(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1600,6 +1600,9 @@ static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){
 | 
				
			|||||||
            height = get_bits(gb, 13);
 | 
					            height = get_bits(gb, 13);
 | 
				
			||||||
            skip_bits1(gb);   /* marker */
 | 
					            skip_bits1(gb);   /* marker */
 | 
				
			||||||
            if(width && height && !(s->width && s->codec_tag == AV_RL32("MP4S"))){ /* they should be non zero but who knows ... */
 | 
					            if(width && height && !(s->width && s->codec_tag == AV_RL32("MP4S"))){ /* they should be non zero but who knows ... */
 | 
				
			||||||
 | 
					                if (s->width && s->height &&
 | 
				
			||||||
 | 
					                    (s->width != width || s->height != height))
 | 
				
			||||||
 | 
					                    s->context_reinit = 1;
 | 
				
			||||||
                s->width = width;
 | 
					                s->width = width;
 | 
				
			||||||
                s->height = height;
 | 
					                s->height = height;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -550,6 +550,15 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst,
 | 
				
			|||||||
        ff_MPV_common_init(s);
 | 
					        ff_MPV_common_init(s);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (s->height != s1->height || s->width != s1->width || s->context_reinit) {
 | 
				
			||||||
 | 
					        int err;
 | 
				
			||||||
 | 
					        s->context_reinit = 0;
 | 
				
			||||||
 | 
					        s->height = s1->height;
 | 
				
			||||||
 | 
					        s->width  = s1->width;
 | 
				
			||||||
 | 
					        if ((err = ff_MPV_common_frame_size_change(s)) < 0)
 | 
				
			||||||
 | 
					            return err;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s->avctx->coded_height  = s1->avctx->coded_height;
 | 
					    s->avctx->coded_height  = s1->avctx->coded_height;
 | 
				
			||||||
    s->avctx->coded_width   = s1->avctx->coded_width;
 | 
					    s->avctx->coded_width   = s1->avctx->coded_width;
 | 
				
			||||||
    s->avctx->width         = s1->avctx->width;
 | 
					    s->avctx->width         = s1->avctx->width;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -703,6 +703,10 @@ typedef struct MpegEncContext {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /* temp buffers for rate control */
 | 
					    /* temp buffers for rate control */
 | 
				
			||||||
    float *cplx_tab, *bits_tab;
 | 
					    float *cplx_tab, *bits_tab;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* flag to indicate a reinitialization is required, e.g. after
 | 
				
			||||||
 | 
					     * a frame size change */
 | 
				
			||||||
 | 
					    int context_reinit;
 | 
				
			||||||
} MpegEncContext;
 | 
					} MpegEncContext;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define REBASE_PICTURE(pic, new_ctx, old_ctx) (pic ? \
 | 
					#define REBASE_PICTURE(pic, new_ctx, old_ctx) (pic ? \
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user