mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 08:46:40 +00:00
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:
parent
c87a7e2667
commit
5a3744e86c
4 changed files with 72 additions and 17 deletions
|
@ -369,21 +369,23 @@ gst_amc_codec_get_output_buffer (GstAmcCodec * codec, gint index, GError ** err)
|
||||||
media_codec.get_output_buffer, &buffer, index))
|
media_codec.get_output_buffer, &buffer, index))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
ret = g_new0 (GstAmcBuffer, 1);
|
if (buffer != NULL) {
|
||||||
ret->object = gst_amc_jni_object_make_global (env, buffer);
|
ret = g_new0 (GstAmcBuffer, 1);
|
||||||
if (!ret->object) {
|
ret->object = gst_amc_jni_object_make_global (env, buffer);
|
||||||
gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
|
if (!ret->object) {
|
||||||
GST_LIBRARY_ERROR_FAILED, "Failed to create global buffer reference");
|
gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
|
||||||
goto error;
|
GST_LIBRARY_ERROR_FAILED, "Failed to create global buffer reference");
|
||||||
}
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
ret->data = (*env)->GetDirectBufferAddress (env, ret->object);
|
ret->data = (*env)->GetDirectBufferAddress (env, ret->object);
|
||||||
if (!ret->data) {
|
if (!ret->data) {
|
||||||
gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
|
gst_amc_jni_set_error (env, err, GST_LIBRARY_ERROR,
|
||||||
GST_LIBRARY_ERROR_FAILED, "Failed to get buffer address");
|
GST_LIBRARY_ERROR_FAILED, "Failed to get buffer address");
|
||||||
goto error;
|
goto error;
|
||||||
|
}
|
||||||
|
ret->size = (*env)->GetDirectBufferCapacity (env, ret->object);
|
||||||
}
|
}
|
||||||
ret->size = (*env)->GetDirectBufferCapacity (env, ret->object);
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
|
||||||
|
|
|
@ -493,8 +493,10 @@ retry:
|
||||||
is_eos = ! !(buffer_info.flags & BUFFER_FLAG_END_OF_STREAM);
|
is_eos = ! !(buffer_info.flags & BUFFER_FLAG_END_OF_STREAM);
|
||||||
|
|
||||||
buf = gst_amc_codec_get_output_buffer (self->codec, idx, &err);
|
buf = gst_amc_codec_get_output_buffer (self->codec, idx, &err);
|
||||||
if (!buf)
|
if (err)
|
||||||
goto failed_to_get_output_buffer;
|
goto failed_to_get_output_buffer;
|
||||||
|
else if (!buf)
|
||||||
|
goto got_null_output_buffer;
|
||||||
|
|
||||||
if (buffer_info.size > 0) {
|
if (buffer_info.size > 0) {
|
||||||
GstBuffer *outbuf;
|
GstBuffer *outbuf;
|
||||||
|
@ -699,6 +701,22 @@ failed_to_get_output_buffer:
|
||||||
g_mutex_unlock (&self->drain_lock);
|
g_mutex_unlock (&self->drain_lock);
|
||||||
return;
|
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:
|
invalid_buffer_size:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
|
GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
|
||||||
|
|
|
@ -1271,9 +1271,12 @@ retry:
|
||||||
is_eos = ! !(buffer_info.flags & BUFFER_FLAG_END_OF_STREAM);
|
is_eos = ! !(buffer_info.flags & BUFFER_FLAG_END_OF_STREAM);
|
||||||
|
|
||||||
buf = gst_amc_codec_get_output_buffer (self->codec, idx, &err);
|
buf = gst_amc_codec_get_output_buffer (self->codec, idx, &err);
|
||||||
if (!buf)
|
if (err)
|
||||||
goto failed_to_get_output_buffer;
|
goto failed_to_get_output_buffer;
|
||||||
|
|
||||||
|
if (self->codec_config != AMC_CODEC_CONFIG_WITH_SURFACE && !buf)
|
||||||
|
goto got_null_output_buffer;
|
||||||
|
|
||||||
if (frame
|
if (frame
|
||||||
&& (deadline =
|
&& (deadline =
|
||||||
gst_video_decoder_get_max_decode_time (GST_VIDEO_DECODER (self),
|
gst_video_decoder_get_max_decode_time (GST_VIDEO_DECODER (self),
|
||||||
|
@ -1574,6 +1577,21 @@ failed_to_get_output_buffer:
|
||||||
return;
|
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:
|
invalid_buffer:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
|
GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
|
||||||
|
|
|
@ -1023,8 +1023,10 @@ process_buffer:
|
||||||
is_eos = ! !(buffer_info.flags & BUFFER_FLAG_END_OF_STREAM);
|
is_eos = ! !(buffer_info.flags & BUFFER_FLAG_END_OF_STREAM);
|
||||||
|
|
||||||
buf = gst_amc_codec_get_output_buffer (self->codec, idx, &err);
|
buf = gst_amc_codec_get_output_buffer (self->codec, idx, &err);
|
||||||
if (!buf)
|
if (err)
|
||||||
goto failed_to_get_output_buffer;
|
goto failed_to_get_output_buffer;
|
||||||
|
else if (!buf)
|
||||||
|
goto got_null_output_buffer;
|
||||||
|
|
||||||
flow_ret =
|
flow_ret =
|
||||||
gst_amc_video_enc_handle_output_frame (self, buf, &buffer_info, frame);
|
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_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
gst_pad_push_event (GST_VIDEO_ENCODER_SRC_PAD (self), gst_event_new_eos ());
|
gst_pad_push_event (GST_VIDEO_ENCODER_SRC_PAD (self), gst_event_new_eos ());
|
||||||
gst_pad_pause_task (GST_VIDEO_ENCODER_SRC_PAD (self));
|
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);
|
GST_VIDEO_ENCODER_STREAM_UNLOCK (self);
|
||||||
g_mutex_lock (&self->drain_lock);
|
g_mutex_lock (&self->drain_lock);
|
||||||
self->draining = FALSE;
|
self->draining = FALSE;
|
||||||
|
|
Loading…
Reference in a new issue