mirror of https://git.ffmpeg.org/ffmpeg.git
Merge remote-tracking branch 'qatar/master'
* qatar/master: rv34: use ff_MPV_common_frame_size_change() mpegvideo: add reinit function for frame parameter changes Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
8846115b1a
|
@ -965,6 +965,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)
|
||||
{
|
||||
|
@ -1124,7 +1195,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;
|
||||
|
||||
|
@ -1135,11 +1216,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;
|
||||
}
|
||||
}
|
||||
|
@ -1161,6 +1242,20 @@ int ff_find_unused_picture(MpegEncContext *s, int shared)
|
|||
return -1;
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -1213,7 +1308,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");
|
||||
|
|
|
@ -141,6 +141,7 @@ typedef struct Picture{
|
|||
int32_t *mb_cmp_score; ///< Table for MB cmp scores, for mb decision FIXME remove
|
||||
int b_frame_score; /* */
|
||||
struct MpegEncContext *owner2; ///< pointer to the MpegEncContext that allocated this picture
|
||||
int needs_realloc; ///< Picture needs to be reallocated (eg due to a frame size change)
|
||||
} Picture;
|
||||
|
||||
/**
|
||||
|
@ -758,6 +759,7 @@ void ff_MPV_common_defaults(MpegEncContext *s);
|
|||
|
||||
void ff_MPV_decode_defaults(MpegEncContext *s);
|
||||
int ff_MPV_common_init(MpegEncContext *s);
|
||||
int ff_MPV_common_frame_size_change(MpegEncContext *s);
|
||||
void ff_MPV_common_end(MpegEncContext *s);
|
||||
void ff_MPV_decode_mb(MpegEncContext *s, DCTELEM block[12][64]);
|
||||
int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx);
|
||||
|
|
|
@ -1537,10 +1537,9 @@ int ff_rv34_decode_update_thread_context(AVCodecContext *dst, const AVCodecConte
|
|||
return 0;
|
||||
|
||||
if (s->height != s1->height || s->width != s1->width) {
|
||||
ff_MPV_common_end(s);
|
||||
s->height = s1->height;
|
||||
s->width = s1->width;
|
||||
if ((err = ff_MPV_common_init(s)) < 0)
|
||||
if ((err = ff_MPV_common_frame_size_change(s)) < 0)
|
||||
return err;
|
||||
if ((err = rv34_decoder_realloc(r)) < 0)
|
||||
return err;
|
||||
|
@ -1659,20 +1658,13 @@ int ff_rv34_decode_frame(AVCodecContext *avctx,
|
|||
if (s->width != si.width || s->height != si.height) {
|
||||
int err;
|
||||
|
||||
if (HAVE_THREADS &&
|
||||
(s->avctx->active_thread_type & FF_THREAD_FRAME)) {
|
||||
av_log_missing_feature(s->avctx, "Width/height changing with "
|
||||
"frame threading is", 0);
|
||||
return AVERROR_PATCHWELCOME;
|
||||
}
|
||||
|
||||
av_log(s->avctx, AV_LOG_WARNING, "Changing dimensions to %dx%d\n",
|
||||
si.width, si.height);
|
||||
ff_MPV_common_end(s);
|
||||
|
||||
s->width = si.width;
|
||||
s->height = si.height;
|
||||
avcodec_set_dimensions(s->avctx, s->width, s->height);
|
||||
if ((err = ff_MPV_common_init(s)) < 0)
|
||||
if ((err = ff_MPV_common_frame_size_change(s)) < 0)
|
||||
return err;
|
||||
if ((err = rv34_decoder_realloc(r)) < 0)
|
||||
return err;
|
||||
|
|
Loading…
Reference in New Issue