decoder: optimize and clean decode_step() up.

Avoid usage of goto. Simplify decode_step() process to first accumulate all
pending buffers into the GstAdapter, and then parse and decode units from
that input adapter. Stop the process once a frame is fully decoded or an
error occurred.
This commit is contained in:
Gwenole Beauchesne 2013-01-18 16:56:15 +01:00
parent cd52fa315a
commit a811a5de3d

View file

@ -275,26 +275,30 @@ decode_step(GstVaapiDecoder *decoder)
GstVaapiDecoderStatus status; GstVaapiDecoderStatus status;
GstBuffer *buffer; GstBuffer *buffer;
gboolean got_frame; gboolean got_frame;
guint got_unit_size; guint got_unit_size, input_size;
if (G_UNLIKELY(ps->at_eos))
return GST_VAAPI_DECODER_STATUS_END_OF_STREAM;
status = gst_vaapi_decoder_check_status(decoder); status = gst_vaapi_decoder_check_status(decoder);
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
return status; return status;
if (ps->current_frame) /* Fill adapter with all buffers we have in the queue */
goto parse; for (;;) {
do {
buffer = pop_buffer(decoder); buffer = pop_buffer(decoder);
if (!buffer) if (!buffer)
return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA; break;
ps->at_eos = GST_BUFFER_IS_EOS(buffer); ps->at_eos = GST_BUFFER_IS_EOS(buffer);
if (!ps->at_eos) if (!ps->at_eos)
gst_adapter_push(ps->input_adapter, buffer); gst_adapter_push(ps->input_adapter, buffer);
}
/* Parse and decode all decode units */
input_size = gst_adapter_available(ps->input_adapter);
if (input_size == 0) {
if (ps->at_eos)
return GST_VAAPI_DECODER_STATUS_END_OF_STREAM;
return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
}
do { do {
if (!ps->current_frame) { if (!ps->current_frame) {
@ -304,16 +308,19 @@ decode_step(GstVaapiDecoder *decoder)
ps->current_frame->ref_count = 1; ps->current_frame->ref_count = 1;
} }
parse: status = do_parse(decoder, ps->current_frame, ps->input_adapter,
status = do_parse(decoder, ps->current_frame, ps->at_eos, &got_unit_size, &got_frame);
ps->input_adapter, ps->at_eos, &got_unit_size, &got_frame);
GST_DEBUG("parse frame (status = %d)", status); GST_DEBUG("parse frame (status = %d)", status);
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA && ps->at_eos)
status = GST_VAAPI_DECODER_STATUS_END_OF_STREAM;
break; break;
}
if (got_unit_size > 0) { if (got_unit_size > 0) {
buffer = gst_adapter_take_buffer(ps->input_adapter, buffer = gst_adapter_take_buffer(ps->input_adapter, got_unit_size);
got_unit_size); input_size -= got_unit_size;
if (gst_adapter_available(ps->output_adapter) == 0) { if (gst_adapter_available(ps->output_adapter) == 0) {
ps->current_frame->pts = ps->current_frame->pts =
gst_adapter_prev_timestamp(ps->input_adapter, NULL); gst_adapter_prev_timestamp(ps->input_adapter, NULL);
@ -333,9 +340,7 @@ decode_step(GstVaapiDecoder *decoder)
ps->current_frame = NULL; ps->current_frame = NULL;
break; break;
} }
} while (status == GST_VAAPI_DECODER_STATUS_SUCCESS && } while (input_size > 0);
gst_adapter_available(ps->input_adapter) > 0);
} while (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA);
return status; return status;
} }