h264: fix end-of-stream conditions (flush).

Decode pending data in the adapter prior to processing the actual
code for end-of-stream.
This commit is contained in:
Gwenole Beauchesne 2012-10-10 10:31:39 +02:00
parent 388e881ba9
commit 6f2e885f11

View file

@ -2220,6 +2220,7 @@ decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer)
GstVaapiDecoderStatus status; GstVaapiDecoderStatus status;
GstH264ParserResult result; GstH264ParserResult result;
GstH264NalUnit nalu; GstH264NalUnit nalu;
gboolean is_eos;
const guchar *buf; const guchar *buf;
guint i, buf_size, nalu_size, size; guint i, buf_size, nalu_size, size;
guint32 start_code; guint32 start_code;
@ -2227,13 +2228,17 @@ decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer)
buf = GST_BUFFER_DATA(buffer); buf = GST_BUFFER_DATA(buffer);
buf_size = GST_BUFFER_SIZE(buffer); buf_size = GST_BUFFER_SIZE(buffer);
if (!buf && buf_size == 0) is_eos = GST_BUFFER_IS_EOS(buffer);
return decode_sequence_end(decoder); if (buf && buf_size > 0)
gst_adapter_push(priv->adapter, gst_buffer_ref(buffer)); gst_adapter_push(priv->adapter, gst_buffer_ref(buffer));
size = gst_adapter_available(priv->adapter); size = gst_adapter_available(priv->adapter);
do { do {
if (size == 0) {
status = GST_VAAPI_DECODER_STATUS_SUCCESS;
break;
}
status = gst_vaapi_decoder_check_status(GST_VAAPI_DECODER(decoder)); status = gst_vaapi_decoder_check_status(GST_VAAPI_DECODER(decoder));
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
break; break;
@ -2264,7 +2269,7 @@ decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer)
); );
} }
else { else {
if (size < 8) if (size < 4)
break; break;
ofs = scan_for_start_code(priv->adapter, 0, size, &start_code); ofs = scan_for_start_code(priv->adapter, 0, size, &start_code);
if (ofs < 0) if (ofs < 0)
@ -2272,11 +2277,14 @@ decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer)
gst_adapter_flush(priv->adapter, ofs); gst_adapter_flush(priv->adapter, ofs);
size -= ofs; size -= ofs;
if (size < 8) ofs = G_UNLIKELY(size < 8) ? -1 :
break; scan_for_start_code(priv->adapter, 4, size - 4, NULL);
ofs = scan_for_start_code(priv->adapter, 4, size - 4, NULL); if (ofs < 0) {
if (ofs < 0) // Assume the whole NAL unit is present if end-of-stream
if (!is_eos)
break; break;
ofs = size;
}
buffer = gst_adapter_take_buffer(priv->adapter, ofs); buffer = gst_adapter_take_buffer(priv->adapter, ofs);
size -= ofs; size -= ofs;
@ -2328,6 +2336,10 @@ decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer)
} }
gst_buffer_unref(buffer); gst_buffer_unref(buffer);
} while (status == GST_VAAPI_DECODER_STATUS_SUCCESS); } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS);
if (is_eos && (status == GST_VAAPI_DECODER_STATUS_SUCCESS ||
status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA))
status = decode_sequence_end(decoder);
return status; return status;
} }