mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-25 19:21:06 +00:00
avviddec: Rename variables and fuse function
* gst_ffmpegviddec_frame() is the only caller of gst_ffmpegviddec_video_frame() and has the same signature. Just move the checks into a single function and use that. * Make it clear which frames are the input and output ones in gst_ffmpegviddec_video_frame() to make issues like the one fixed in the previous commit more obvious. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6851>
This commit is contained in:
parent
f858179d01
commit
aab2f59d02
1 changed files with 54 additions and 62 deletions
|
@ -1839,15 +1839,24 @@ not_negotiated:
|
|||
*/
|
||||
static gboolean
|
||||
gst_ffmpegviddec_video_frame (GstFFMpegVidDec * ffmpegdec,
|
||||
GstVideoCodecFrame * frame, GstFlowReturn * ret)
|
||||
GstVideoCodecFrame * input_frame, GstFlowReturn * ret)
|
||||
{
|
||||
gint res;
|
||||
gboolean got_frame = FALSE;
|
||||
gboolean mode_switch;
|
||||
GstVideoCodecFrame *out_frame;
|
||||
GstVideoCodecFrame *output_frame;
|
||||
GstFFMpegVidDecVideoFrame *out_dframe;
|
||||
GstBufferPool *pool;
|
||||
|
||||
if (G_UNLIKELY (ffmpegdec->context->codec == NULL))
|
||||
goto no_codec;
|
||||
|
||||
#if LIBAVCODEC_VERSION_MAJOR >= 60
|
||||
ffmpegdec->context->frame_num++;
|
||||
#else
|
||||
ffmpegdec->context->frame_number++;
|
||||
#endif
|
||||
|
||||
*ret = GST_FLOW_OK;
|
||||
|
||||
/* in case we skip frames */
|
||||
|
@ -1855,7 +1864,7 @@ gst_ffmpegviddec_video_frame (GstFFMpegVidDec * ffmpegdec,
|
|||
|
||||
/* run QoS code, we don't stop decoding the frame when we are late because
|
||||
* else we might skip a reference frame */
|
||||
gst_ffmpegviddec_do_qos (ffmpegdec, frame, &mode_switch);
|
||||
gst_ffmpegviddec_do_qos (ffmpegdec, input_frame, &mode_switch);
|
||||
|
||||
/* FFmpeg might request new buffer from other threads.
|
||||
* Release lock here */
|
||||
|
@ -1882,17 +1891,17 @@ gst_ffmpegviddec_video_frame (GstFFMpegVidDec * ffmpegdec,
|
|||
/* get the output picture timing info again */
|
||||
out_dframe = ffmpegdec->picture->opaque;
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT (60, 31, 100)
|
||||
out_frame =
|
||||
output_frame =
|
||||
gst_video_codec_frame_ref (av_buffer_get_opaque (ffmpegdec->
|
||||
picture->opaque_ref));
|
||||
#else
|
||||
g_assert (out_dframe);
|
||||
out_frame = gst_video_codec_frame_ref (out_dframe->frame);
|
||||
output_frame = gst_video_codec_frame_ref (out_dframe->frame);
|
||||
#endif
|
||||
|
||||
/* also give back a buffer allocated by the frame, if any */
|
||||
if (out_dframe) {
|
||||
gst_buffer_replace (&out_frame->output_buffer, out_dframe->buffer);
|
||||
gst_buffer_replace (&output_frame->output_buffer, out_dframe->buffer);
|
||||
gst_buffer_replace (&out_dframe->buffer, NULL);
|
||||
}
|
||||
|
||||
|
@ -1923,7 +1932,7 @@ gst_ffmpegviddec_video_frame (GstFFMpegVidDec * ffmpegdec,
|
|||
|
||||
GST_DEBUG_OBJECT (ffmpegdec,
|
||||
"pts %" G_GUINT64_FORMAT " duration %" G_GUINT64_FORMAT,
|
||||
out_frame->pts, out_frame->duration);
|
||||
output_frame->pts, output_frame->duration);
|
||||
GST_DEBUG_OBJECT (ffmpegdec, "picture: pts %" G_GUINT64_FORMAT,
|
||||
(guint64) ffmpegdec->picture->pts);
|
||||
#if LIBAVUTIL_VERSION_MAJOR < 58
|
||||
|
@ -1947,21 +1956,22 @@ gst_ffmpegviddec_video_frame (GstFFMpegVidDec * ffmpegdec,
|
|||
!!(ffmpegdec->picture->flags & AV_FRAME_FLAG_CORRUPT));
|
||||
|
||||
if (!gst_ffmpegviddec_negotiate (ffmpegdec, ffmpegdec->context,
|
||||
ffmpegdec->picture, GST_BUFFER_FLAGS (out_frame->input_buffer)))
|
||||
ffmpegdec->picture, GST_BUFFER_FLAGS (output_frame->input_buffer)))
|
||||
goto negotiation_error;
|
||||
|
||||
pool = gst_video_decoder_get_buffer_pool (GST_VIDEO_DECODER (ffmpegdec));
|
||||
if (G_UNLIKELY (out_frame->output_buffer == NULL)) {
|
||||
*ret = get_output_buffer (ffmpegdec, out_frame);
|
||||
} else if (G_UNLIKELY (out_frame->output_buffer->pool != pool)) {
|
||||
GstBuffer *tmp = out_frame->output_buffer;
|
||||
out_frame->output_buffer = NULL;
|
||||
*ret = get_output_buffer (ffmpegdec, out_frame);
|
||||
if (G_UNLIKELY (output_frame->output_buffer == NULL)) {
|
||||
*ret = get_output_buffer (ffmpegdec, output_frame);
|
||||
} else if (G_UNLIKELY (output_frame->output_buffer->pool != pool)) {
|
||||
GstBuffer *tmp = output_frame->output_buffer;
|
||||
output_frame->output_buffer = NULL;
|
||||
*ret = get_output_buffer (ffmpegdec, output_frame);
|
||||
gst_buffer_unref (tmp);
|
||||
}
|
||||
#ifndef G_DISABLE_ASSERT
|
||||
else {
|
||||
GstVideoMeta *vmeta = gst_buffer_get_video_meta (out_frame->output_buffer);
|
||||
GstVideoMeta *vmeta =
|
||||
gst_buffer_get_video_meta (output_frame->output_buffer);
|
||||
if (vmeta) {
|
||||
GstVideoInfo *info = &ffmpegdec->output_state->info;
|
||||
g_assert ((gint) vmeta->width == GST_VIDEO_INFO_WIDTH (info));
|
||||
|
@ -1976,24 +1986,27 @@ gst_ffmpegviddec_video_frame (GstFFMpegVidDec * ffmpegdec,
|
|||
|
||||
/* Mark corrupted frames as corrupted */
|
||||
if (ffmpegdec->picture->flags & AV_FRAME_FLAG_CORRUPT)
|
||||
GST_BUFFER_FLAG_SET (out_frame->output_buffer, GST_BUFFER_FLAG_CORRUPTED);
|
||||
GST_BUFFER_FLAG_SET (output_frame->output_buffer,
|
||||
GST_BUFFER_FLAG_CORRUPTED);
|
||||
|
||||
if (ffmpegdec->pic_interlaced) {
|
||||
/* set interlaced flags */
|
||||
if (ffmpegdec->picture->repeat_pict)
|
||||
GST_BUFFER_FLAG_SET (out_frame->output_buffer, GST_VIDEO_BUFFER_FLAG_RFF);
|
||||
GST_BUFFER_FLAG_SET (output_frame->output_buffer,
|
||||
GST_VIDEO_BUFFER_FLAG_RFF);
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(60, 31, 100)
|
||||
if (ffmpegdec->picture->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST)
|
||||
#else
|
||||
if (ffmpegdec->picture->top_field_first)
|
||||
#endif
|
||||
GST_BUFFER_FLAG_SET (out_frame->output_buffer, GST_VIDEO_BUFFER_FLAG_TFF);
|
||||
GST_BUFFER_FLAG_SET (output_frame->output_buffer,
|
||||
GST_VIDEO_BUFFER_FLAG_TFF);
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(60, 31, 100)
|
||||
if (ffmpegdec->picture->flags & AV_FRAME_FLAG_INTERLACED)
|
||||
#else
|
||||
if (ffmpegdec->picture->interlaced_frame)
|
||||
#endif
|
||||
GST_BUFFER_FLAG_SET (out_frame->output_buffer,
|
||||
GST_BUFFER_FLAG_SET (output_frame->output_buffer,
|
||||
GST_VIDEO_BUFFER_FLAG_INTERLACED);
|
||||
}
|
||||
|
||||
|
@ -2007,11 +2020,11 @@ gst_ffmpegviddec_video_frame (GstFFMpegVidDec * ffmpegdec,
|
|||
GST_MEMDUMP ("A53 CC", side_data->data, side_data->size);
|
||||
|
||||
/* do not add closed caption meta if it already exists */
|
||||
if (!gst_buffer_get_meta (out_frame->input_buffer,
|
||||
if (!gst_buffer_get_meta (output_frame->input_buffer,
|
||||
GST_VIDEO_CAPTION_META_API_TYPE)) {
|
||||
out_frame->output_buffer =
|
||||
gst_buffer_make_writable (out_frame->output_buffer);
|
||||
gst_buffer_add_video_caption_meta (out_frame->output_buffer,
|
||||
output_frame->output_buffer =
|
||||
gst_buffer_make_writable (output_frame->output_buffer);
|
||||
gst_buffer_add_video_caption_meta (output_frame->output_buffer,
|
||||
GST_VIDEO_CAPTION_TYPE_CEA708_RAW, side_data->data,
|
||||
side_data->size);
|
||||
} else {
|
||||
|
@ -2037,7 +2050,7 @@ gst_ffmpegviddec_video_frame (GstFFMpegVidDec * ffmpegdec,
|
|||
while (l) {
|
||||
GstVideoCodecFrame *tmp = l->data;
|
||||
|
||||
if (tmp == out_frame)
|
||||
if (tmp == output_frame)
|
||||
old = FALSE;
|
||||
|
||||
if (old && GST_VIDEO_CODEC_FRAME_IS_DECODE_ONLY (tmp)) {
|
||||
|
@ -2060,28 +2073,30 @@ gst_ffmpegviddec_video_frame (GstFFMpegVidDec * ffmpegdec,
|
|||
|
||||
av_frame_unref (ffmpegdec->picture);
|
||||
|
||||
if (frame)
|
||||
GST_VIDEO_CODEC_FRAME_FLAG_UNSET (frame,
|
||||
if (input_frame)
|
||||
GST_VIDEO_CODEC_FRAME_FLAG_UNSET (input_frame,
|
||||
GST_FFMPEG_VIDEO_CODEC_FRAME_FLAG_ALLOCATED);
|
||||
|
||||
if (gst_video_decoder_get_subframe_mode (GST_VIDEO_DECODER (ffmpegdec)))
|
||||
gst_video_decoder_have_last_subframe (GST_VIDEO_DECODER (ffmpegdec),
|
||||
out_frame);
|
||||
output_frame);
|
||||
|
||||
/* FIXME: Ideally we would remap the buffer read-only now before pushing but
|
||||
* libav might still have a reference to it!
|
||||
*/
|
||||
if (GST_BUFFER_FLAG_IS_SET (out_frame->input_buffer,
|
||||
if (GST_BUFFER_FLAG_IS_SET (output_frame->input_buffer,
|
||||
GST_VIDEO_BUFFER_FLAG_ONEFIELD)) {
|
||||
GST_BUFFER_FLAG_SET (out_frame->output_buffer,
|
||||
GST_BUFFER_FLAG_SET (output_frame->output_buffer,
|
||||
GST_VIDEO_BUFFER_FLAG_ONEFIELD);
|
||||
if (GST_BUFFER_FLAG_IS_SET (out_frame->input_buffer,
|
||||
if (GST_BUFFER_FLAG_IS_SET (output_frame->input_buffer,
|
||||
GST_VIDEO_BUFFER_FLAG_TFF)) {
|
||||
GST_BUFFER_FLAG_SET (out_frame->output_buffer, GST_VIDEO_BUFFER_FLAG_TFF);
|
||||
GST_BUFFER_FLAG_SET (output_frame->output_buffer,
|
||||
GST_VIDEO_BUFFER_FLAG_TFF);
|
||||
}
|
||||
}
|
||||
*ret =
|
||||
gst_video_decoder_finish_frame (GST_VIDEO_DECODER (ffmpegdec), out_frame);
|
||||
gst_video_decoder_finish_frame (GST_VIDEO_DECODER (ffmpegdec),
|
||||
output_frame);
|
||||
|
||||
beach:
|
||||
GST_DEBUG_OBJECT (ffmpegdec, "return flow %s, got frame: %d",
|
||||
|
@ -2092,15 +2107,15 @@ beach:
|
|||
no_output:
|
||||
{
|
||||
GST_DEBUG_OBJECT (ffmpegdec, "no output buffer");
|
||||
GST_VIDEO_CODEC_FRAME_FLAG_UNSET (frame,
|
||||
GST_VIDEO_CODEC_FRAME_FLAG_UNSET (input_frame,
|
||||
GST_FFMPEG_VIDEO_CODEC_FRAME_FLAG_ALLOCATED);
|
||||
gst_video_decoder_drop_frame (GST_VIDEO_DECODER (ffmpegdec), out_frame);
|
||||
gst_video_decoder_drop_frame (GST_VIDEO_DECODER (ffmpegdec), output_frame);
|
||||
goto beach;
|
||||
}
|
||||
|
||||
negotiation_error:
|
||||
{
|
||||
gst_video_decoder_drop_frame (GST_VIDEO_DECODER (ffmpegdec), out_frame);
|
||||
gst_video_decoder_drop_frame (GST_VIDEO_DECODER (ffmpegdec), output_frame);
|
||||
if (GST_PAD_IS_FLUSHING (GST_VIDEO_DECODER_SRC_PAD (ffmpegdec))) {
|
||||
*ret = GST_FLOW_FLUSHING;
|
||||
goto beach;
|
||||
|
@ -2109,39 +2124,16 @@ negotiation_error:
|
|||
*ret = GST_FLOW_NOT_NEGOTIATED;
|
||||
goto beach;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Returns: Whether a frame was decoded */
|
||||
static gboolean
|
||||
gst_ffmpegviddec_frame (GstFFMpegVidDec * ffmpegdec, GstVideoCodecFrame * frame,
|
||||
GstFlowReturn * ret)
|
||||
{
|
||||
gboolean got_frame = FALSE;
|
||||
|
||||
if (G_UNLIKELY (ffmpegdec->context->codec == NULL))
|
||||
goto no_codec;
|
||||
|
||||
*ret = GST_FLOW_OK;
|
||||
#if LIBAVCODEC_VERSION_MAJOR >= 60
|
||||
ffmpegdec->context->frame_num++;
|
||||
#else
|
||||
ffmpegdec->context->frame_number++;
|
||||
#endif
|
||||
|
||||
got_frame = gst_ffmpegviddec_video_frame (ffmpegdec, frame, ret);
|
||||
|
||||
return got_frame;
|
||||
|
||||
/* ERRORS */
|
||||
no_codec:
|
||||
{
|
||||
GST_ERROR_OBJECT (ffmpegdec, "no codec context");
|
||||
*ret = GST_FLOW_NOT_NEGOTIATED;
|
||||
return -1;
|
||||
goto beach;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static GstFlowReturn
|
||||
gst_ffmpegviddec_drain (GstVideoDecoder * decoder)
|
||||
{
|
||||
|
@ -2160,7 +2152,7 @@ gst_ffmpegviddec_drain (GstVideoDecoder * decoder)
|
|||
GST_VIDEO_DECODER_STREAM_LOCK (ffmpegdec);
|
||||
|
||||
do {
|
||||
got_frame = gst_ffmpegviddec_frame (ffmpegdec, NULL, &ret);
|
||||
got_frame = gst_ffmpegviddec_video_frame (ffmpegdec, NULL, &ret);
|
||||
} while (got_frame && ret == GST_FLOW_OK);
|
||||
|
||||
GST_VIDEO_DECODER_STREAM_UNLOCK (ffmpegdec);
|
||||
|
@ -2285,7 +2277,7 @@ gst_ffmpegviddec_handle_frame (GstVideoDecoder * decoder,
|
|||
|
||||
do {
|
||||
/* decode a frame of audio/video now */
|
||||
got_frame = gst_ffmpegviddec_frame (ffmpegdec, frame, &ret);
|
||||
got_frame = gst_ffmpegviddec_video_frame (ffmpegdec, frame, &ret);
|
||||
|
||||
if (ret != GST_FLOW_OK) {
|
||||
GST_LOG_OBJECT (ffmpegdec, "breaking because of flow ret %s",
|
||||
|
|
Loading…
Reference in a new issue