avcodec/mpegvideo_dec: Factor allocating dummy frames out
This will allow to reuse it to allocate dummy frames for the second field (which can be a P-field even if the first field was an intra field). Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
This commit is contained in:
@@ -281,14 +281,21 @@ fail:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int av_cold alloc_dummy_frame(MpegEncContext *s, Picture **picp)
|
static int av_cold alloc_dummy_frame(MpegEncContext *s, Picture **picp, Picture *wpic)
|
||||||
{
|
{
|
||||||
Picture *pic;
|
Picture *pic;
|
||||||
int ret = alloc_picture(s, picp, 1);
|
int ret = alloc_picture(s, &pic, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
pic = *picp;
|
ff_mpeg_unref_picture(wpic);
|
||||||
|
ret = ff_mpeg_ref_picture(wpic, pic);
|
||||||
|
if (ret < 0) {
|
||||||
|
ff_mpeg_unref_picture(pic);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
*picp = pic;
|
||||||
|
|
||||||
ff_thread_report_progress(&pic->tf, INT_MAX, 0);
|
ff_thread_report_progress(&pic->tf, INT_MAX, 0);
|
||||||
ff_thread_report_progress(&pic->tf, INT_MAX, 1);
|
ff_thread_report_progress(&pic->tf, INT_MAX, 1);
|
||||||
@@ -314,6 +321,45 @@ static void color_frame(AVFrame *frame, int luma)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ff_mpv_alloc_dummy_frames(MpegEncContext *s)
|
||||||
|
{
|
||||||
|
AVCodecContext *avctx = s->avctx;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if ((!s->last_picture_ptr || !s->last_picture_ptr->f->buf[0]) &&
|
||||||
|
(s->pict_type != AV_PICTURE_TYPE_I)) {
|
||||||
|
if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture_ptr && s->next_picture_ptr->f->buf[0])
|
||||||
|
av_log(avctx, AV_LOG_DEBUG,
|
||||||
|
"allocating dummy last picture for B frame\n");
|
||||||
|
else if (s->codec_id != AV_CODEC_ID_H261 /* H.261 has no keyframes */ &&
|
||||||
|
(s->picture_structure == PICT_FRAME || s->first_field))
|
||||||
|
av_log(avctx, AV_LOG_ERROR,
|
||||||
|
"warning: first frame is no keyframe\n");
|
||||||
|
|
||||||
|
/* Allocate a dummy frame */
|
||||||
|
ret = alloc_dummy_frame(s, &s->last_picture_ptr, &s->last_picture);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (!avctx->hwaccel) {
|
||||||
|
int luma_val = s->codec_id == AV_CODEC_ID_FLV1 || s->codec_id == AV_CODEC_ID_H263 ? 16 : 0x80;
|
||||||
|
color_frame(s->last_picture_ptr->f, luma_val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((!s->next_picture_ptr || !s->next_picture_ptr->f->buf[0]) &&
|
||||||
|
s->pict_type == AV_PICTURE_TYPE_B) {
|
||||||
|
/* Allocate a dummy frame */
|
||||||
|
ret = alloc_dummy_frame(s, &s->next_picture_ptr, &s->next_picture);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
av_assert0(s->pict_type == AV_PICTURE_TYPE_I || (s->last_picture_ptr &&
|
||||||
|
s->last_picture_ptr->f->buf[0]));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* generic function called after decoding
|
* generic function called after decoding
|
||||||
* the header and before a frame is decoded.
|
* the header and before a frame is decoded.
|
||||||
@@ -382,34 +428,6 @@ int ff_mpv_frame_start(MpegEncContext *s, AVCodecContext *avctx)
|
|||||||
s->current_picture_ptr ? s->current_picture_ptr->f->data[0] : NULL,
|
s->current_picture_ptr ? s->current_picture_ptr->f->data[0] : NULL,
|
||||||
s->pict_type, s->droppable);
|
s->pict_type, s->droppable);
|
||||||
|
|
||||||
if ((!s->last_picture_ptr || !s->last_picture_ptr->f->buf[0]) &&
|
|
||||||
(s->pict_type != AV_PICTURE_TYPE_I)) {
|
|
||||||
if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture_ptr && s->next_picture_ptr->f->buf[0])
|
|
||||||
av_log(avctx, AV_LOG_DEBUG,
|
|
||||||
"allocating dummy last picture for B frame\n");
|
|
||||||
else if (s->codec_id != AV_CODEC_ID_H261)
|
|
||||||
av_log(avctx, AV_LOG_ERROR,
|
|
||||||
"warning: first frame is no keyframe\n");
|
|
||||||
|
|
||||||
/* Allocate a dummy frame */
|
|
||||||
ret = alloc_dummy_frame(s, &s->last_picture_ptr);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
if (!avctx->hwaccel) {
|
|
||||||
int luma_val = s->codec_id == AV_CODEC_ID_FLV1 || s->codec_id == AV_CODEC_ID_H263 ? 16 : 0x80;
|
|
||||||
color_frame(s->last_picture_ptr->f, luma_val);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if ((!s->next_picture_ptr || !s->next_picture_ptr->f->buf[0]) &&
|
|
||||||
s->pict_type == AV_PICTURE_TYPE_B) {
|
|
||||||
/* Allocate a dummy frame */
|
|
||||||
ret = alloc_dummy_frame(s, &s->next_picture_ptr);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s->last_picture_ptr) {
|
if (s->last_picture_ptr) {
|
||||||
if (s->last_picture_ptr->f->buf[0] &&
|
if (s->last_picture_ptr->f->buf[0] &&
|
||||||
(ret = ff_mpeg_ref_picture(&s->last_picture,
|
(ret = ff_mpeg_ref_picture(&s->last_picture,
|
||||||
@@ -423,8 +441,9 @@ int ff_mpv_frame_start(MpegEncContext *s, AVCodecContext *avctx)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
av_assert0(s->pict_type == AV_PICTURE_TYPE_I || (s->last_picture_ptr &&
|
ret = ff_mpv_alloc_dummy_frames(s);
|
||||||
s->last_picture_ptr->f->buf[0]));
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
/* set dequantizer, we can't do it during init as
|
/* set dequantizer, we can't do it during init as
|
||||||
* it might change for MPEG-4 and we can't do it in the header
|
* it might change for MPEG-4 and we can't do it in the header
|
||||||
|
@@ -50,6 +50,10 @@ void ff_mpv_decode_init(MpegEncContext *s, AVCodecContext *avctx);
|
|||||||
int ff_mpv_common_frame_size_change(MpegEncContext *s);
|
int ff_mpv_common_frame_size_change(MpegEncContext *s);
|
||||||
|
|
||||||
int ff_mpv_frame_start(MpegEncContext *s, AVCodecContext *avctx);
|
int ff_mpv_frame_start(MpegEncContext *s, AVCodecContext *avctx);
|
||||||
|
/**
|
||||||
|
* Ensure that the dummy frames are allocated according to pict_type if necessary.
|
||||||
|
*/
|
||||||
|
int ff_mpv_alloc_dummy_frames(MpegEncContext *s);
|
||||||
void ff_mpv_reconstruct_mb(MpegEncContext *s, int16_t block[12][64]);
|
void ff_mpv_reconstruct_mb(MpegEncContext *s, int16_t block[12][64]);
|
||||||
void ff_mpv_report_decode_progress(MpegEncContext *s);
|
void ff_mpv_report_decode_progress(MpegEncContext *s);
|
||||||
void ff_mpv_frame_end(MpegEncContext *s);
|
void ff_mpv_frame_end(MpegEncContext *s);
|
||||||
|
Reference in New Issue
Block a user