From 51d6dc1c83f0c606752802d872c6ae43e2705a69 Mon Sep 17 00:00:00 2001 From: Wind Yuan Date: Wed, 5 Sep 2012 22:43:52 -0400 Subject: [PATCH 2/4] h264,mpeg2,mpeg4: decode residual buffers before sequence end --- gst-libs/gst/vaapi/gstvaapidecoder_h264.c | 19 ++++++++++++++----- gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c | 11 +++++++++-- gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c | 18 +++++++++++++----- 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c index 89fef91..2b86d26 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_h264.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_h264.c @@ -2205,6 +2205,7 @@ decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) { GstVaapiDecoderH264Private * const priv = decoder->priv; GstVaapiDecoderStatus status; + gboolean is_end = FALSE; GstH264ParserResult result; GstH264NalUnit nalu; guchar *buf; @@ -2212,11 +2213,14 @@ decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) buf = GST_BUFFER_DATA(buffer); buf_size = GST_BUFFER_SIZE(buffer); - if (!buf && buf_size == 0) - return decode_sequence_end(decoder); - - gst_buffer_ref(buffer); - gst_adapter_push(priv->adapter, buffer); + if (!buf && buf_size == 0) { + if (!priv->sub_buffer || !GST_BUFFER_SIZE(priv->sub_buffer)) + return decode_sequence_end(decoder); + is_end = TRUE; + } else { + gst_buffer_ref(buffer); + gst_adapter_push(priv->adapter, buffer); + } if (priv->sub_buffer) { buffer = gst_buffer_merge(priv->sub_buffer, buffer); @@ -2293,6 +2297,11 @@ decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer) gst_adapter_flush(priv->adapter, nalu.size); ofs = nalu.offset + nalu.size; } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS && ofs < buf_size); + + if (is_end && + (status == GST_VAAPI_DECODER_STATUS_SUCCESS || + status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA)) + return decode_sequence_end(decoder); return status; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c index 38ecb33..f65f78e 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c @@ -944,6 +944,7 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) { GstVaapiDecoderMpeg2Private * const priv = decoder->priv; GstVaapiDecoderStatus status; + gboolean is_end = FALSE; guchar *buf; guint buf_size, size; guint32 start_code; @@ -953,9 +954,10 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) buf = GST_BUFFER_DATA(buffer); buf_size = GST_BUFFER_SIZE(buffer); if (!buf && buf_size == 0) - return decode_sequence_end(decoder); + is_end = TRUE; - gst_adapter_push(priv->adapter, gst_buffer_ref(buffer)); + if (buf && buf_size) + gst_adapter_push(priv->adapter, gst_buffer_ref(buffer)); size = gst_adapter_available(priv->adapter); status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; @@ -1057,6 +1059,11 @@ decode_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer) } gst_buffer_unref(buffer); } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); + + if (is_end && + (status == GST_VAAPI_DECODER_STATUS_SUCCESS || + status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA)) + return decode_sequence_end(decoder); return status; } diff --git a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c index acf9d0d..7f4fac2 100644 --- a/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c +++ b/gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c @@ -906,6 +906,7 @@ decode_buffer(GstVaapiDecoderMpeg4 *decoder, GstBuffer *buffer) { GstVaapiDecoderMpeg4Private * const priv = decoder->priv; GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN; + gboolean is_end = FALSE; guchar *buf; guint pos, buf_size; @@ -913,11 +914,14 @@ decode_buffer(GstVaapiDecoderMpeg4 *decoder, GstBuffer *buffer) buf_size = GST_BUFFER_SIZE(buffer); // visual object sequence end - if (!buf && buf_size == 0) - return decode_sequence_end(decoder); - - gst_buffer_ref(buffer); - gst_adapter_push(priv->adapter, buffer); + if (!buf && buf_size == 0) { + if (!priv->sub_buffer || !GST_BUFFER_SIZE(priv->sub_buffer)) + return decode_sequence_end(decoder); + is_end = TRUE; + } else { + gst_buffer_ref(buffer); + gst_adapter_push(priv->adapter, buffer); + } if (priv->sub_buffer) { buffer = gst_buffer_merge(priv->sub_buffer, buffer); @@ -989,6 +993,10 @@ decode_buffer(GstVaapiDecoderMpeg4 *decoder, GstBuffer *buffer) priv->sub_buffer = gst_buffer_create_sub(buffer, pos, buf_size-pos); status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; } + if (is_end && + (status == GST_VAAPI_DECODER_STATUS_SUCCESS || + status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA)) + return decode_sequence_end(decoder); return status; } -- 1.7.6.5