amc: MediaCodec::getOutputBuffer() can return NULL without exception

Happens when doing zerocopy rendering, or when passing a wrong index to it.
Handle this properly for zerocopy rendering, fail properly for the other
cases.

https://bugzilla.gnome.org/show_bug.cgi?id=760961
This commit is contained in:
Sebastian Dröge 2016-01-22 16:13:45 +02:00
parent c87a7e2667
commit 5a3744e86c
4 changed files with 72 additions and 17 deletions

View file

@ -369,6 +369,7 @@ gst_amc_codec_get_output_buffer (GstAmcCodec * codec, gint index, GError ** err)
media_codec.get_output_buffer, &buffer, index))
goto done;
if (buffer != NULL) {
ret = g_new0 (GstAmcBuffer, 1);
ret->object = gst_amc_jni_object_make_global (env, buffer);
if (!ret->object) {
@ -384,6 +385,7 @@ gst_amc_codec_get_output_buffer (GstAmcCodec * codec, gint index, GError ** err)
goto error;
}
ret->size = (*env)->GetDirectBufferCapacity (env, ret->object);
}
done:

View file

@ -493,8 +493,10 @@ retry:
is_eos = ! !(buffer_info.flags & BUFFER_FLAG_END_OF_STREAM);
buf = gst_amc_codec_get_output_buffer (self->codec, idx, &err);
if (!buf)
if (err)
goto failed_to_get_output_buffer;
else if (!buf)
goto got_null_output_buffer;
if (buffer_info.size > 0) {
GstBuffer *outbuf;
@ -699,6 +701,22 @@ failed_to_get_output_buffer:
g_mutex_unlock (&self->drain_lock);
return;
}
got_null_output_buffer:
{
GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
("Got no output buffer"));
gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
self->downstream_flow_ret = GST_FLOW_ERROR;
GST_AUDIO_DECODER_STREAM_UNLOCK (self);
g_mutex_lock (&self->drain_lock);
self->draining = FALSE;
g_cond_broadcast (&self->drain_cond);
g_mutex_unlock (&self->drain_lock);
return;
}
invalid_buffer_size:
{
GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),

View file

@ -1271,9 +1271,12 @@ retry:
is_eos = ! !(buffer_info.flags & BUFFER_FLAG_END_OF_STREAM);
buf = gst_amc_codec_get_output_buffer (self->codec, idx, &err);
if (!buf)
if (err)
goto failed_to_get_output_buffer;
if (self->codec_config != AMC_CODEC_CONFIG_WITH_SURFACE && !buf)
goto got_null_output_buffer;
if (frame
&& (deadline =
gst_video_decoder_get_max_decode_time (GST_VIDEO_DECODER (self),
@ -1574,6 +1577,21 @@ failed_to_get_output_buffer:
return;
}
got_null_output_buffer:
{
GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
("Got no output buffer"));
gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), gst_event_new_eos ());
gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self));
self->downstream_flow_ret = GST_FLOW_ERROR;
GST_VIDEO_DECODER_STREAM_UNLOCK (self);
g_mutex_lock (&self->drain_lock);
self->draining = FALSE;
g_cond_broadcast (&self->drain_cond);
g_mutex_unlock (&self->drain_lock);
return;
}
invalid_buffer:
{
GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),

View file

@ -1023,8 +1023,10 @@ process_buffer:
is_eos = ! !(buffer_info.flags & BUFFER_FLAG_END_OF_STREAM);
buf = gst_amc_codec_get_output_buffer (self->codec, idx, &err);
if (!buf)
if (err)
goto failed_to_get_output_buffer;
else if (!buf)
goto got_null_output_buffer;
flow_ret =
gst_amc_video_enc_handle_output_frame (self, buf, &buffer_info, frame);
@ -1147,7 +1149,22 @@ failed_to_get_output_buffer:
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
gst_pad_push_event (GST_VIDEO_ENCODER_SRC_PAD (self), gst_event_new_eos ());
gst_pad_pause_task (GST_VIDEO_ENCODER_SRC_PAD (self));
self->downstream_flow_ret = GST_FLOW_NOT_NEGOTIATED;
self->downstream_flow_ret = GST_FLOW_ERROR;
GST_VIDEO_ENCODER_STREAM_UNLOCK (self);
g_mutex_lock (&self->drain_lock);
self->draining = FALSE;
g_cond_broadcast (&self->drain_cond);
g_mutex_unlock (&self->drain_lock);
return;
}
got_null_output_buffer:
{
GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
("Got no output buffer"));
gst_pad_push_event (GST_VIDEO_ENCODER_SRC_PAD (self), gst_event_new_eos ());
gst_pad_pause_task (GST_VIDEO_ENCODER_SRC_PAD (self));
self->downstream_flow_ret = GST_FLOW_ERROR;
GST_VIDEO_ENCODER_STREAM_UNLOCK (self);
g_mutex_lock (&self->drain_lock);
self->draining = FALSE;