mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-21 22:58:16 +00:00
qsvdecoder: Release too old frames
Release too old frames manually. Fixes: https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/3163 Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6586>
This commit is contained in:
parent
7ce569359f
commit
10ffbdbb1f
1 changed files with 25 additions and 10 deletions
|
@ -37,6 +37,8 @@ using namespace Microsoft::WRL;
|
||||||
#include "gstqsvallocator_va.h"
|
#include "gstqsvallocator_va.h"
|
||||||
#endif /* G_OS_WIN32 */
|
#endif /* G_OS_WIN32 */
|
||||||
|
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_STATIC (gst_qsv_decoder_debug);
|
GST_DEBUG_CATEGORY_STATIC (gst_qsv_decoder_debug);
|
||||||
#define GST_CAT_DEFAULT gst_qsv_decoder_debug
|
#define GST_CAT_DEFAULT gst_qsv_decoder_debug
|
||||||
|
|
||||||
|
@ -524,6 +526,7 @@ gst_qsv_decoder_get_next_task (GstQsvDecoder * self)
|
||||||
static GstVideoCodecFrame *
|
static GstVideoCodecFrame *
|
||||||
gst_qsv_decoder_find_output_frame (GstQsvDecoder * self, GstClockTime pts)
|
gst_qsv_decoder_find_output_frame (GstQsvDecoder * self, GstClockTime pts)
|
||||||
{
|
{
|
||||||
|
auto videodec = GST_VIDEO_DECODER (self);
|
||||||
GList *frames, *iter;
|
GList *frames, *iter;
|
||||||
GstVideoCodecFrame *ret = nullptr;
|
GstVideoCodecFrame *ret = nullptr;
|
||||||
GstVideoCodecFrame *closest = nullptr;
|
GstVideoCodecFrame *closest = nullptr;
|
||||||
|
@ -531,9 +534,9 @@ gst_qsv_decoder_find_output_frame (GstQsvDecoder * self, GstClockTime pts)
|
||||||
|
|
||||||
/* give up, just returns the oldest frame */
|
/* give up, just returns the oldest frame */
|
||||||
if (!GST_CLOCK_TIME_IS_VALID (pts))
|
if (!GST_CLOCK_TIME_IS_VALID (pts))
|
||||||
return gst_video_decoder_get_oldest_frame (GST_VIDEO_DECODER (self));
|
return gst_video_decoder_get_oldest_frame (videodec);
|
||||||
|
|
||||||
frames = gst_video_decoder_get_frames (GST_VIDEO_DECODER (self));
|
frames = gst_video_decoder_get_frames (videodec);
|
||||||
|
|
||||||
for (iter = frames; iter; iter = g_list_next (iter)) {
|
for (iter = frames; iter; iter = g_list_next (iter)) {
|
||||||
GstVideoCodecFrame *frame = (GstVideoCodecFrame *) iter->data;
|
GstVideoCodecFrame *frame = (GstVideoCodecFrame *) iter->data;
|
||||||
|
@ -564,21 +567,33 @@ gst_qsv_decoder_find_output_frame (GstQsvDecoder * self, GstClockTime pts)
|
||||||
if (ret) {
|
if (ret) {
|
||||||
gst_video_codec_frame_ref (ret);
|
gst_video_codec_frame_ref (ret);
|
||||||
|
|
||||||
|
/* Do garbage collection */
|
||||||
|
std::queue < GstVideoCodecFrame * >old_frames;
|
||||||
|
|
||||||
/* Release older frames, it can happen if input buffer holds only single
|
/* Release older frames, it can happen if input buffer holds only single
|
||||||
* field in case of H264 */
|
* field in case of H264 or incomplete AU */
|
||||||
for (iter = frames; iter; iter = g_list_next (iter)) {
|
for (iter = frames; iter; iter = g_list_next (iter)) {
|
||||||
GstVideoCodecFrame *frame = (GstVideoCodecFrame *) iter->data;
|
GstVideoCodecFrame *frame = (GstVideoCodecFrame *) iter->data;
|
||||||
|
|
||||||
if (frame == ret)
|
if (frame == ret)
|
||||||
continue;
|
break;
|
||||||
|
|
||||||
if (!GST_CLOCK_TIME_IS_VALID (frame->pts))
|
old_frames.push (gst_video_codec_frame_ref (frame));
|
||||||
continue;
|
}
|
||||||
|
|
||||||
if (frame->pts < ret->pts) {
|
GST_LOG_OBJECT (self, "%u frames are queued before the current output",
|
||||||
gst_video_decoder_release_frame (GST_VIDEO_DECODER (self),
|
(guint) old_frames.size ());
|
||||||
gst_video_codec_frame_ref (frame));
|
|
||||||
}
|
while (old_frames.size () > 16) {
|
||||||
|
auto front = old_frames.front ();
|
||||||
|
old_frames.pop ();
|
||||||
|
gst_video_decoder_release_frame (videodec, front);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!old_frames.empty ()) {
|
||||||
|
auto front = old_frames.front ();
|
||||||
|
old_frames.pop ();
|
||||||
|
gst_video_codec_frame_unref (front);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ret = gst_video_decoder_get_oldest_frame (GST_VIDEO_DECODER (self));
|
ret = gst_video_decoder_get_oldest_frame (GST_VIDEO_DECODER (self));
|
||||||
|
|
Loading…
Reference in a new issue