GstVideoCodecFrame *frame;
gboolean mapped;
GstVideoFrame vframe;
+ GstBuffer *buffer;
} GstFFMpegVidDecVideoFrame;
static GstFFMpegVidDecVideoFrame *
if (frame->mapped)
gst_video_frame_unmap (&frame->vframe);
gst_video_decoder_release_frame (GST_VIDEO_DECODER (ffmpegdec), frame->frame);
+ gst_buffer_replace (&frame->buffer, NULL);
g_slice_free (GstFFMpegVidDecVideoFrame, frame);
}
* picture back from ffmpeg we can use this to correctly timestamp the output
* buffer */
picture->reordered_opaque = context->reordered_opaque;
+ GST_DEBUG_OBJECT (ffmpegdec, "opaque value SN %d",
+ (gint32) picture->reordered_opaque);
frame =
gst_video_decoder_get_frame (GST_VIDEO_DECODER (ffmpegdec),
if (ret != GST_FLOW_OK)
goto alloc_failed;
+ /* piggy-backed alloc'ed on the frame,
+ * and there was much rejoicing and we are grateful.
+ * Now take away buffer from frame, we will give it back later when decoded.
+ * This allows multiple request for a buffer per frame; unusual but possible. */
+ gst_buffer_replace (&dframe->buffer, frame->output_buffer);
+ gst_buffer_replace (&frame->output_buffer, NULL);
+
/* Fill avpicture */
info = &ffmpegdec->output_state->info;
- if (!gst_video_frame_map (&dframe->vframe, info, dframe->frame->output_buffer,
+ if (!gst_video_frame_map (&dframe->vframe, info, dframe->buffer,
GST_MAP_READWRITE))
goto invalid_frame;
dframe->mapped = TRUE;
}
gst_video_frame_unmap (&dframe->vframe);
dframe->mapped = FALSE;
- gst_buffer_replace (&frame->output_buffer, NULL);
+ gst_buffer_replace (&dframe->buffer, NULL);
ffmpegdec->current_dr = FALSE;
goto no_dr;
* the opaque data. */
picture->type = FF_BUFFER_TYPE_USER;
- GST_LOG_OBJECT (ffmpegdec, "returned frame %p", frame->output_buffer);
+ GST_LOG_OBJECT (ffmpegdec, "returned frame %p", dframe->buffer);
return 0;
{
/* alloc default buffer when we can't get one from downstream */
GST_LOG_OBJECT (ffmpegdec, "failed to map frame, fallback alloc");
- gst_buffer_unref (frame->output_buffer);
- frame->output_buffer = NULL;
+ gst_buffer_replace (&dframe->buffer, NULL);
goto fallback;
}
fallback:
}
}
+/* this should havesame effect as _get_buffer wrt opaque metadata,
+ * but preserving current content, if any */
static int
gst_ffmpegviddec_reget_buffer (AVCodecContext * context, AVFrame * picture)
{
ffmpegdec = (GstFFMpegVidDec *) context->opaque;
frame = (GstFFMpegVidDecVideoFrame *) picture->opaque;
- GST_DEBUG_OBJECT (ffmpegdec, "release frame %d",
+ GST_DEBUG_OBJECT (ffmpegdec, "release frame SN %d",
frame->frame->system_frame_number);
/* check if it was our buffer */
out_dframe = ffmpegdec->picture->opaque;
out_frame = gst_video_codec_frame_ref (out_dframe->frame);
+ /* also give back a buffer allocated by the frame, if any */
+ gst_buffer_replace (&out_frame->output_buffer, out_dframe->buffer);
+ gst_buffer_replace (&out_dframe->buffer, NULL);
+
GST_DEBUG_OBJECT (ffmpegdec,
"pts %" G_GUINT64_FORMAT " duration %" G_GUINT64_FORMAT,
out_frame->pts, out_frame->duration);