mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
androidmedia: Add exceptions from the Java API to error messages, and post more error/warning messages overall
This commit is contained in:
parent
440574d963
commit
f844af2320
5 changed files with 384 additions and 171 deletions
|
@ -3859,8 +3859,8 @@ gst_amc_codec_info_to_caps (const GstAmcCodecInfo * codec_info,
|
||||||
const gchar *profile;
|
const gchar *profile;
|
||||||
|
|
||||||
profile =
|
profile =
|
||||||
gst_amc_mpeg4_profile_to_string (type->
|
gst_amc_mpeg4_profile_to_string (type->profile_levels[j].
|
||||||
profile_levels[j].profile);
|
profile);
|
||||||
if (!profile) {
|
if (!profile) {
|
||||||
GST_ERROR ("Unable to map MPEG4 profile 0x%08x",
|
GST_ERROR ("Unable to map MPEG4 profile 0x%08x",
|
||||||
type->profile_levels[j].profile);
|
type->profile_levels[j].profile);
|
||||||
|
@ -3933,8 +3933,8 @@ gst_amc_codec_info_to_caps (const GstAmcCodecInfo * codec_info,
|
||||||
gint profile;
|
gint profile;
|
||||||
|
|
||||||
profile =
|
profile =
|
||||||
gst_amc_h263_profile_to_gst_id (type->
|
gst_amc_h263_profile_to_gst_id (type->profile_levels[j].
|
||||||
profile_levels[j].profile);
|
profile);
|
||||||
|
|
||||||
if (profile == -1) {
|
if (profile == -1) {
|
||||||
GST_ERROR ("Unable to map h263 profile 0x%08x",
|
GST_ERROR ("Unable to map h263 profile 0x%08x",
|
||||||
|
@ -3998,8 +3998,8 @@ gst_amc_codec_info_to_caps (const GstAmcCodecInfo * codec_info,
|
||||||
const gchar *profile, *alternative = NULL;
|
const gchar *profile, *alternative = NULL;
|
||||||
|
|
||||||
profile =
|
profile =
|
||||||
gst_amc_avc_profile_to_string (type->
|
gst_amc_avc_profile_to_string (type->profile_levels[j].
|
||||||
profile_levels[j].profile, &alternative);
|
profile, &alternative);
|
||||||
|
|
||||||
if (!profile) {
|
if (!profile) {
|
||||||
GST_ERROR ("Unable to map H264 profile 0x%08x",
|
GST_ERROR ("Unable to map H264 profile 0x%08x",
|
||||||
|
|
|
@ -165,6 +165,23 @@ gboolean gst_amc_audio_channel_mask_to_positions (guint32 channel_mask, gint cha
|
||||||
guint32 gst_amc_audio_channel_mask_from_positions (GstAudioChannelPosition *positions, gint channels);
|
guint32 gst_amc_audio_channel_mask_from_positions (GstAudioChannelPosition *positions, gint channels);
|
||||||
void gst_amc_codec_info_to_caps (const GstAmcCodecInfo * codec_info, GstCaps **sink_caps, GstCaps **src_caps);
|
void gst_amc_codec_info_to_caps (const GstAmcCodecInfo * codec_info, GstCaps **sink_caps, GstCaps **src_caps);
|
||||||
|
|
||||||
|
#define GST_ELEMENT_ERROR_FROM_ERROR(el, err) G_STMT_START { \
|
||||||
|
gchar *__dbg = g_strdup (err->message); \
|
||||||
|
GST_WARNING_OBJECT (el, "error: %s", __dbg); \
|
||||||
|
gst_element_message_full (GST_ELEMENT(el), GST_MESSAGE_ERROR, \
|
||||||
|
err->domain, err->code, \
|
||||||
|
NULL, __dbg, __FILE__, GST_FUNCTION, __LINE__); \
|
||||||
|
g_clear_error (&err); \
|
||||||
|
} G_STMT_END
|
||||||
|
|
||||||
|
#define GST_ELEMENT_WARNING_FROM_ERROR(el, err) G_STMT_START { \
|
||||||
|
gchar *__dbg = g_strdup (err->message); \
|
||||||
|
GST_WARNING_OBJECT (el, "error: %s", __dbg); \
|
||||||
|
gst_element_message_full (GST_ELEMENT(el), GST_MESSAGE_WARNING, \
|
||||||
|
err->domain, err->code, \
|
||||||
|
NULL, __dbg, __FILE__, GST_FUNCTION, __LINE__); \
|
||||||
|
g_clear_error (&err); \
|
||||||
|
} G_STMT_END
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -225,12 +225,15 @@ gst_amc_audio_dec_open (GstAudioDecoder * decoder)
|
||||||
{
|
{
|
||||||
GstAmcAudioDec *self = GST_AMC_AUDIO_DEC (decoder);
|
GstAmcAudioDec *self = GST_AMC_AUDIO_DEC (decoder);
|
||||||
GstAmcAudioDecClass *klass = GST_AMC_AUDIO_DEC_GET_CLASS (self);
|
GstAmcAudioDecClass *klass = GST_AMC_AUDIO_DEC_GET_CLASS (self);
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (self, "Opening decoder");
|
GST_DEBUG_OBJECT (self, "Opening decoder");
|
||||||
|
|
||||||
self->codec = gst_amc_codec_new (klass->codec_info->name);
|
self->codec = gst_amc_codec_new (klass->codec_info->name, &err);
|
||||||
if (!self->codec)
|
if (!self->codec) {
|
||||||
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
self->started = FALSE;
|
self->started = FALSE;
|
||||||
self->flushing = TRUE;
|
self->flushing = TRUE;
|
||||||
|
|
||||||
|
@ -247,7 +250,12 @@ gst_amc_audio_dec_close (GstAudioDecoder * decoder)
|
||||||
GST_DEBUG_OBJECT (self, "Closing decoder");
|
GST_DEBUG_OBJECT (self, "Closing decoder");
|
||||||
|
|
||||||
if (self->codec) {
|
if (self->codec) {
|
||||||
gst_amc_codec_release (self->codec);
|
GError *err = NULL;
|
||||||
|
|
||||||
|
gst_amc_codec_release (self->codec, &err);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
|
|
||||||
gst_amc_codec_free (self->codec);
|
gst_amc_codec_free (self->codec);
|
||||||
}
|
}
|
||||||
self->codec = NULL;
|
self->codec = NULL;
|
||||||
|
@ -276,6 +284,7 @@ gst_amc_audio_dec_change_state (GstElement * element, GstStateChange transition)
|
||||||
{
|
{
|
||||||
GstAmcAudioDec *self;
|
GstAmcAudioDec *self;
|
||||||
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
|
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_AMC_AUDIO_DEC (element),
|
g_return_val_if_fail (GST_IS_AMC_AUDIO_DEC (element),
|
||||||
GST_STATE_CHANGE_FAILURE);
|
GST_STATE_CHANGE_FAILURE);
|
||||||
|
@ -293,7 +302,9 @@ gst_amc_audio_dec_change_state (GstElement * element, GstStateChange transition)
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||||
self->flushing = TRUE;
|
self->flushing = TRUE;
|
||||||
gst_amc_codec_flush (self->codec);
|
gst_amc_codec_flush (self->codec, &err);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
g_mutex_lock (&self->drain_lock);
|
g_mutex_lock (&self->drain_lock);
|
||||||
self->draining = FALSE;
|
self->draining = FALSE;
|
||||||
g_cond_broadcast (&self->drain_cond);
|
g_cond_broadcast (&self->drain_cond);
|
||||||
|
@ -333,10 +344,13 @@ gst_amc_audio_dec_set_src_caps (GstAmcAudioDec * self, GstAmcFormat * format)
|
||||||
gint rate, channels;
|
gint rate, channels;
|
||||||
guint32 channel_mask = 0;
|
guint32 channel_mask = 0;
|
||||||
GstAudioChannelPosition to[64];
|
GstAudioChannelPosition to[64];
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
if (!gst_amc_format_get_int (format, "sample-rate", &rate) ||
|
if (!gst_amc_format_get_int (format, "sample-rate", &rate, &err) ||
|
||||||
!gst_amc_format_get_int (format, "channel-count", &channels)) {
|
!gst_amc_format_get_int (format, "channel-count", &channels, &err)) {
|
||||||
GST_ERROR_OBJECT (self, "Failed to get output format metadata");
|
GST_ERROR_OBJECT (self, "Failed to get output format metadata: %s",
|
||||||
|
err->message);
|
||||||
|
g_clear_error (&err);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,8 +360,9 @@ gst_amc_audio_dec_set_src_caps (GstAmcAudioDec * self, GstAmcFormat * format)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not always present */
|
/* Not always present */
|
||||||
if (gst_amc_format_contains_key (format, "channel-mask"))
|
if (gst_amc_format_contains_key (format, "channel-mask", NULL))
|
||||||
gst_amc_format_get_int (format, "channel-mask", (gint *) & channel_mask);
|
gst_amc_format_get_int (format, "channel-mask", (gint *) & channel_mask,
|
||||||
|
NULL);
|
||||||
|
|
||||||
gst_amc_audio_channel_mask_to_positions (channel_mask, channels,
|
gst_amc_audio_channel_mask_to_positions (channel_mask, channels,
|
||||||
self->positions);
|
self->positions);
|
||||||
|
@ -380,6 +395,7 @@ gst_amc_audio_dec_loop (GstAmcAudioDec * self)
|
||||||
gboolean is_eos;
|
gboolean is_eos;
|
||||||
GstAmcBufferInfo buffer_info;
|
GstAmcBufferInfo buffer_info;
|
||||||
gint idx;
|
gint idx;
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
GST_AUDIO_DECODER_STREAM_LOCK (self);
|
GST_AUDIO_DECODER_STREAM_LOCK (self);
|
||||||
|
|
||||||
|
@ -391,13 +407,17 @@ retry:
|
||||||
GST_AUDIO_DECODER_STREAM_UNLOCK (self);
|
GST_AUDIO_DECODER_STREAM_UNLOCK (self);
|
||||||
/* Wait at most 100ms here, some codecs don't fail dequeueing if
|
/* Wait at most 100ms here, some codecs don't fail dequeueing if
|
||||||
* the codec is flushing, causing deadlocks during shutdown */
|
* the codec is flushing, causing deadlocks during shutdown */
|
||||||
idx = gst_amc_codec_dequeue_output_buffer (self->codec, &buffer_info, 100000);
|
idx =
|
||||||
|
gst_amc_codec_dequeue_output_buffer (self->codec, &buffer_info, 100000,
|
||||||
|
&err);
|
||||||
GST_AUDIO_DECODER_STREAM_LOCK (self);
|
GST_AUDIO_DECODER_STREAM_LOCK (self);
|
||||||
/*} */
|
/*} */
|
||||||
|
|
||||||
if (idx < 0) {
|
if (idx < 0) {
|
||||||
if (self->flushing)
|
if (self->flushing) {
|
||||||
|
g_clear_error (&err);
|
||||||
goto flushing;
|
goto flushing;
|
||||||
|
}
|
||||||
|
|
||||||
switch (idx) {
|
switch (idx) {
|
||||||
case INFO_OUTPUT_BUFFERS_CHANGED:{
|
case INFO_OUTPUT_BUFFERS_CHANGED:{
|
||||||
|
@ -407,7 +427,7 @@ retry:
|
||||||
self->n_output_buffers);
|
self->n_output_buffers);
|
||||||
self->output_buffers =
|
self->output_buffers =
|
||||||
gst_amc_codec_get_output_buffers (self->codec,
|
gst_amc_codec_get_output_buffers (self->codec,
|
||||||
&self->n_output_buffers);
|
&self->n_output_buffers, &err);
|
||||||
if (!self->output_buffers)
|
if (!self->output_buffers)
|
||||||
goto get_output_buffers_error;
|
goto get_output_buffers_error;
|
||||||
break;
|
break;
|
||||||
|
@ -418,11 +438,15 @@ retry:
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (self, "Output format has changed");
|
GST_DEBUG_OBJECT (self, "Output format has changed");
|
||||||
|
|
||||||
format = gst_amc_codec_get_output_format (self->codec);
|
format = gst_amc_codec_get_output_format (self->codec, &err);
|
||||||
if (!format)
|
if (!format)
|
||||||
goto format_error;
|
goto format_error;
|
||||||
|
|
||||||
format_string = gst_amc_format_to_string (format);
|
format_string = gst_amc_format_to_string (format, &err);
|
||||||
|
if (err) {
|
||||||
|
gst_amc_format_free (format);
|
||||||
|
goto format_error;
|
||||||
|
}
|
||||||
GST_DEBUG_OBJECT (self, "Got new output format: %s", format_string);
|
GST_DEBUG_OBJECT (self, "Got new output format: %s", format_string);
|
||||||
g_free (format_string);
|
g_free (format_string);
|
||||||
|
|
||||||
|
@ -437,7 +461,7 @@ retry:
|
||||||
self->n_output_buffers);
|
self->n_output_buffers);
|
||||||
self->output_buffers =
|
self->output_buffers =
|
||||||
gst_amc_codec_get_output_buffers (self->codec,
|
gst_amc_codec_get_output_buffers (self->codec,
|
||||||
&self->n_output_buffers);
|
&self->n_output_buffers, &err);
|
||||||
if (!self->output_buffers)
|
if (!self->output_buffers)
|
||||||
goto get_output_buffers_error;
|
goto get_output_buffers_error;
|
||||||
|
|
||||||
|
@ -538,7 +562,7 @@ retry:
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (!gst_amc_codec_release_output_buffer (self->codec, idx))
|
if (!gst_amc_codec_release_output_buffer (self->codec, idx, &err))
|
||||||
goto failed_release;
|
goto failed_release;
|
||||||
|
|
||||||
if (is_eos || flow_ret == GST_FLOW_EOS) {
|
if (is_eos || flow_ret == GST_FLOW_EOS) {
|
||||||
|
@ -569,8 +593,7 @@ done:
|
||||||
|
|
||||||
dequeue_error:
|
dequeue_error:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
("Failed to dequeue output buffer"));
|
|
||||||
gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
|
gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
|
||||||
gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
|
gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
|
||||||
self->downstream_flow_ret = GST_FLOW_ERROR;
|
self->downstream_flow_ret = GST_FLOW_ERROR;
|
||||||
|
@ -580,8 +603,7 @@ dequeue_error:
|
||||||
|
|
||||||
get_output_buffers_error:
|
get_output_buffers_error:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
("Failed to get output buffers"));
|
|
||||||
gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
|
gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
|
||||||
gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
|
gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
|
||||||
self->downstream_flow_ret = GST_FLOW_ERROR;
|
self->downstream_flow_ret = GST_FLOW_ERROR;
|
||||||
|
@ -591,6 +613,9 @@ get_output_buffers_error:
|
||||||
|
|
||||||
format_error:
|
format_error:
|
||||||
{
|
{
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
|
else
|
||||||
GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
|
GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
|
||||||
("Failed to handle format"));
|
("Failed to handle format"));
|
||||||
gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
|
gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
|
||||||
|
@ -601,8 +626,7 @@ format_error:
|
||||||
}
|
}
|
||||||
failed_release:
|
failed_release:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
("Failed to release output buffer index %d", idx));
|
|
||||||
gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
|
gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
|
||||||
gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
|
gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
|
||||||
self->downstream_flow_ret = GST_FLOW_ERROR;
|
self->downstream_flow_ret = GST_FLOW_ERROR;
|
||||||
|
@ -654,7 +678,9 @@ invalid_buffer_size:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
|
GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
|
||||||
("Invalid buffer size %u (bfp %d)", buffer_info.size, self->info.bpf));
|
("Invalid buffer size %u (bfp %d)", buffer_info.size, self->info.bpf));
|
||||||
gst_amc_codec_release_output_buffer (self->codec, idx);
|
gst_amc_codec_release_output_buffer (self->codec, idx, &err);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
|
gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
|
||||||
gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
|
gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
|
||||||
self->downstream_flow_ret = GST_FLOW_ERROR;
|
self->downstream_flow_ret = GST_FLOW_ERROR;
|
||||||
|
@ -666,7 +692,9 @@ failed_allocate:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
|
GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL),
|
||||||
("Failed to allocate output buffer"));
|
("Failed to allocate output buffer"));
|
||||||
gst_amc_codec_release_output_buffer (self->codec, idx);
|
gst_amc_codec_release_output_buffer (self->codec, idx, &err);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
|
gst_pad_push_event (GST_AUDIO_DECODER_SRC_PAD (self), gst_event_new_eos ());
|
||||||
gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
|
gst_pad_pause_task (GST_AUDIO_DECODER_SRC_PAD (self));
|
||||||
self->downstream_flow_ret = GST_FLOW_ERROR;
|
self->downstream_flow_ret = GST_FLOW_ERROR;
|
||||||
|
@ -694,13 +722,18 @@ static gboolean
|
||||||
gst_amc_audio_dec_stop (GstAudioDecoder * decoder)
|
gst_amc_audio_dec_stop (GstAudioDecoder * decoder)
|
||||||
{
|
{
|
||||||
GstAmcAudioDec *self;
|
GstAmcAudioDec *self;
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
self = GST_AMC_AUDIO_DEC (decoder);
|
self = GST_AMC_AUDIO_DEC (decoder);
|
||||||
GST_DEBUG_OBJECT (self, "Stopping decoder");
|
GST_DEBUG_OBJECT (self, "Stopping decoder");
|
||||||
self->flushing = TRUE;
|
self->flushing = TRUE;
|
||||||
if (self->started) {
|
if (self->started) {
|
||||||
gst_amc_codec_flush (self->codec);
|
gst_amc_codec_flush (self->codec, &err);
|
||||||
gst_amc_codec_stop (self->codec);
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
|
gst_amc_codec_stop (self->codec, &err);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
self->started = FALSE;
|
self->started = FALSE;
|
||||||
if (self->input_buffers)
|
if (self->input_buffers)
|
||||||
gst_amc_codec_free_buffers (self->input_buffers, self->n_input_buffers);
|
gst_amc_codec_free_buffers (self->input_buffers, self->n_input_buffers);
|
||||||
|
@ -739,6 +772,7 @@ gst_amc_audio_dec_set_format (GstAudioDecoder * decoder, GstCaps * caps)
|
||||||
gboolean needs_disable = FALSE;
|
gboolean needs_disable = FALSE;
|
||||||
gchar *format_string;
|
gchar *format_string;
|
||||||
gint rate, channels;
|
gint rate, channels;
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
self = GST_AMC_AUDIO_DEC (decoder);
|
self = GST_AMC_AUDIO_DEC (decoder);
|
||||||
|
|
||||||
|
@ -794,9 +828,9 @@ gst_amc_audio_dec_set_format (GstAudioDecoder * decoder, GstCaps * caps)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
format = gst_amc_format_new_audio (mime, rate, channels);
|
format = gst_amc_format_new_audio (mime, rate, channels, &err);
|
||||||
if (!format) {
|
if (!format) {
|
||||||
GST_ERROR_OBJECT (self, "Failed to create audio format");
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -813,7 +847,9 @@ gst_amc_audio_dec_set_format (GstAudioDecoder * decoder, GstCaps * caps)
|
||||||
gst_buffer_map (codec_data, &minfo, GST_MAP_READ);
|
gst_buffer_map (codec_data, &minfo, GST_MAP_READ);
|
||||||
data = g_memdup (minfo.data, minfo.size);
|
data = g_memdup (minfo.data, minfo.size);
|
||||||
self->codec_datas = g_list_prepend (self->codec_datas, data);
|
self->codec_datas = g_list_prepend (self->codec_datas, data);
|
||||||
gst_amc_format_set_buffer (format, "csd-0", data, minfo.size);
|
gst_amc_format_set_buffer (format, "csd-0", data, minfo.size, &err);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
gst_buffer_unmap (codec_data, &minfo);
|
gst_buffer_unmap (codec_data, &minfo);
|
||||||
} else if (gst_structure_has_field (s, "streamheader")) {
|
} else if (gst_structure_has_field (s, "streamheader")) {
|
||||||
const GValue *sh = gst_structure_get_value (s, "streamheader");
|
const GValue *sh = gst_structure_get_value (s, "streamheader");
|
||||||
|
@ -843,36 +879,45 @@ gst_amc_audio_dec_set_format (GstAudioDecoder * decoder, GstCaps * caps)
|
||||||
gst_buffer_map (buf, &minfo, GST_MAP_READ);
|
gst_buffer_map (buf, &minfo, GST_MAP_READ);
|
||||||
data = g_memdup (minfo.data, minfo.size);
|
data = g_memdup (minfo.data, minfo.size);
|
||||||
self->codec_datas = g_list_prepend (self->codec_datas, data);
|
self->codec_datas = g_list_prepend (self->codec_datas, data);
|
||||||
gst_amc_format_set_buffer (format, fname, data, minfo.size);
|
gst_amc_format_set_buffer (format, fname, data, minfo.size, &err);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
gst_buffer_unmap (buf, &minfo);
|
gst_buffer_unmap (buf, &minfo);
|
||||||
g_free (fname);
|
g_free (fname);
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
format_string = gst_amc_format_to_string (format);
|
format_string = gst_amc_format_to_string (format, &err);
|
||||||
GST_DEBUG_OBJECT (self, "Configuring codec with format: %s", format_string);
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
|
GST_DEBUG_OBJECT (self, "Configuring codec with format: %s",
|
||||||
|
GST_STR_NULL (format_string));
|
||||||
g_free (format_string);
|
g_free (format_string);
|
||||||
|
|
||||||
self->n_buffers = 0;
|
self->n_buffers = 0;
|
||||||
if (!gst_amc_codec_configure (self->codec, format, 0)) {
|
if (!gst_amc_codec_configure (self->codec, format, 0, &err)) {
|
||||||
GST_ERROR_OBJECT (self, "Failed to configure codec");
|
GST_ERROR_OBJECT (self, "Failed to configure codec");
|
||||||
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_amc_format_free (format);
|
gst_amc_format_free (format);
|
||||||
|
|
||||||
if (!gst_amc_codec_start (self->codec)) {
|
if (!gst_amc_codec_start (self->codec, &err)) {
|
||||||
GST_ERROR_OBJECT (self, "Failed to start codec");
|
GST_ERROR_OBJECT (self, "Failed to start codec");
|
||||||
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->input_buffers)
|
if (self->input_buffers)
|
||||||
gst_amc_codec_free_buffers (self->input_buffers, self->n_input_buffers);
|
gst_amc_codec_free_buffers (self->input_buffers, self->n_input_buffers);
|
||||||
self->input_buffers =
|
self->input_buffers =
|
||||||
gst_amc_codec_get_input_buffers (self->codec, &self->n_input_buffers);
|
gst_amc_codec_get_input_buffers (self->codec, &self->n_input_buffers,
|
||||||
|
&err);
|
||||||
if (!self->input_buffers) {
|
if (!self->input_buffers) {
|
||||||
GST_ERROR_OBJECT (self, "Failed to get input buffers");
|
GST_ERROR_OBJECT (self, "Failed to get input buffers");
|
||||||
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -912,6 +957,7 @@ static void
|
||||||
gst_amc_audio_dec_flush (GstAudioDecoder * decoder, gboolean hard)
|
gst_amc_audio_dec_flush (GstAudioDecoder * decoder, gboolean hard)
|
||||||
{
|
{
|
||||||
GstAmcAudioDec *self;
|
GstAmcAudioDec *self;
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
self = GST_AMC_AUDIO_DEC (decoder);
|
self = GST_AMC_AUDIO_DEC (decoder);
|
||||||
|
|
||||||
|
@ -930,7 +976,9 @@ gst_amc_audio_dec_flush (GstAudioDecoder * decoder, gboolean hard)
|
||||||
GST_PAD_STREAM_LOCK (GST_AUDIO_DECODER_SRC_PAD (self));
|
GST_PAD_STREAM_LOCK (GST_AUDIO_DECODER_SRC_PAD (self));
|
||||||
GST_PAD_STREAM_UNLOCK (GST_AUDIO_DECODER_SRC_PAD (self));
|
GST_PAD_STREAM_UNLOCK (GST_AUDIO_DECODER_SRC_PAD (self));
|
||||||
GST_AUDIO_DECODER_STREAM_LOCK (self);
|
GST_AUDIO_DECODER_STREAM_LOCK (self);
|
||||||
gst_amc_codec_flush (self->codec);
|
gst_amc_codec_flush (self->codec, &err);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
self->flushing = FALSE;
|
self->flushing = FALSE;
|
||||||
|
|
||||||
/* Start the srcpad loop again */
|
/* Start the srcpad loop again */
|
||||||
|
@ -953,6 +1001,7 @@ gst_amc_audio_dec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf)
|
||||||
guint offset = 0;
|
guint offset = 0;
|
||||||
GstClockTime timestamp, duration, timestamp_offset = 0;
|
GstClockTime timestamp, duration, timestamp_offset = 0;
|
||||||
GstMapInfo minfo;
|
GstMapInfo minfo;
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
memset (&minfo, 0, sizeof (minfo));
|
memset (&minfo, 0, sizeof (minfo));
|
||||||
|
|
||||||
|
@ -1001,12 +1050,15 @@ gst_amc_audio_dec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf)
|
||||||
GST_AUDIO_DECODER_STREAM_UNLOCK (self);
|
GST_AUDIO_DECODER_STREAM_UNLOCK (self);
|
||||||
/* Wait at most 100ms here, some codecs don't fail dequeueing if
|
/* Wait at most 100ms here, some codecs don't fail dequeueing if
|
||||||
* the codec is flushing, causing deadlocks during shutdown */
|
* the codec is flushing, causing deadlocks during shutdown */
|
||||||
idx = gst_amc_codec_dequeue_input_buffer (self->codec, 100000);
|
idx = gst_amc_codec_dequeue_input_buffer (self->codec, 100000, &err);
|
||||||
GST_AUDIO_DECODER_STREAM_LOCK (self);
|
GST_AUDIO_DECODER_STREAM_LOCK (self);
|
||||||
|
|
||||||
if (idx < 0) {
|
if (idx < 0) {
|
||||||
if (self->flushing)
|
if (self->flushing) {
|
||||||
|
g_clear_error (&err);
|
||||||
goto flushing;
|
goto flushing;
|
||||||
|
}
|
||||||
|
|
||||||
switch (idx) {
|
switch (idx) {
|
||||||
case INFO_TRY_AGAIN_LATER:
|
case INFO_TRY_AGAIN_LATER:
|
||||||
GST_DEBUG_OBJECT (self, "Dequeueing input buffer timed out");
|
GST_DEBUG_OBJECT (self, "Dequeueing input buffer timed out");
|
||||||
|
@ -1031,7 +1083,9 @@ gst_amc_audio_dec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf)
|
||||||
|
|
||||||
if (self->downstream_flow_ret != GST_FLOW_OK) {
|
if (self->downstream_flow_ret != GST_FLOW_OK) {
|
||||||
memset (&buffer_info, 0, sizeof (buffer_info));
|
memset (&buffer_info, 0, sizeof (buffer_info));
|
||||||
gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info);
|
gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info, &err);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
goto downstream_error;
|
goto downstream_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1071,7 +1125,8 @@ gst_amc_audio_dec_handle_frame (GstAudioDecoder * decoder, GstBuffer * inbuf)
|
||||||
"Queueing buffer %d: size %d time %" G_GINT64_FORMAT " flags 0x%08x",
|
"Queueing buffer %d: size %d time %" G_GINT64_FORMAT " flags 0x%08x",
|
||||||
idx, buffer_info.size, buffer_info.presentation_time_us,
|
idx, buffer_info.size, buffer_info.presentation_time_us,
|
||||||
buffer_info.flags);
|
buffer_info.flags);
|
||||||
if (!gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info))
|
if (!gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info,
|
||||||
|
&err))
|
||||||
goto queue_error;
|
goto queue_error;
|
||||||
}
|
}
|
||||||
gst_buffer_unmap (inbuf, &minfo);
|
gst_buffer_unmap (inbuf, &minfo);
|
||||||
|
@ -1101,8 +1156,7 @@ invalid_buffer_index:
|
||||||
}
|
}
|
||||||
dequeue_error:
|
dequeue_error:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
("Failed to dequeue input buffer"));
|
|
||||||
if (minfo.data)
|
if (minfo.data)
|
||||||
gst_buffer_unmap (inbuf, &minfo);
|
gst_buffer_unmap (inbuf, &minfo);
|
||||||
if (inbuf)
|
if (inbuf)
|
||||||
|
@ -1111,8 +1165,7 @@ dequeue_error:
|
||||||
}
|
}
|
||||||
queue_error:
|
queue_error:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
("Failed to queue input buffer"));
|
|
||||||
if (minfo.data)
|
if (minfo.data)
|
||||||
gst_buffer_unmap (inbuf, &minfo);
|
gst_buffer_unmap (inbuf, &minfo);
|
||||||
if (inbuf)
|
if (inbuf)
|
||||||
|
@ -1135,6 +1188,7 @@ gst_amc_audio_dec_drain (GstAmcAudioDec * self)
|
||||||
{
|
{
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
gint idx;
|
gint idx;
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (self, "Draining codec");
|
GST_DEBUG_OBJECT (self, "Draining codec");
|
||||||
if (!self->started) {
|
if (!self->started) {
|
||||||
|
@ -1156,7 +1210,7 @@ gst_amc_audio_dec_drain (GstAmcAudioDec * self)
|
||||||
* class drop the EOS event. We will send it later when
|
* class drop the EOS event. We will send it later when
|
||||||
* the EOS buffer arrives on the output port.
|
* the EOS buffer arrives on the output port.
|
||||||
* Wait at most 0.5s here. */
|
* Wait at most 0.5s here. */
|
||||||
idx = gst_amc_codec_dequeue_input_buffer (self->codec, 500000);
|
idx = gst_amc_codec_dequeue_input_buffer (self->codec, 500000, &err);
|
||||||
GST_AUDIO_DECODER_STREAM_LOCK (self);
|
GST_AUDIO_DECODER_STREAM_LOCK (self);
|
||||||
|
|
||||||
if (idx >= 0 && idx < self->n_input_buffers) {
|
if (idx >= 0 && idx < self->n_input_buffers) {
|
||||||
|
@ -1172,13 +1226,14 @@ gst_amc_audio_dec_drain (GstAmcAudioDec * self)
|
||||||
gst_util_uint64_scale (self->last_upstream_ts, 1, GST_USECOND);
|
gst_util_uint64_scale (self->last_upstream_ts, 1, GST_USECOND);
|
||||||
buffer_info.flags |= BUFFER_FLAG_END_OF_STREAM;
|
buffer_info.flags |= BUFFER_FLAG_END_OF_STREAM;
|
||||||
|
|
||||||
if (gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info)) {
|
if (gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info, &err)) {
|
||||||
GST_DEBUG_OBJECT (self, "Waiting until codec is drained");
|
GST_DEBUG_OBJECT (self, "Waiting until codec is drained");
|
||||||
g_cond_wait (&self->drain_cond, &self->drain_lock);
|
g_cond_wait (&self->drain_cond, &self->drain_lock);
|
||||||
GST_DEBUG_OBJECT (self, "Drained codec");
|
GST_DEBUG_OBJECT (self, "Drained codec");
|
||||||
ret = GST_FLOW_OK;
|
ret = GST_FLOW_OK;
|
||||||
} else {
|
} else {
|
||||||
GST_ERROR_OBJECT (self, "Failed to queue input buffer");
|
GST_ERROR_OBJECT (self, "Failed to queue input buffer");
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
ret = GST_FLOW_ERROR;
|
ret = GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1190,6 +1245,8 @@ gst_amc_audio_dec_drain (GstAmcAudioDec * self)
|
||||||
ret = GST_FLOW_ERROR;
|
ret = GST_FLOW_ERROR;
|
||||||
} else {
|
} else {
|
||||||
GST_ERROR_OBJECT (self, "Failed to acquire buffer for EOS: %d", idx);
|
GST_ERROR_OBJECT (self, "Failed to acquire buffer for EOS: %d", idx);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
ret = GST_FLOW_ERROR;
|
ret = GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -249,12 +249,15 @@ gst_amc_video_dec_open (GstVideoDecoder * decoder)
|
||||||
{
|
{
|
||||||
GstAmcVideoDec *self = GST_AMC_VIDEO_DEC (decoder);
|
GstAmcVideoDec *self = GST_AMC_VIDEO_DEC (decoder);
|
||||||
GstAmcVideoDecClass *klass = GST_AMC_VIDEO_DEC_GET_CLASS (self);
|
GstAmcVideoDecClass *klass = GST_AMC_VIDEO_DEC_GET_CLASS (self);
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (self, "Opening decoder");
|
GST_DEBUG_OBJECT (self, "Opening decoder");
|
||||||
|
|
||||||
self->codec = gst_amc_codec_new (klass->codec_info->name);
|
self->codec = gst_amc_codec_new (klass->codec_info->name, &err);
|
||||||
if (!self->codec)
|
if (!self->codec) {
|
||||||
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
self->started = FALSE;
|
self->started = FALSE;
|
||||||
self->flushing = TRUE;
|
self->flushing = TRUE;
|
||||||
|
|
||||||
|
@ -271,7 +274,12 @@ gst_amc_video_dec_close (GstVideoDecoder * decoder)
|
||||||
GST_DEBUG_OBJECT (self, "Closing decoder");
|
GST_DEBUG_OBJECT (self, "Closing decoder");
|
||||||
|
|
||||||
if (self->codec) {
|
if (self->codec) {
|
||||||
gst_amc_codec_release (self->codec);
|
GError *err = NULL;
|
||||||
|
|
||||||
|
gst_amc_codec_release (self->codec, &err);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
|
|
||||||
gst_amc_codec_free (self->codec);
|
gst_amc_codec_free (self->codec);
|
||||||
}
|
}
|
||||||
self->codec = NULL;
|
self->codec = NULL;
|
||||||
|
@ -300,6 +308,7 @@ gst_amc_video_dec_change_state (GstElement * element, GstStateChange transition)
|
||||||
{
|
{
|
||||||
GstAmcVideoDec *self;
|
GstAmcVideoDec *self;
|
||||||
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
|
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_AMC_VIDEO_DEC (element),
|
g_return_val_if_fail (GST_IS_AMC_VIDEO_DEC (element),
|
||||||
GST_STATE_CHANGE_FAILURE);
|
GST_STATE_CHANGE_FAILURE);
|
||||||
|
@ -317,7 +326,9 @@ gst_amc_video_dec_change_state (GstElement * element, GstStateChange transition)
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||||
self->flushing = TRUE;
|
self->flushing = TRUE;
|
||||||
gst_amc_codec_flush (self->codec);
|
gst_amc_codec_flush (self->codec, &err);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
g_mutex_lock (&self->drain_lock);
|
g_mutex_lock (&self->drain_lock);
|
||||||
self->draining = FALSE;
|
self->draining = FALSE;
|
||||||
g_cond_broadcast (&self->drain_cond);
|
g_cond_broadcast (&self->drain_cond);
|
||||||
|
@ -450,25 +461,31 @@ gst_amc_video_dec_set_src_caps (GstAmcVideoDec * self, GstAmcFormat * format)
|
||||||
gint crop_top, crop_bottom;
|
gint crop_top, crop_bottom;
|
||||||
GstVideoFormat gst_format;
|
GstVideoFormat gst_format;
|
||||||
GstAmcVideoDecClass *klass = GST_AMC_VIDEO_DEC_GET_CLASS (self);
|
GstAmcVideoDecClass *klass = GST_AMC_VIDEO_DEC_GET_CLASS (self);
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
if (!gst_amc_format_get_int (format, "color-format", &color_format) ||
|
if (!gst_amc_format_get_int (format, "color-format", &color_format, &err) ||
|
||||||
!gst_amc_format_get_int (format, "width", &width) ||
|
!gst_amc_format_get_int (format, "width", &width, &err) ||
|
||||||
!gst_amc_format_get_int (format, "height", &height)) {
|
!gst_amc_format_get_int (format, "height", &height, &err)) {
|
||||||
GST_ERROR_OBJECT (self, "Failed to get output format metadata");
|
GST_ERROR_OBJECT (self, "Failed to get output format metadata: %s",
|
||||||
|
err->message);
|
||||||
|
g_clear_error (&err);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gst_amc_format_get_int (format, "stride", &stride) ||
|
if (!gst_amc_format_get_int (format, "stride", &stride, &err) ||
|
||||||
!gst_amc_format_get_int (format, "slice-height", &slice_height)) {
|
!gst_amc_format_get_int (format, "slice-height", &slice_height, &err)) {
|
||||||
GST_ERROR_OBJECT (self, "Failed to get stride and slice-height");
|
GST_ERROR_OBJECT (self, "Failed to get stride and slice-height: %s",
|
||||||
|
err->message);
|
||||||
|
g_clear_error (&err);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gst_amc_format_get_int (format, "crop-left", &crop_left) ||
|
if (!gst_amc_format_get_int (format, "crop-left", &crop_left, &err) ||
|
||||||
!gst_amc_format_get_int (format, "crop-right", &crop_right) ||
|
!gst_amc_format_get_int (format, "crop-right", &crop_right, &err) ||
|
||||||
!gst_amc_format_get_int (format, "crop-top", &crop_top) ||
|
!gst_amc_format_get_int (format, "crop-top", &crop_top, &err) ||
|
||||||
!gst_amc_format_get_int (format, "crop-bottom", &crop_bottom)) {
|
!gst_amc_format_get_int (format, "crop-bottom", &crop_bottom, &err)) {
|
||||||
GST_ERROR_OBJECT (self, "Failed to get crop rectangle");
|
GST_ERROR_OBJECT (self, "Failed to get crop rectangle: %s", err->message);
|
||||||
|
g_clear_error (&err);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -565,6 +582,7 @@ gst_amc_video_dec_loop (GstAmcVideoDec * self)
|
||||||
gboolean is_eos;
|
gboolean is_eos;
|
||||||
GstAmcBufferInfo buffer_info;
|
GstAmcBufferInfo buffer_info;
|
||||||
gint idx;
|
gint idx;
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
GST_VIDEO_DECODER_STREAM_LOCK (self);
|
GST_VIDEO_DECODER_STREAM_LOCK (self);
|
||||||
|
|
||||||
|
@ -576,13 +594,17 @@ retry:
|
||||||
GST_VIDEO_DECODER_STREAM_UNLOCK (self);
|
GST_VIDEO_DECODER_STREAM_UNLOCK (self);
|
||||||
/* Wait at most 100ms here, some codecs don't fail dequeueing if
|
/* Wait at most 100ms here, some codecs don't fail dequeueing if
|
||||||
* the codec is flushing, causing deadlocks during shutdown */
|
* the codec is flushing, causing deadlocks during shutdown */
|
||||||
idx = gst_amc_codec_dequeue_output_buffer (self->codec, &buffer_info, 100000);
|
idx =
|
||||||
|
gst_amc_codec_dequeue_output_buffer (self->codec, &buffer_info, 100000,
|
||||||
|
&err);
|
||||||
GST_VIDEO_DECODER_STREAM_LOCK (self);
|
GST_VIDEO_DECODER_STREAM_LOCK (self);
|
||||||
/*} */
|
/*} */
|
||||||
|
|
||||||
if (idx < 0) {
|
if (idx < 0) {
|
||||||
if (self->flushing || self->downstream_flow_ret == GST_FLOW_FLUSHING)
|
if (self->flushing || self->downstream_flow_ret == GST_FLOW_FLUSHING) {
|
||||||
|
g_clear_error (&err);
|
||||||
goto flushing;
|
goto flushing;
|
||||||
|
}
|
||||||
|
|
||||||
switch (idx) {
|
switch (idx) {
|
||||||
case INFO_OUTPUT_BUFFERS_CHANGED:{
|
case INFO_OUTPUT_BUFFERS_CHANGED:{
|
||||||
|
@ -592,7 +614,7 @@ retry:
|
||||||
self->n_output_buffers);
|
self->n_output_buffers);
|
||||||
self->output_buffers =
|
self->output_buffers =
|
||||||
gst_amc_codec_get_output_buffers (self->codec,
|
gst_amc_codec_get_output_buffers (self->codec,
|
||||||
&self->n_output_buffers);
|
&self->n_output_buffers, &err);
|
||||||
if (!self->output_buffers)
|
if (!self->output_buffers)
|
||||||
goto get_output_buffers_error;
|
goto get_output_buffers_error;
|
||||||
break;
|
break;
|
||||||
|
@ -603,11 +625,15 @@ retry:
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (self, "Output format has changed");
|
GST_DEBUG_OBJECT (self, "Output format has changed");
|
||||||
|
|
||||||
format = gst_amc_codec_get_output_format (self->codec);
|
format = gst_amc_codec_get_output_format (self->codec, &err);
|
||||||
if (!format)
|
if (!format)
|
||||||
goto format_error;
|
goto format_error;
|
||||||
|
|
||||||
format_string = gst_amc_format_to_string (format);
|
format_string = gst_amc_format_to_string (format, &err);
|
||||||
|
if (!format) {
|
||||||
|
gst_amc_format_free (format);
|
||||||
|
goto format_error;
|
||||||
|
}
|
||||||
GST_DEBUG_OBJECT (self, "Got new output format: %s", format_string);
|
GST_DEBUG_OBJECT (self, "Got new output format: %s", format_string);
|
||||||
g_free (format_string);
|
g_free (format_string);
|
||||||
|
|
||||||
|
@ -622,7 +648,7 @@ retry:
|
||||||
self->n_output_buffers);
|
self->n_output_buffers);
|
||||||
self->output_buffers =
|
self->output_buffers =
|
||||||
gst_amc_codec_get_output_buffers (self->codec,
|
gst_amc_codec_get_output_buffers (self->codec,
|
||||||
&self->n_output_buffers);
|
&self->n_output_buffers, &err);
|
||||||
if (!self->output_buffers)
|
if (!self->output_buffers)
|
||||||
goto get_output_buffers_error;
|
goto get_output_buffers_error;
|
||||||
|
|
||||||
|
@ -634,7 +660,7 @@ retry:
|
||||||
goto retry;
|
goto retry;
|
||||||
break;
|
break;
|
||||||
case G_MININT:
|
case G_MININT:
|
||||||
GST_ERROR_OBJECT (self, "Failure dequeueing input buffer");
|
GST_ERROR_OBJECT (self, "Failure dequeueing output buffer");
|
||||||
goto dequeue_error;
|
goto dequeue_error;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -678,9 +704,11 @@ retry:
|
||||||
|
|
||||||
if (!gst_amc_video_dec_fill_buffer (self, idx, &buffer_info, outbuf)) {
|
if (!gst_amc_video_dec_fill_buffer (self, idx, &buffer_info, outbuf)) {
|
||||||
gst_buffer_unref (outbuf);
|
gst_buffer_unref (outbuf);
|
||||||
if (!gst_amc_codec_release_output_buffer (self->codec, idx))
|
if (!gst_amc_codec_release_output_buffer (self->codec, idx, &err))
|
||||||
GST_ERROR_OBJECT (self, "Failed to release output buffer index %d",
|
GST_ERROR_OBJECT (self, "Failed to release output buffer index %d",
|
||||||
idx);
|
idx);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
goto invalid_buffer;
|
goto invalid_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -692,9 +720,11 @@ retry:
|
||||||
if ((flow_ret = gst_video_decoder_allocate_output_frame (GST_VIDEO_DECODER
|
if ((flow_ret = gst_video_decoder_allocate_output_frame (GST_VIDEO_DECODER
|
||||||
(self), frame)) != GST_FLOW_OK) {
|
(self), frame)) != GST_FLOW_OK) {
|
||||||
GST_ERROR_OBJECT (self, "Failed to allocate buffer");
|
GST_ERROR_OBJECT (self, "Failed to allocate buffer");
|
||||||
if (!gst_amc_codec_release_output_buffer (self->codec, idx))
|
if (!gst_amc_codec_release_output_buffer (self->codec, idx, &err))
|
||||||
GST_ERROR_OBJECT (self, "Failed to release output buffer index %d",
|
GST_ERROR_OBJECT (self, "Failed to release output buffer index %d",
|
||||||
idx);
|
idx);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
goto flow_error;
|
goto flow_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -702,9 +732,11 @@ retry:
|
||||||
frame->output_buffer)) {
|
frame->output_buffer)) {
|
||||||
gst_buffer_replace (&frame->output_buffer, NULL);
|
gst_buffer_replace (&frame->output_buffer, NULL);
|
||||||
gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame);
|
gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame);
|
||||||
if (!gst_amc_codec_release_output_buffer (self->codec, idx))
|
if (!gst_amc_codec_release_output_buffer (self->codec, idx, &err))
|
||||||
GST_ERROR_OBJECT (self, "Failed to release output buffer index %d",
|
GST_ERROR_OBJECT (self, "Failed to release output buffer index %d",
|
||||||
idx);
|
idx);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
goto invalid_buffer;
|
goto invalid_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -713,7 +745,7 @@ retry:
|
||||||
flow_ret = gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame);
|
flow_ret = gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gst_amc_codec_release_output_buffer (self->codec, idx))
|
if (!gst_amc_codec_release_output_buffer (self->codec, idx, &err))
|
||||||
goto failed_release;
|
goto failed_release;
|
||||||
|
|
||||||
if (is_eos || flow_ret == GST_FLOW_EOS) {
|
if (is_eos || flow_ret == GST_FLOW_EOS) {
|
||||||
|
@ -744,8 +776,7 @@ retry:
|
||||||
|
|
||||||
dequeue_error:
|
dequeue_error:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
("Failed to dequeue output buffer"));
|
|
||||||
gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), gst_event_new_eos ());
|
gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), gst_event_new_eos ());
|
||||||
gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self));
|
gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self));
|
||||||
self->downstream_flow_ret = GST_FLOW_ERROR;
|
self->downstream_flow_ret = GST_FLOW_ERROR;
|
||||||
|
@ -755,8 +786,7 @@ dequeue_error:
|
||||||
|
|
||||||
get_output_buffers_error:
|
get_output_buffers_error:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
("Failed to get output buffers"));
|
|
||||||
gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), gst_event_new_eos ());
|
gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), gst_event_new_eos ());
|
||||||
gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self));
|
gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self));
|
||||||
self->downstream_flow_ret = GST_FLOW_ERROR;
|
self->downstream_flow_ret = GST_FLOW_ERROR;
|
||||||
|
@ -766,6 +796,9 @@ get_output_buffers_error:
|
||||||
|
|
||||||
format_error:
|
format_error:
|
||||||
{
|
{
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
|
else
|
||||||
GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
|
GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
|
||||||
("Failed to handle format"));
|
("Failed to handle format"));
|
||||||
gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), gst_event_new_eos ());
|
gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), gst_event_new_eos ());
|
||||||
|
@ -776,8 +809,7 @@ format_error:
|
||||||
}
|
}
|
||||||
failed_release:
|
failed_release:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
("Failed to release output buffer index %d", idx));
|
|
||||||
gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), gst_event_new_eos ());
|
gst_pad_push_event (GST_VIDEO_DECODER_SRC_PAD (self), gst_event_new_eos ());
|
||||||
gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self));
|
gst_pad_pause_task (GST_VIDEO_DECODER_SRC_PAD (self));
|
||||||
self->downstream_flow_ret = GST_FLOW_ERROR;
|
self->downstream_flow_ret = GST_FLOW_ERROR;
|
||||||
|
@ -846,13 +878,18 @@ static gboolean
|
||||||
gst_amc_video_dec_stop (GstVideoDecoder * decoder)
|
gst_amc_video_dec_stop (GstVideoDecoder * decoder)
|
||||||
{
|
{
|
||||||
GstAmcVideoDec *self;
|
GstAmcVideoDec *self;
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
self = GST_AMC_VIDEO_DEC (decoder);
|
self = GST_AMC_VIDEO_DEC (decoder);
|
||||||
GST_DEBUG_OBJECT (self, "Stopping decoder");
|
GST_DEBUG_OBJECT (self, "Stopping decoder");
|
||||||
self->flushing = TRUE;
|
self->flushing = TRUE;
|
||||||
if (self->started) {
|
if (self->started) {
|
||||||
gst_amc_codec_flush (self->codec);
|
gst_amc_codec_flush (self->codec, &err);
|
||||||
gst_amc_codec_stop (self->codec);
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
|
gst_amc_codec_stop (self->codec, &err);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
self->started = FALSE;
|
self->started = FALSE;
|
||||||
if (self->input_buffers)
|
if (self->input_buffers)
|
||||||
gst_amc_codec_free_buffers (self->input_buffers, self->n_input_buffers);
|
gst_amc_codec_free_buffers (self->input_buffers, self->n_input_buffers);
|
||||||
|
@ -890,6 +927,7 @@ gst_amc_video_dec_set_format (GstVideoDecoder * decoder,
|
||||||
gchar *format_string;
|
gchar *format_string;
|
||||||
guint8 *codec_data = NULL;
|
guint8 *codec_data = NULL;
|
||||||
gsize codec_data_size = 0;
|
gsize codec_data_size = 0;
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
self = GST_AMC_VIDEO_DEC (decoder);
|
self = GST_AMC_VIDEO_DEC (decoder);
|
||||||
|
|
||||||
|
@ -967,39 +1005,51 @@ gst_amc_video_dec_set_format (GstVideoDecoder * decoder,
|
||||||
}
|
}
|
||||||
|
|
||||||
format =
|
format =
|
||||||
gst_amc_format_new_video (mime, state->info.width, state->info.height);
|
gst_amc_format_new_video (mime, state->info.width, state->info.height,
|
||||||
|
&err);
|
||||||
if (!format) {
|
if (!format) {
|
||||||
GST_ERROR_OBJECT (self, "Failed to create video format");
|
GST_ERROR_OBJECT (self, "Failed to create video format");
|
||||||
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: This buffer needs to be valid until the codec is stopped again */
|
/* FIXME: This buffer needs to be valid until the codec is stopped again */
|
||||||
if (self->codec_data)
|
if (self->codec_data) {
|
||||||
gst_amc_format_set_buffer (format, "csd-0", self->codec_data,
|
gst_amc_format_set_buffer (format, "csd-0", self->codec_data,
|
||||||
self->codec_data_size);
|
self->codec_data_size, &err);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
|
}
|
||||||
|
|
||||||
format_string = gst_amc_format_to_string (format);
|
format_string = gst_amc_format_to_string (format, &err);
|
||||||
GST_DEBUG_OBJECT (self, "Configuring codec with format: %s", format_string);
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
|
GST_DEBUG_OBJECT (self, "Configuring codec with format: %s",
|
||||||
|
GST_STR_NULL (format_string));
|
||||||
g_free (format_string);
|
g_free (format_string);
|
||||||
|
|
||||||
if (!gst_amc_codec_configure (self->codec, format, 0)) {
|
if (!gst_amc_codec_configure (self->codec, format, 0, &err)) {
|
||||||
GST_ERROR_OBJECT (self, "Failed to configure codec");
|
GST_ERROR_OBJECT (self, "Failed to configure codec");
|
||||||
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_amc_format_free (format);
|
gst_amc_format_free (format);
|
||||||
|
|
||||||
if (!gst_amc_codec_start (self->codec)) {
|
if (!gst_amc_codec_start (self->codec, &err)) {
|
||||||
GST_ERROR_OBJECT (self, "Failed to start codec");
|
GST_ERROR_OBJECT (self, "Failed to start codec");
|
||||||
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->input_buffers)
|
if (self->input_buffers)
|
||||||
gst_amc_codec_free_buffers (self->input_buffers, self->n_input_buffers);
|
gst_amc_codec_free_buffers (self->input_buffers, self->n_input_buffers);
|
||||||
self->input_buffers =
|
self->input_buffers =
|
||||||
gst_amc_codec_get_input_buffers (self->codec, &self->n_input_buffers);
|
gst_amc_codec_get_input_buffers (self->codec, &self->n_input_buffers,
|
||||||
|
&err);
|
||||||
if (!self->input_buffers) {
|
if (!self->input_buffers) {
|
||||||
GST_ERROR_OBJECT (self, "Failed to get input buffers");
|
GST_ERROR_OBJECT (self, "Failed to get input buffers");
|
||||||
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1020,6 +1070,7 @@ static gboolean
|
||||||
gst_amc_video_dec_flush (GstVideoDecoder * decoder)
|
gst_amc_video_dec_flush (GstVideoDecoder * decoder)
|
||||||
{
|
{
|
||||||
GstAmcVideoDec *self;
|
GstAmcVideoDec *self;
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
self = GST_AMC_VIDEO_DEC (decoder);
|
self = GST_AMC_VIDEO_DEC (decoder);
|
||||||
|
|
||||||
|
@ -1038,7 +1089,9 @@ gst_amc_video_dec_flush (GstVideoDecoder * decoder)
|
||||||
GST_PAD_STREAM_LOCK (GST_VIDEO_DECODER_SRC_PAD (self));
|
GST_PAD_STREAM_LOCK (GST_VIDEO_DECODER_SRC_PAD (self));
|
||||||
GST_PAD_STREAM_UNLOCK (GST_VIDEO_DECODER_SRC_PAD (self));
|
GST_PAD_STREAM_UNLOCK (GST_VIDEO_DECODER_SRC_PAD (self));
|
||||||
GST_VIDEO_DECODER_STREAM_LOCK (self);
|
GST_VIDEO_DECODER_STREAM_LOCK (self);
|
||||||
gst_amc_codec_flush (self->codec);
|
gst_amc_codec_flush (self->codec, &err);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
self->flushing = FALSE;
|
self->flushing = FALSE;
|
||||||
|
|
||||||
/* Start the srcpad loop again */
|
/* Start the srcpad loop again */
|
||||||
|
@ -1064,6 +1117,7 @@ gst_amc_video_dec_handle_frame (GstVideoDecoder * decoder,
|
||||||
guint offset = 0;
|
guint offset = 0;
|
||||||
GstClockTime timestamp, duration, timestamp_offset = 0;
|
GstClockTime timestamp, duration, timestamp_offset = 0;
|
||||||
GstMapInfo minfo;
|
GstMapInfo minfo;
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
memset (&minfo, 0, sizeof (minfo));
|
memset (&minfo, 0, sizeof (minfo));
|
||||||
|
|
||||||
|
@ -1101,12 +1155,15 @@ gst_amc_video_dec_handle_frame (GstVideoDecoder * decoder,
|
||||||
GST_VIDEO_DECODER_STREAM_UNLOCK (self);
|
GST_VIDEO_DECODER_STREAM_UNLOCK (self);
|
||||||
/* Wait at most 100ms here, some codecs don't fail dequeueing if
|
/* Wait at most 100ms here, some codecs don't fail dequeueing if
|
||||||
* the codec is flushing, causing deadlocks during shutdown */
|
* the codec is flushing, causing deadlocks during shutdown */
|
||||||
idx = gst_amc_codec_dequeue_input_buffer (self->codec, 100000);
|
idx = gst_amc_codec_dequeue_input_buffer (self->codec, 100000, &err);
|
||||||
GST_VIDEO_DECODER_STREAM_LOCK (self);
|
GST_VIDEO_DECODER_STREAM_LOCK (self);
|
||||||
|
|
||||||
if (idx < 0) {
|
if (idx < 0) {
|
||||||
if (self->flushing)
|
if (self->flushing) {
|
||||||
|
g_clear_error (&err);
|
||||||
goto flushing;
|
goto flushing;
|
||||||
|
}
|
||||||
|
|
||||||
switch (idx) {
|
switch (idx) {
|
||||||
case INFO_TRY_AGAIN_LATER:
|
case INFO_TRY_AGAIN_LATER:
|
||||||
GST_DEBUG_OBJECT (self, "Dequeueing input buffer timed out");
|
GST_DEBUG_OBJECT (self, "Dequeueing input buffer timed out");
|
||||||
|
@ -1131,7 +1188,9 @@ gst_amc_video_dec_handle_frame (GstVideoDecoder * decoder,
|
||||||
|
|
||||||
if (self->downstream_flow_ret != GST_FLOW_OK) {
|
if (self->downstream_flow_ret != GST_FLOW_OK) {
|
||||||
memset (&buffer_info, 0, sizeof (buffer_info));
|
memset (&buffer_info, 0, sizeof (buffer_info));
|
||||||
gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info);
|
gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info, &err);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
goto downstream_error;
|
goto downstream_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1175,7 +1234,8 @@ gst_amc_video_dec_handle_frame (GstVideoDecoder * decoder,
|
||||||
"Queueing buffer %d: size %d time %" G_GINT64_FORMAT " flags 0x%08x",
|
"Queueing buffer %d: size %d time %" G_GINT64_FORMAT " flags 0x%08x",
|
||||||
idx, buffer_info.size, buffer_info.presentation_time_us,
|
idx, buffer_info.size, buffer_info.presentation_time_us,
|
||||||
buffer_info.flags);
|
buffer_info.flags);
|
||||||
if (!gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info))
|
if (!gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info,
|
||||||
|
&err))
|
||||||
goto queue_error;
|
goto queue_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1204,8 +1264,7 @@ invalid_buffer_index:
|
||||||
}
|
}
|
||||||
dequeue_error:
|
dequeue_error:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
("Failed to dequeue input buffer"));
|
|
||||||
if (minfo.data)
|
if (minfo.data)
|
||||||
gst_buffer_unmap (frame->input_buffer, &minfo);
|
gst_buffer_unmap (frame->input_buffer, &minfo);
|
||||||
gst_video_codec_frame_unref (frame);
|
gst_video_codec_frame_unref (frame);
|
||||||
|
@ -1213,8 +1272,7 @@ dequeue_error:
|
||||||
}
|
}
|
||||||
queue_error:
|
queue_error:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
("Failed to queue input buffer"));
|
|
||||||
if (minfo.data)
|
if (minfo.data)
|
||||||
gst_buffer_unmap (frame->input_buffer, &minfo);
|
gst_buffer_unmap (frame->input_buffer, &minfo);
|
||||||
gst_video_codec_frame_unref (frame);
|
gst_video_codec_frame_unref (frame);
|
||||||
|
@ -1245,6 +1303,7 @@ gst_amc_video_dec_drain (GstAmcVideoDec * self, gboolean at_eos)
|
||||||
{
|
{
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
gint idx;
|
gint idx;
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (self, "Draining codec");
|
GST_DEBUG_OBJECT (self, "Draining codec");
|
||||||
if (!self->started) {
|
if (!self->started) {
|
||||||
|
@ -1268,7 +1327,7 @@ gst_amc_video_dec_drain (GstAmcVideoDec * self, gboolean at_eos)
|
||||||
* class drop the EOS event. We will send it later when
|
* class drop the EOS event. We will send it later when
|
||||||
* the EOS buffer arrives on the output port.
|
* the EOS buffer arrives on the output port.
|
||||||
* Wait at most 0.5s here. */
|
* Wait at most 0.5s here. */
|
||||||
idx = gst_amc_codec_dequeue_input_buffer (self->codec, 500000);
|
idx = gst_amc_codec_dequeue_input_buffer (self->codec, 500000, &err);
|
||||||
GST_VIDEO_DECODER_STREAM_LOCK (self);
|
GST_VIDEO_DECODER_STREAM_LOCK (self);
|
||||||
|
|
||||||
if (idx >= 0 && idx < self->n_input_buffers) {
|
if (idx >= 0 && idx < self->n_input_buffers) {
|
||||||
|
@ -1284,13 +1343,14 @@ gst_amc_video_dec_drain (GstAmcVideoDec * self, gboolean at_eos)
|
||||||
gst_util_uint64_scale (self->last_upstream_ts, 1, GST_USECOND);
|
gst_util_uint64_scale (self->last_upstream_ts, 1, GST_USECOND);
|
||||||
buffer_info.flags |= BUFFER_FLAG_END_OF_STREAM;
|
buffer_info.flags |= BUFFER_FLAG_END_OF_STREAM;
|
||||||
|
|
||||||
if (gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info)) {
|
if (gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info, &err)) {
|
||||||
GST_DEBUG_OBJECT (self, "Waiting until codec is drained");
|
GST_DEBUG_OBJECT (self, "Waiting until codec is drained");
|
||||||
g_cond_wait (&self->drain_cond, &self->drain_lock);
|
g_cond_wait (&self->drain_cond, &self->drain_lock);
|
||||||
GST_DEBUG_OBJECT (self, "Drained codec");
|
GST_DEBUG_OBJECT (self, "Drained codec");
|
||||||
ret = GST_FLOW_OK;
|
ret = GST_FLOW_OK;
|
||||||
} else {
|
} else {
|
||||||
GST_ERROR_OBJECT (self, "Failed to queue input buffer");
|
GST_ERROR_OBJECT (self, "Failed to queue input buffer");
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
ret = GST_FLOW_ERROR;
|
ret = GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1302,6 +1362,8 @@ gst_amc_video_dec_drain (GstAmcVideoDec * self, gboolean at_eos)
|
||||||
ret = GST_FLOW_ERROR;
|
ret = GST_FLOW_ERROR;
|
||||||
} else {
|
} else {
|
||||||
GST_ERROR_OBJECT (self, "Failed to acquire buffer for EOS: %d", idx);
|
GST_ERROR_OBJECT (self, "Failed to acquire buffer for EOS: %d", idx);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
ret = GST_FLOW_ERROR;
|
ret = GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -161,6 +161,7 @@ create_amc_format (GstAmcVideoEnc * encoder, GstVideoCodecState * input_state,
|
||||||
gint stride, slice_height;
|
gint stride, slice_height;
|
||||||
GstAmcFormat *format = NULL;
|
GstAmcFormat *format = NULL;
|
||||||
GstVideoInfo *info = &input_state->info;
|
GstVideoInfo *info = &input_state->info;
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
klass = GST_AMC_VIDEO_ENC_GET_CLASS (encoder);
|
klass = GST_AMC_VIDEO_ENC_GET_CLASS (encoder);
|
||||||
s = gst_caps_get_structure (src_caps, 0);
|
s = gst_caps_get_structure (src_caps, 0);
|
||||||
|
@ -213,10 +214,11 @@ create_amc_format (GstAmcVideoEnc * encoder, GstVideoCodecState * input_state,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
format = gst_amc_format_new_video (mime, info->width, info->height);
|
format = gst_amc_format_new_video (mime, info->width, info->height, &err);
|
||||||
if (!format) {
|
if (!format) {
|
||||||
GST_ERROR_OBJECT (encoder, "Failed to create a \"%s,%dx%d\" MediaFormat",
|
GST_ERROR_OBJECT (encoder, "Failed to create a \"%s,%dx%d\" MediaFormat",
|
||||||
mime, info->width, info->height);
|
mime, info->width, info->height);
|
||||||
|
GST_ELEMENT_ERROR_FROM_ERROR (encoder, err);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,12 +228,20 @@ create_amc_format (GstAmcVideoEnc * encoder, GstVideoCodecState * input_state,
|
||||||
if (color_format == -1)
|
if (color_format == -1)
|
||||||
goto video_format_failed_to_convert;
|
goto video_format_failed_to_convert;
|
||||||
|
|
||||||
gst_amc_format_set_int (format, "bitrate", encoder->bitrate);
|
gst_amc_format_set_int (format, "bitrate", encoder->bitrate, &err);
|
||||||
gst_amc_format_set_int (format, "color-format", color_format);
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (encoder, err);
|
||||||
|
gst_amc_format_set_int (format, "color-format", color_format, &err);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (encoder, err);
|
||||||
stride = GST_ROUND_UP_4 (info->width); /* safe (?) */
|
stride = GST_ROUND_UP_4 (info->width); /* safe (?) */
|
||||||
gst_amc_format_set_int (format, "stride", stride);
|
gst_amc_format_set_int (format, "stride", stride, &err);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (encoder, err);
|
||||||
slice_height = info->height;
|
slice_height = info->height;
|
||||||
gst_amc_format_set_int (format, "slice-height", slice_height);
|
gst_amc_format_set_int (format, "slice-height", slice_height, &err);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (encoder, err);
|
||||||
|
|
||||||
if (profile_string) {
|
if (profile_string) {
|
||||||
if (amc_profile.id == -1)
|
if (amc_profile.id == -1)
|
||||||
|
@ -250,11 +260,16 @@ create_amc_format (GstAmcVideoEnc * encoder, GstVideoCodecState * input_state,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (encoder->i_frame_int)
|
if (encoder->i_frame_int)
|
||||||
gst_amc_format_set_int (format, "i-frame-interval", encoder->i_frame_int);
|
gst_amc_format_set_int (format, "i-frame-interval", encoder->i_frame_int,
|
||||||
|
&err);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (encoder, err);
|
||||||
|
|
||||||
if (info->fps_d)
|
if (info->fps_d)
|
||||||
gst_amc_format_set_float (format, "frame-rate",
|
gst_amc_format_set_float (format, "frame-rate",
|
||||||
((gfloat) info->fps_n) / info->fps_d);
|
((gfloat) info->fps_n) / info->fps_d, &err);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (encoder, err);
|
||||||
|
|
||||||
encoder->format = info->finfo->format;
|
encoder->format = info->finfo->format;
|
||||||
if (!gst_amc_color_format_info_set (&encoder->color_format_info,
|
if (!gst_amc_color_format_info_set (&encoder->color_format_info,
|
||||||
|
@ -306,21 +321,24 @@ caps_from_amc_format (GstAmcFormat * amc_format)
|
||||||
gint amc_profile, amc_level;
|
gint amc_profile, amc_level;
|
||||||
gfloat frame_rate = 0.0;
|
gfloat frame_rate = 0.0;
|
||||||
gint fraction_n, fraction_d;
|
gint fraction_n, fraction_d;
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
if (!gst_amc_format_get_string (amc_format, "mime", &mime)) {
|
if (!gst_amc_format_get_string (amc_format, "mime", &mime, &err)) {
|
||||||
GST_ERROR ("Failed to get 'mime'");
|
GST_ERROR ("Failed to get 'mime': %s", err->message);
|
||||||
|
g_clear_error (&err);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gst_amc_format_get_int (amc_format, "width", &width) ||
|
if (!gst_amc_format_get_int (amc_format, "width", &width, &err) ||
|
||||||
!gst_amc_format_get_int (amc_format, "height", &height)) {
|
!gst_amc_format_get_int (amc_format, "height", &height, &err)) {
|
||||||
GST_ERROR ("Failed to get size");
|
GST_ERROR ("Failed to get size: %s", err->message);
|
||||||
|
g_clear_error (&err);
|
||||||
|
|
||||||
g_free (mime);
|
g_free (mime);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_amc_format_get_float (amc_format, "frame-rate", &frame_rate);
|
gst_amc_format_get_float (amc_format, "frame-rate", &frame_rate, NULL);
|
||||||
gst_util_double_to_fraction (frame_rate, &fraction_n, &fraction_d);
|
gst_util_double_to_fraction (frame_rate, &fraction_n, &fraction_d);
|
||||||
|
|
||||||
if (strcmp (mime, "video/mp4v-es") == 0) {
|
if (strcmp (mime, "video/mp4v-es") == 0) {
|
||||||
|
@ -331,7 +349,7 @@ caps_from_amc_format (GstAmcFormat * amc_format)
|
||||||
"systemstream", G_TYPE_BOOLEAN, FALSE,
|
"systemstream", G_TYPE_BOOLEAN, FALSE,
|
||||||
"parsed", G_TYPE_BOOLEAN, TRUE, NULL);
|
"parsed", G_TYPE_BOOLEAN, TRUE, NULL);
|
||||||
|
|
||||||
if (gst_amc_format_get_int (amc_format, "profile", &amc_profile)) {
|
if (gst_amc_format_get_int (amc_format, "profile", &amc_profile, NULL)) {
|
||||||
profile_string = gst_amc_mpeg4_profile_to_string (amc_profile);
|
profile_string = gst_amc_mpeg4_profile_to_string (amc_profile);
|
||||||
if (!profile_string)
|
if (!profile_string)
|
||||||
goto unsupported_profile;
|
goto unsupported_profile;
|
||||||
|
@ -340,7 +358,7 @@ caps_from_amc_format (GstAmcFormat * amc_format)
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gst_amc_format_get_int (amc_format, "level", &amc_level)) {
|
if (gst_amc_format_get_int (amc_format, "level", &amc_level, NULL)) {
|
||||||
level_string = gst_amc_mpeg4_level_to_string (amc_profile);
|
level_string = gst_amc_mpeg4_level_to_string (amc_profile);
|
||||||
if (!level_string)
|
if (!level_string)
|
||||||
goto unsupported_level;
|
goto unsupported_level;
|
||||||
|
@ -360,7 +378,7 @@ caps_from_amc_format (GstAmcFormat * amc_format)
|
||||||
"stream-format", G_TYPE_STRING, "byte-stream",
|
"stream-format", G_TYPE_STRING, "byte-stream",
|
||||||
"alignment", G_TYPE_STRING, "au", NULL);
|
"alignment", G_TYPE_STRING, "au", NULL);
|
||||||
|
|
||||||
if (gst_amc_format_get_int (amc_format, "profile", &amc_profile)) {
|
if (gst_amc_format_get_int (amc_format, "profile", &amc_profile, NULL)) {
|
||||||
profile_string = gst_amc_avc_profile_to_string (amc_profile, NULL);
|
profile_string = gst_amc_avc_profile_to_string (amc_profile, NULL);
|
||||||
if (!profile_string)
|
if (!profile_string)
|
||||||
goto unsupported_profile;
|
goto unsupported_profile;
|
||||||
|
@ -369,7 +387,7 @@ caps_from_amc_format (GstAmcFormat * amc_format)
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gst_amc_format_get_int (amc_format, "level", &amc_level)) {
|
if (gst_amc_format_get_int (amc_format, "level", &amc_level, NULL)) {
|
||||||
level_string = gst_amc_avc_level_to_string (amc_profile);
|
level_string = gst_amc_avc_level_to_string (amc_profile);
|
||||||
if (!level_string)
|
if (!level_string)
|
||||||
goto unsupported_level;
|
goto unsupported_level;
|
||||||
|
@ -553,12 +571,15 @@ gst_amc_video_enc_open (GstVideoEncoder * encoder)
|
||||||
{
|
{
|
||||||
GstAmcVideoEnc *self = GST_AMC_VIDEO_ENC (encoder);
|
GstAmcVideoEnc *self = GST_AMC_VIDEO_ENC (encoder);
|
||||||
GstAmcVideoEncClass *klass = GST_AMC_VIDEO_ENC_GET_CLASS (self);
|
GstAmcVideoEncClass *klass = GST_AMC_VIDEO_ENC_GET_CLASS (self);
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (self, "Opening encoder");
|
GST_DEBUG_OBJECT (self, "Opening encoder");
|
||||||
|
|
||||||
self->codec = gst_amc_codec_new (klass->codec_info->name);
|
self->codec = gst_amc_codec_new (klass->codec_info->name, &err);
|
||||||
if (!self->codec)
|
if (!self->codec) {
|
||||||
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
self->started = FALSE;
|
self->started = FALSE;
|
||||||
self->flushing = TRUE;
|
self->flushing = TRUE;
|
||||||
|
|
||||||
|
@ -574,8 +595,15 @@ gst_amc_video_enc_close (GstVideoEncoder * encoder)
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (self, "Closing encoder");
|
GST_DEBUG_OBJECT (self, "Closing encoder");
|
||||||
|
|
||||||
if (self->codec)
|
if (self->codec) {
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
|
gst_amc_codec_release (self->codec, &err);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
|
|
||||||
gst_amc_codec_free (self->codec);
|
gst_amc_codec_free (self->codec);
|
||||||
|
}
|
||||||
self->codec = NULL;
|
self->codec = NULL;
|
||||||
|
|
||||||
self->started = FALSE;
|
self->started = FALSE;
|
||||||
|
@ -602,6 +630,7 @@ gst_amc_video_enc_change_state (GstElement * element, GstStateChange transition)
|
||||||
{
|
{
|
||||||
GstAmcVideoEnc *self;
|
GstAmcVideoEnc *self;
|
||||||
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
|
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
g_return_val_if_fail (GST_IS_AMC_VIDEO_ENC (element),
|
g_return_val_if_fail (GST_IS_AMC_VIDEO_ENC (element),
|
||||||
GST_STATE_CHANGE_FAILURE);
|
GST_STATE_CHANGE_FAILURE);
|
||||||
|
@ -619,7 +648,9 @@ gst_amc_video_enc_change_state (GstElement * element, GstStateChange transition)
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
||||||
self->flushing = TRUE;
|
self->flushing = TRUE;
|
||||||
gst_amc_codec_flush (self->codec);
|
gst_amc_codec_flush (self->codec, &err);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
g_mutex_lock (&self->drain_lock);
|
g_mutex_lock (&self->drain_lock);
|
||||||
self->draining = FALSE;
|
self->draining = FALSE;
|
||||||
g_cond_broadcast (&self->drain_cond);
|
g_cond_broadcast (&self->drain_cond);
|
||||||
|
@ -889,6 +920,7 @@ gst_amc_video_enc_loop (GstAmcVideoEnc * self)
|
||||||
GstAmcBufferInfo buffer_info;
|
GstAmcBufferInfo buffer_info;
|
||||||
GstAmcBuffer *buf;
|
GstAmcBuffer *buf;
|
||||||
gint idx;
|
gint idx;
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
GST_VIDEO_ENCODER_STREAM_LOCK (self);
|
GST_VIDEO_ENCODER_STREAM_LOCK (self);
|
||||||
|
|
||||||
|
@ -897,13 +929,17 @@ retry:
|
||||||
GST_VIDEO_ENCODER_STREAM_UNLOCK (self);
|
GST_VIDEO_ENCODER_STREAM_UNLOCK (self);
|
||||||
/* Wait at most 100ms here, some codecs don't fail dequeueing if
|
/* Wait at most 100ms here, some codecs don't fail dequeueing if
|
||||||
* the codec is flushing, causing deadlocks during shutdown */
|
* the codec is flushing, causing deadlocks during shutdown */
|
||||||
idx = gst_amc_codec_dequeue_output_buffer (self->codec, &buffer_info, 100000);
|
idx =
|
||||||
|
gst_amc_codec_dequeue_output_buffer (self->codec, &buffer_info, 100000,
|
||||||
|
&err);
|
||||||
GST_VIDEO_ENCODER_STREAM_LOCK (self);
|
GST_VIDEO_ENCODER_STREAM_LOCK (self);
|
||||||
/*} */
|
/*} */
|
||||||
|
|
||||||
if (idx < 0 || self->amc_format) {
|
if (idx < 0 || self->amc_format) {
|
||||||
if (self->flushing || self->downstream_flow_ret == GST_FLOW_FLUSHING)
|
if (self->flushing || self->downstream_flow_ret == GST_FLOW_FLUSHING) {
|
||||||
|
g_clear_error (&err);
|
||||||
goto flushing;
|
goto flushing;
|
||||||
|
}
|
||||||
|
|
||||||
/* The comments from https://android.googlesource.com/platform/cts/+/android-4.3_r3.1/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
|
/* The comments from https://android.googlesource.com/platform/cts/+/android-4.3_r3.1/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
|
||||||
* line 539 says INFO_OUTPUT_FORMAT_CHANGED is not expected for an encoder
|
* line 539 says INFO_OUTPUT_FORMAT_CHANGED is not expected for an encoder
|
||||||
|
@ -915,7 +951,12 @@ retry:
|
||||||
GST_DEBUG_OBJECT (self, "Output format has changed");
|
GST_DEBUG_OBJECT (self, "Output format has changed");
|
||||||
|
|
||||||
format = (idx == INFO_OUTPUT_FORMAT_CHANGED) ?
|
format = (idx == INFO_OUTPUT_FORMAT_CHANGED) ?
|
||||||
gst_amc_codec_get_output_format (self->codec) : self->amc_format;
|
gst_amc_codec_get_output_format (self->codec,
|
||||||
|
&err) : self->amc_format;
|
||||||
|
if (err) {
|
||||||
|
format = self->amc_format;
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
|
}
|
||||||
|
|
||||||
if (self->amc_format) {
|
if (self->amc_format) {
|
||||||
if (format != self->amc_format)
|
if (format != self->amc_format)
|
||||||
|
@ -926,8 +967,11 @@ retry:
|
||||||
if (!format)
|
if (!format)
|
||||||
goto format_error;
|
goto format_error;
|
||||||
|
|
||||||
|
format_string = gst_amc_format_to_string (format, &err);
|
||||||
format_string = gst_amc_format_to_string (format);
|
if (err) {
|
||||||
|
gst_amc_format_free (format);
|
||||||
|
goto format_error;
|
||||||
|
}
|
||||||
GST_DEBUG_OBJECT (self, "Got new output format: %s", format_string);
|
GST_DEBUG_OBJECT (self, "Got new output format: %s", format_string);
|
||||||
g_free (format_string);
|
g_free (format_string);
|
||||||
|
|
||||||
|
@ -943,7 +987,7 @@ retry:
|
||||||
self->n_output_buffers);
|
self->n_output_buffers);
|
||||||
self->output_buffers =
|
self->output_buffers =
|
||||||
gst_amc_codec_get_output_buffers (self->codec,
|
gst_amc_codec_get_output_buffers (self->codec,
|
||||||
&self->n_output_buffers);
|
&self->n_output_buffers, &err);
|
||||||
if (!self->output_buffers)
|
if (!self->output_buffers)
|
||||||
goto get_output_buffers_error;
|
goto get_output_buffers_error;
|
||||||
|
|
||||||
|
@ -961,7 +1005,7 @@ retry:
|
||||||
self->n_output_buffers);
|
self->n_output_buffers);
|
||||||
self->output_buffers =
|
self->output_buffers =
|
||||||
gst_amc_codec_get_output_buffers (self->codec,
|
gst_amc_codec_get_output_buffers (self->codec,
|
||||||
&self->n_output_buffers);
|
&self->n_output_buffers, &err);
|
||||||
if (!self->output_buffers)
|
if (!self->output_buffers)
|
||||||
goto get_output_buffers_error;
|
goto get_output_buffers_error;
|
||||||
break;
|
break;
|
||||||
|
@ -998,8 +1042,10 @@ process_buffer:
|
||||||
GST_ERROR_OBJECT (self, "Invalid output buffer index %d of %d",
|
GST_ERROR_OBJECT (self, "Invalid output buffer index %d of %d",
|
||||||
idx, self->n_output_buffers);
|
idx, self->n_output_buffers);
|
||||||
|
|
||||||
if (!gst_amc_codec_release_output_buffer (self->codec, idx))
|
if (!gst_amc_codec_release_output_buffer (self->codec, idx, &err))
|
||||||
GST_ERROR_OBJECT (self, "Failed to release output buffer index %d", idx);
|
GST_ERROR_OBJECT (self, "Failed to release output buffer index %d", idx);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
goto invalid_buffer;
|
goto invalid_buffer;
|
||||||
}
|
}
|
||||||
buf = &self->output_buffers[idx];
|
buf = &self->output_buffers[idx];
|
||||||
|
@ -1007,7 +1053,7 @@ process_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);
|
||||||
|
|
||||||
if (!gst_amc_codec_release_output_buffer (self->codec, idx))
|
if (!gst_amc_codec_release_output_buffer (self->codec, idx, &err))
|
||||||
goto failed_release;
|
goto failed_release;
|
||||||
|
|
||||||
if (is_eos || flow_ret == GST_FLOW_EOS) {
|
if (is_eos || flow_ret == GST_FLOW_EOS) {
|
||||||
|
@ -1038,8 +1084,7 @@ process_buffer:
|
||||||
|
|
||||||
dequeue_error:
|
dequeue_error:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
("Failed to dequeue output buffer"));
|
|
||||||
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_ERROR;
|
self->downstream_flow_ret = GST_FLOW_ERROR;
|
||||||
|
@ -1049,8 +1094,7 @@ dequeue_error:
|
||||||
|
|
||||||
get_output_buffers_error:
|
get_output_buffers_error:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
("Failed to get output buffers"));
|
|
||||||
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_ERROR;
|
self->downstream_flow_ret = GST_FLOW_ERROR;
|
||||||
|
@ -1060,6 +1104,9 @@ get_output_buffers_error:
|
||||||
|
|
||||||
format_error:
|
format_error:
|
||||||
{
|
{
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
|
else
|
||||||
GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
|
GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
|
||||||
("Failed to handle format"));
|
("Failed to handle format"));
|
||||||
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 ());
|
||||||
|
@ -1070,8 +1117,7 @@ format_error:
|
||||||
}
|
}
|
||||||
failed_release:
|
failed_release:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
("Failed to release output buffer index %d", idx));
|
|
||||||
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_ERROR;
|
self->downstream_flow_ret = GST_FLOW_ERROR;
|
||||||
|
@ -1137,13 +1183,18 @@ static gboolean
|
||||||
gst_amc_video_enc_stop (GstVideoEncoder * encoder)
|
gst_amc_video_enc_stop (GstVideoEncoder * encoder)
|
||||||
{
|
{
|
||||||
GstAmcVideoEnc *self;
|
GstAmcVideoEnc *self;
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
self = GST_AMC_VIDEO_ENC (encoder);
|
self = GST_AMC_VIDEO_ENC (encoder);
|
||||||
GST_DEBUG_OBJECT (self, "Stopping encoder");
|
GST_DEBUG_OBJECT (self, "Stopping encoder");
|
||||||
self->flushing = TRUE;
|
self->flushing = TRUE;
|
||||||
if (self->started) {
|
if (self->started) {
|
||||||
gst_amc_codec_flush (self->codec);
|
gst_amc_codec_flush (self->codec, &err);
|
||||||
gst_amc_codec_stop (self->codec);
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
|
gst_amc_codec_stop (self->codec, &err);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
self->started = FALSE;
|
self->started = FALSE;
|
||||||
if (self->input_buffers)
|
if (self->input_buffers)
|
||||||
gst_amc_codec_free_buffers (self->input_buffers, self->n_input_buffers);
|
gst_amc_codec_free_buffers (self->input_buffers, self->n_input_buffers);
|
||||||
|
@ -1184,6 +1235,7 @@ gst_amc_video_enc_set_format (GstVideoEncoder * encoder,
|
||||||
gboolean needs_disable = FALSE;
|
gboolean needs_disable = FALSE;
|
||||||
gchar *format_string;
|
gchar *format_string;
|
||||||
gboolean r = FALSE;
|
gboolean r = FALSE;
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
self = GST_AMC_VIDEO_ENC (encoder);
|
self = GST_AMC_VIDEO_ENC (encoder);
|
||||||
|
|
||||||
|
@ -1248,26 +1300,33 @@ gst_amc_video_enc_set_format (GstVideoEncoder * encoder,
|
||||||
if (!format)
|
if (!format)
|
||||||
goto quit;
|
goto quit;
|
||||||
|
|
||||||
format_string = gst_amc_format_to_string (format);
|
format_string = gst_amc_format_to_string (format, &err);
|
||||||
GST_DEBUG_OBJECT (self, "Configuring codec with format: %s", format_string);
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
|
GST_DEBUG_OBJECT (self, "Configuring codec with format: %s",
|
||||||
|
GST_STR_NULL (format_string));
|
||||||
g_free (format_string);
|
g_free (format_string);
|
||||||
|
|
||||||
if (!gst_amc_codec_configure (self->codec, format, 1)) {
|
if (!gst_amc_codec_configure (self->codec, format, 1, &err)) {
|
||||||
GST_ERROR_OBJECT (self, "Failed to configure codec");
|
GST_ERROR_OBJECT (self, "Failed to configure codec");
|
||||||
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
goto quit;
|
goto quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gst_amc_codec_start (self->codec)) {
|
if (!gst_amc_codec_start (self->codec, &err)) {
|
||||||
GST_ERROR_OBJECT (self, "Failed to start codec");
|
GST_ERROR_OBJECT (self, "Failed to start codec");
|
||||||
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
goto quit;
|
goto quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->input_buffers)
|
if (self->input_buffers)
|
||||||
gst_amc_codec_free_buffers (self->input_buffers, self->n_input_buffers);
|
gst_amc_codec_free_buffers (self->input_buffers, self->n_input_buffers);
|
||||||
self->input_buffers =
|
self->input_buffers =
|
||||||
gst_amc_codec_get_input_buffers (self->codec, &self->n_input_buffers);
|
gst_amc_codec_get_input_buffers (self->codec, &self->n_input_buffers,
|
||||||
|
&err);
|
||||||
if (!self->input_buffers) {
|
if (!self->input_buffers) {
|
||||||
GST_ERROR_OBJECT (self, "Failed to get input buffers");
|
GST_ERROR_OBJECT (self, "Failed to get input buffers");
|
||||||
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
goto quit;
|
goto quit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1300,6 +1359,7 @@ static gboolean
|
||||||
gst_amc_video_enc_flush (GstVideoEncoder * encoder)
|
gst_amc_video_enc_flush (GstVideoEncoder * encoder)
|
||||||
{
|
{
|
||||||
GstAmcVideoEnc *self;
|
GstAmcVideoEnc *self;
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
self = GST_AMC_VIDEO_ENC (encoder);
|
self = GST_AMC_VIDEO_ENC (encoder);
|
||||||
|
|
||||||
|
@ -1311,7 +1371,9 @@ gst_amc_video_enc_flush (GstVideoEncoder * encoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
self->flushing = TRUE;
|
self->flushing = TRUE;
|
||||||
gst_amc_codec_flush (self->codec);
|
gst_amc_codec_flush (self->codec, &err);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
|
|
||||||
/* Wait until the srcpad loop is finished,
|
/* Wait until the srcpad loop is finished,
|
||||||
* unlock GST_VIDEO_ENCODER_STREAM_LOCK to prevent deadlocks
|
* unlock GST_VIDEO_ENCODER_STREAM_LOCK to prevent deadlocks
|
||||||
|
@ -1344,6 +1406,7 @@ gst_amc_video_enc_handle_frame (GstVideoEncoder * encoder,
|
||||||
GstAmcBufferInfo buffer_info;
|
GstAmcBufferInfo buffer_info;
|
||||||
GstClockTime timestamp, duration, timestamp_offset = 0;
|
GstClockTime timestamp, duration, timestamp_offset = 0;
|
||||||
BufferIdentification *id;
|
BufferIdentification *id;
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
self = GST_AMC_VIDEO_ENC (encoder);
|
self = GST_AMC_VIDEO_ENC (encoder);
|
||||||
|
|
||||||
|
@ -1377,12 +1440,15 @@ again:
|
||||||
GST_VIDEO_ENCODER_STREAM_UNLOCK (self);
|
GST_VIDEO_ENCODER_STREAM_UNLOCK (self);
|
||||||
/* Wait at most 100ms here, some codecs don't fail dequeueing if
|
/* Wait at most 100ms here, some codecs don't fail dequeueing if
|
||||||
* the codec is flushing, causing deadlocks during shutdown */
|
* the codec is flushing, causing deadlocks during shutdown */
|
||||||
idx = gst_amc_codec_dequeue_input_buffer (self->codec, 100000);
|
idx = gst_amc_codec_dequeue_input_buffer (self->codec, 100000, &err);
|
||||||
GST_VIDEO_ENCODER_STREAM_LOCK (self);
|
GST_VIDEO_ENCODER_STREAM_LOCK (self);
|
||||||
|
|
||||||
if (idx < 0) {
|
if (idx < 0) {
|
||||||
if (self->flushing)
|
if (self->flushing) {
|
||||||
|
g_clear_error (&err);
|
||||||
goto flushing;
|
goto flushing;
|
||||||
|
}
|
||||||
|
|
||||||
switch (idx) {
|
switch (idx) {
|
||||||
case INFO_TRY_AGAIN_LATER:
|
case INFO_TRY_AGAIN_LATER:
|
||||||
GST_DEBUG_OBJECT (self, "Dequeueing input buffer timed out");
|
GST_DEBUG_OBJECT (self, "Dequeueing input buffer timed out");
|
||||||
|
@ -1407,7 +1473,9 @@ again:
|
||||||
|
|
||||||
if (self->downstream_flow_ret != GST_FLOW_OK) {
|
if (self->downstream_flow_ret != GST_FLOW_OK) {
|
||||||
memset (&buffer_info, 0, sizeof (buffer_info));
|
memset (&buffer_info, 0, sizeof (buffer_info));
|
||||||
gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info);
|
gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info, &err);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
goto downstream_error;
|
goto downstream_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1424,7 +1492,9 @@ again:
|
||||||
if (!gst_amc_video_enc_fill_buffer (self, frame->input_buffer, buf,
|
if (!gst_amc_video_enc_fill_buffer (self, frame->input_buffer, buf,
|
||||||
&buffer_info)) {
|
&buffer_info)) {
|
||||||
memset (&buffer_info, 0, sizeof (buffer_info));
|
memset (&buffer_info, 0, sizeof (buffer_info));
|
||||||
gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info);
|
gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info, &err);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
goto buffer_fill_error;
|
goto buffer_fill_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1446,7 +1516,7 @@ again:
|
||||||
"Queueing buffer %d: size %d time %" G_GINT64_FORMAT " flags 0x%08x",
|
"Queueing buffer %d: size %d time %" G_GINT64_FORMAT " flags 0x%08x",
|
||||||
idx, buffer_info.size, buffer_info.presentation_time_us,
|
idx, buffer_info.size, buffer_info.presentation_time_us,
|
||||||
buffer_info.flags);
|
buffer_info.flags);
|
||||||
if (!gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info))
|
if (!gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info, &err))
|
||||||
goto queue_error;
|
goto queue_error;
|
||||||
|
|
||||||
gst_video_codec_frame_unref (frame);
|
gst_video_codec_frame_unref (frame);
|
||||||
|
@ -1478,15 +1548,13 @@ buffer_fill_error:
|
||||||
}
|
}
|
||||||
dequeue_error:
|
dequeue_error:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
("Failed to dequeue input buffer"));
|
|
||||||
gst_video_codec_frame_unref (frame);
|
gst_video_codec_frame_unref (frame);
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
queue_error:
|
queue_error:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL),
|
GST_ELEMENT_ERROR_FROM_ERROR (self, err);
|
||||||
("Failed to queue input buffer"));
|
|
||||||
gst_video_codec_frame_unref (frame);
|
gst_video_codec_frame_unref (frame);
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -1503,6 +1571,7 @@ gst_amc_video_enc_finish (GstVideoEncoder * encoder)
|
||||||
{
|
{
|
||||||
GstAmcVideoEnc *self;
|
GstAmcVideoEnc *self;
|
||||||
gint idx;
|
gint idx;
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
self = GST_AMC_VIDEO_ENC (encoder);
|
self = GST_AMC_VIDEO_ENC (encoder);
|
||||||
GST_DEBUG_OBJECT (self, "Sending EOS to the component");
|
GST_DEBUG_OBJECT (self, "Sending EOS to the component");
|
||||||
|
@ -1522,7 +1591,7 @@ gst_amc_video_enc_finish (GstVideoEncoder * encoder)
|
||||||
* class drop the EOS event. We will send it later when
|
* class drop the EOS event. We will send it later when
|
||||||
* the EOS buffer arrives on the output port.
|
* the EOS buffer arrives on the output port.
|
||||||
* Wait at most 0.5s here. */
|
* Wait at most 0.5s here. */
|
||||||
idx = gst_amc_codec_dequeue_input_buffer (self->codec, 500000);
|
idx = gst_amc_codec_dequeue_input_buffer (self->codec, 500000, &err);
|
||||||
GST_VIDEO_ENCODER_STREAM_LOCK (self);
|
GST_VIDEO_ENCODER_STREAM_LOCK (self);
|
||||||
|
|
||||||
if (idx >= 0 && idx < self->n_input_buffers) {
|
if (idx >= 0 && idx < self->n_input_buffers) {
|
||||||
|
@ -1534,15 +1603,19 @@ gst_amc_video_enc_finish (GstVideoEncoder * encoder)
|
||||||
gst_util_uint64_scale (self->last_upstream_ts, 1, GST_USECOND);
|
gst_util_uint64_scale (self->last_upstream_ts, 1, GST_USECOND);
|
||||||
buffer_info.flags |= BUFFER_FLAG_END_OF_STREAM;
|
buffer_info.flags |= BUFFER_FLAG_END_OF_STREAM;
|
||||||
|
|
||||||
if (gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info))
|
if (gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info, &err)) {
|
||||||
GST_DEBUG_OBJECT (self, "Sent EOS to the codec");
|
GST_DEBUG_OBJECT (self, "Sent EOS to the codec");
|
||||||
else
|
} else {
|
||||||
GST_ERROR_OBJECT (self, "Failed to send EOS to the codec");
|
GST_ERROR_OBJECT (self, "Failed to send EOS to the codec");
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
|
}
|
||||||
} else if (idx >= self->n_input_buffers) {
|
} else if (idx >= self->n_input_buffers) {
|
||||||
GST_ERROR_OBJECT (self, "Invalid input buffer index %d of %d",
|
GST_ERROR_OBJECT (self, "Invalid input buffer index %d of %d",
|
||||||
idx, self->n_input_buffers);
|
idx, self->n_input_buffers);
|
||||||
} else {
|
} else {
|
||||||
GST_ERROR_OBJECT (self, "Failed to dequeue input buffer for EOS: %d", idx);
|
GST_ERROR_OBJECT (self, "Failed to dequeue input buffer for EOS: %d", idx);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
return GST_VIDEO_ENCODER_FLOW_DROPPED;
|
return GST_VIDEO_ENCODER_FLOW_DROPPED;
|
||||||
|
@ -1553,6 +1626,7 @@ gst_amc_video_enc_drain (GstAmcVideoEnc * self)
|
||||||
{
|
{
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
gint idx;
|
gint idx;
|
||||||
|
GError *err = NULL;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (self, "Draining codec");
|
GST_DEBUG_OBJECT (self, "Draining codec");
|
||||||
if (!self->started) {
|
if (!self->started) {
|
||||||
|
@ -1574,7 +1648,7 @@ gst_amc_video_enc_drain (GstAmcVideoEnc * self)
|
||||||
* class drop the EOS event. We will send it later when
|
* class drop the EOS event. We will send it later when
|
||||||
* the EOS buffer arrives on the output port.
|
* the EOS buffer arrives on the output port.
|
||||||
* Wait at most 0.5s here. */
|
* Wait at most 0.5s here. */
|
||||||
idx = gst_amc_codec_dequeue_input_buffer (self->codec, 500000);
|
idx = gst_amc_codec_dequeue_input_buffer (self->codec, 500000, &err);
|
||||||
GST_VIDEO_ENCODER_STREAM_LOCK (self);
|
GST_VIDEO_ENCODER_STREAM_LOCK (self);
|
||||||
|
|
||||||
if (idx >= 0 && idx < self->n_input_buffers) {
|
if (idx >= 0 && idx < self->n_input_buffers) {
|
||||||
|
@ -1590,13 +1664,14 @@ gst_amc_video_enc_drain (GstAmcVideoEnc * self)
|
||||||
gst_util_uint64_scale (self->last_upstream_ts, 1, GST_USECOND);
|
gst_util_uint64_scale (self->last_upstream_ts, 1, GST_USECOND);
|
||||||
buffer_info.flags |= BUFFER_FLAG_END_OF_STREAM;
|
buffer_info.flags |= BUFFER_FLAG_END_OF_STREAM;
|
||||||
|
|
||||||
if (gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info)) {
|
if (gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info, &err)) {
|
||||||
GST_DEBUG_OBJECT (self, "Waiting until codec is drained");
|
GST_DEBUG_OBJECT (self, "Waiting until codec is drained");
|
||||||
g_cond_wait (&self->drain_cond, &self->drain_lock);
|
g_cond_wait (&self->drain_cond, &self->drain_lock);
|
||||||
GST_DEBUG_OBJECT (self, "Drained codec");
|
GST_DEBUG_OBJECT (self, "Drained codec");
|
||||||
ret = GST_FLOW_OK;
|
ret = GST_FLOW_OK;
|
||||||
} else {
|
} else {
|
||||||
GST_ERROR_OBJECT (self, "Failed to queue input buffer");
|
GST_ERROR_OBJECT (self, "Failed to queue input buffer");
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
ret = GST_FLOW_ERROR;
|
ret = GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1608,6 +1683,8 @@ gst_amc_video_enc_drain (GstAmcVideoEnc * self)
|
||||||
ret = GST_FLOW_ERROR;
|
ret = GST_FLOW_ERROR;
|
||||||
} else {
|
} else {
|
||||||
GST_ERROR_OBJECT (self, "Failed to acquire buffer for EOS: %d", idx);
|
GST_ERROR_OBJECT (self, "Failed to acquire buffer for EOS: %d", idx);
|
||||||
|
if (err)
|
||||||
|
GST_ELEMENT_WARNING_FROM_ERROR (self, err);
|
||||||
ret = GST_FLOW_ERROR;
|
ret = GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue