|  |  | @@ -1001,6 +1001,77 @@ static int free_context_frame(MpegEncContext *s) | 
		
	
		
			
			|  |  |  | return 0; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | int ff_MPV_common_frame_size_change(MpegEncContext *s) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | int i, err = 0; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (s->slice_context_count > 1) { | 
		
	
		
			
			|  |  |  | for (i = 0; i < s->slice_context_count; i++) { | 
		
	
		
			
			|  |  |  | free_duplicate_context(s->thread_context[i]); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | for (i = 1; i < s->slice_context_count; i++) { | 
		
	
		
			
			|  |  |  | av_freep(&s->thread_context[i]); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } else | 
		
	
		
			
			|  |  |  | free_duplicate_context(s); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | free_context_frame(s); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (s->picture) | 
		
	
		
			
			|  |  |  | for (i = 0; i < s->picture_count; i++) { | 
		
	
		
			
			|  |  |  | s->picture[i].needs_realloc = 1; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | s->last_picture_ptr         = | 
		
	
		
			
			|  |  |  | s->next_picture_ptr         = | 
		
	
		
			
			|  |  |  | s->current_picture_ptr      = NULL; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | // init | 
		
	
		
			
			|  |  |  | if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO && !s->progressive_sequence) | 
		
	
		
			
			|  |  |  | s->mb_height = (s->height + 31) / 32 * 2; | 
		
	
		
			
			|  |  |  | else if (s->codec_id != AV_CODEC_ID_H264) | 
		
	
		
			
			|  |  |  | s->mb_height = (s->height + 15) / 16; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if ((s->width || s->height) && | 
		
	
		
			
			|  |  |  | av_image_check_size(s->width, s->height, 0, s->avctx)) | 
		
	
		
			
			|  |  |  | return AVERROR_INVALIDDATA; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if ((err = init_context_frame(s))) | 
		
	
		
			
			|  |  |  | goto fail; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | s->thread_context[0]   = s; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (s->width && s->height) { | 
		
	
		
			
			|  |  |  | int nb_slices = s->slice_context_count; | 
		
	
		
			
			|  |  |  | if (nb_slices > 1) { | 
		
	
		
			
			|  |  |  | for (i = 1; i < nb_slices; i++) { | 
		
	
		
			
			|  |  |  | s->thread_context[i] = av_malloc(sizeof(MpegEncContext)); | 
		
	
		
			
			|  |  |  | memcpy(s->thread_context[i], s, sizeof(MpegEncContext)); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | for (i = 0; i < nb_slices; i++) { | 
		
	
		
			
			|  |  |  | if (init_duplicate_context(s->thread_context[i], s) < 0) | 
		
	
		
			
			|  |  |  | goto fail; | 
		
	
		
			
			|  |  |  | s->thread_context[i]->start_mb_y = | 
		
	
		
			
			|  |  |  | (s->mb_height * (i) + nb_slices / 2) / nb_slices; | 
		
	
		
			
			|  |  |  | s->thread_context[i]->end_mb_y   = | 
		
	
		
			
			|  |  |  | (s->mb_height * (i + 1) + nb_slices / 2) / nb_slices; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } else { | 
		
	
		
			
			|  |  |  | if (init_duplicate_context(s, s) < 0) | 
		
	
		
			
			|  |  |  | goto fail; | 
		
	
		
			
			|  |  |  | s->start_mb_y = 0; | 
		
	
		
			
			|  |  |  | s->end_mb_y   = s->mb_height; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | s->slice_context_count = nb_slices; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | return 0; | 
		
	
		
			
			|  |  |  | fail: | 
		
	
		
			
			|  |  |  | ff_MPV_common_end(s); | 
		
	
		
			
			|  |  |  | return err; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | /* init common structure for both encoder and decoder */ | 
		
	
		
			
			|  |  |  | void ff_MPV_common_end(MpegEncContext *s) | 
		
	
		
			
			|  |  |  | { | 
		
	
	
		
			
				|  |  | @@ -1155,7 +1226,17 @@ void ff_release_unused_pictures(MpegEncContext*s, int remove_current) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | int ff_find_unused_picture(MpegEncContext *s, int shared) | 
		
	
		
			
			|  |  |  | static inline int pic_is_unused(MpegEncContext *s, Picture *pic) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | if (pic->f.data[0] == NULL) | 
		
	
		
			
			|  |  |  | return 1; | 
		
	
		
			
			|  |  |  | if (pic->needs_realloc) | 
		
	
		
			
			|  |  |  | if (!pic->owner2 || pic->owner2 == s) | 
		
	
		
			
			|  |  |  | return 1; | 
		
	
		
			
			|  |  |  | return 0; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static int find_unused_picture(MpegEncContext *s, int shared) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | int i; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
				|  |  | @@ -1166,11 +1247,11 @@ int ff_find_unused_picture(MpegEncContext *s, int shared) | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } else { | 
		
	
		
			
			|  |  |  | for (i = s->picture_range_start; i < s->picture_range_end; i++) { | 
		
	
		
			
			|  |  |  | if (s->picture[i].f.data[0] == NULL && s->picture[i].f.type != 0) | 
		
	
		
			
			|  |  |  | if (pic_is_unused(s, &s->picture[i]) && s->picture[i].f.type != 0) | 
		
	
		
			
			|  |  |  | return i; // FIXME | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | for (i = s->picture_range_start; i < s->picture_range_end; i++) { | 
		
	
		
			
			|  |  |  | if (s->picture[i].f.data[0] == NULL) | 
		
	
		
			
			|  |  |  | if (pic_is_unused(s, &s->picture[i])) | 
		
	
		
			
			|  |  |  | return i; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
	
		
			
				|  |  | @@ -1178,6 +1259,20 @@ int ff_find_unused_picture(MpegEncContext *s, int shared) | 
		
	
		
			
			|  |  |  | return AVERROR_INVALIDDATA; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | int ff_find_unused_picture(MpegEncContext *s, int shared) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | int ret = find_unused_picture(s, shared); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (ret >= 0 && ret < s->picture_range_end) { | 
		
	
		
			
			|  |  |  | if (s->picture[ret].needs_realloc) { | 
		
	
		
			
			|  |  |  | s->picture[ret].needs_realloc = 0; | 
		
	
		
			
			|  |  |  | free_picture(s, &s->picture[ret]); | 
		
	
		
			
			|  |  |  | avcodec_get_frame_defaults(&s->picture[ret].f); | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | return ret; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static void update_noise_reduction(MpegEncContext *s) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | int intra, i; | 
		
	
	
		
			
				|  |  | @@ -1225,7 +1320,7 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) | 
		
	
		
			
			|  |  |  | if (s->picture[i].owner2 == s && s->picture[i].f.data[0] && | 
		
	
		
			
			|  |  |  | &s->picture[i] != s->last_picture_ptr && | 
		
	
		
			
			|  |  |  | &s->picture[i] != s->next_picture_ptr && | 
		
	
		
			
			|  |  |  | s->picture[i].f.reference) { | 
		
	
		
			
			|  |  |  | s->picture[i].f.reference && !s->picture[i].needs_realloc) { | 
		
	
		
			
			|  |  |  | if (!(avctx->active_thread_type & FF_THREAD_FRAME)) | 
		
	
		
			
			|  |  |  | av_log(avctx, AV_LOG_ERROR, | 
		
	
		
			
			|  |  |  | "releasing zombie picture\n"); | 
		
	
	
		
			
				|  |  | 
 |