diff options
author | Sebastian Dröge <sebastian@centricular.com> | 2015-05-27 23:34:14 +0200 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2015-05-31 21:27:27 +0200 |
commit | a6fb4822477dffb8bcf0e4183a212e559e3bd5b6 (patch) | |
tree | a63c12e4a9341fdcf91e4a9d3cb03b93ab01d606 /sys/androidmedia/gstamcvideoenc.c | |
parent | 360f0be2a80ca11e1b3b0c087367c48cb18c4c3e (diff) | |
download | gstreamer-plugins-bad-a6fb4822477dffb8bcf0e4183a212e559e3bd5b6.tar.gz |
androidmedia: Conditionally use get_{input,output}_buffer() Android 21 APIs
Also properly set limit/position on byte buffer, some codecs prefer to have
correct values there.
Diffstat (limited to 'sys/androidmedia/gstamcvideoenc.c')
-rw-r--r-- | sys/androidmedia/gstamcvideoenc.c | 165 |
1 files changed, 66 insertions, 99 deletions
diff --git a/sys/androidmedia/gstamcvideoenc.c b/sys/androidmedia/gstamcvideoenc.c index 4384c7624..8a6dd44b8 100644 --- a/sys/androidmedia/gstamcvideoenc.c +++ b/sys/androidmedia/gstamcvideoenc.c @@ -10,6 +10,8 @@ * Copyright (C) 2013, Lemote Ltd. * Author: Chen Jie <chenj@lemote.com> * + * Copyright (C) 2015, Sebastian Dröge <sebastian@centricular.com> + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation @@ -982,15 +984,6 @@ retry: gst_amc_format_free (format); - if (self->output_buffers) - gst_amc_codec_free_buffers (self->output_buffers, - self->n_output_buffers); - self->output_buffers = - gst_amc_codec_get_output_buffers (self->codec, - &self->n_output_buffers, &err); - if (!self->output_buffers) - goto get_output_buffers_error; - if (idx >= 0) goto process_buffer; @@ -998,18 +991,10 @@ retry: } switch (idx) { - case INFO_OUTPUT_BUFFERS_CHANGED:{ - GST_DEBUG_OBJECT (self, "Output buffers have changed"); - if (self->output_buffers) - gst_amc_codec_free_buffers (self->output_buffers, - self->n_output_buffers); - self->output_buffers = - gst_amc_codec_get_output_buffers (self->codec, - &self->n_output_buffers, &err); - if (!self->output_buffers) - goto get_output_buffers_error; + case INFO_OUTPUT_BUFFERS_CHANGED: + /* Handled internally */ + g_assert_not_reached (); break; - } case INFO_TRY_AGAIN_LATER: GST_DEBUG_OBJECT (self, "Dequeueing output buffer timed out"); goto retry; @@ -1038,17 +1023,16 @@ process_buffer: is_eos = ! !(buffer_info.flags & BUFFER_FLAG_END_OF_STREAM); - if (idx >= self->n_output_buffers) { - GST_ERROR_OBJECT (self, "Invalid output buffer index %d of %d", - idx, self->n_output_buffers); - - goto invalid_buffer; - } - buf = &self->output_buffers[idx]; + buf = gst_amc_codec_get_output_buffer (self->codec, idx, &err); + if (!buf) + goto failed_to_get_output_buffer; flow_ret = gst_amc_video_enc_handle_output_frame (self, buf, &buffer_info, frame); + gst_amc_buffer_free (buf); + buf = NULL; + if (!gst_amc_codec_release_output_buffer (self->codec, idx, &err)) { if (self->flushing) { g_clear_error (&err); @@ -1097,20 +1081,6 @@ dequeue_error: return; } -get_output_buffers_error: - { - GST_ELEMENT_ERROR_FROM_ERROR (self, err); - gst_pad_push_event (GST_VIDEO_ENCODER_SRC_PAD (self), gst_event_new_eos ()); - gst_pad_pause_task (GST_VIDEO_ENCODER_SRC_PAD (self)); - self->downstream_flow_ret = GST_FLOW_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; - } - format_error: { if (err) @@ -1173,10 +1143,9 @@ flow_error: return; } -invalid_buffer: +failed_to_get_output_buffer: { - GST_ELEMENT_ERROR (self, LIBRARY, SETTINGS, (NULL), - ("Invalid sized input buffer")); + GST_ELEMENT_ERROR_FROM_ERROR (self, err); gst_pad_push_event (GST_VIDEO_ENCODER_SRC_PAD (self), gst_event_new_eos ()); gst_pad_pause_task (GST_VIDEO_ENCODER_SRC_PAD (self)); self->downstream_flow_ret = GST_FLOW_NOT_NEGOTIATED; @@ -1221,12 +1190,6 @@ gst_amc_video_enc_stop (GstVideoEncoder * encoder) if (err) GST_ELEMENT_WARNING_FROM_ERROR (self, err); self->started = FALSE; - if (self->input_buffers) - gst_amc_codec_free_buffers (self->input_buffers, self->n_input_buffers); - self->input_buffers = NULL; - if (self->output_buffers) - gst_amc_codec_free_buffers (self->output_buffers, self->n_output_buffers); - self->output_buffers = NULL; } gst_pad_stop_task (GST_VIDEO_ENCODER_SRC_PAD (encoder)); @@ -1341,17 +1304,6 @@ gst_amc_video_enc_set_format (GstVideoEncoder * encoder, goto quit; } - if (self->input_buffers) - gst_amc_codec_free_buffers (self->input_buffers, self->n_input_buffers); - self->input_buffers = - gst_amc_codec_get_input_buffers (self->codec, &self->n_input_buffers, - &err); - if (!self->input_buffers) { - GST_ERROR_OBJECT (self, "Failed to get input buffers"); - GST_ELEMENT_ERROR_FROM_ERROR (self, err); - goto quit; - } - self->amc_format = format; format = NULL; @@ -1481,9 +1433,6 @@ again: goto again; } - if (idx >= self->n_input_buffers) - goto invalid_buffer_index; - if (self->flushing) { memset (&buffer_info, 0, sizeof (buffer_info)); gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info, NULL); @@ -1503,11 +1452,15 @@ again: /* Copy the buffer content in chunks of size as requested * by the port */ - buf = &self->input_buffers[idx]; + buf = gst_amc_codec_get_input_buffer (self->codec, idx, &err); + if (!buf) + goto failed_to_get_input_buffer; memset (&buffer_info, 0, sizeof (buffer_info)); buffer_info.offset = 0; buffer_info.size = MIN (self->color_format_info.frame_size, buf->size); + gst_amc_buffer_set_position_and_limit (buf, NULL, buffer_info.offset, + buffer_info.size); if (!gst_amc_video_enc_fill_buffer (self, frame->input_buffer, buf, &buffer_info)) { @@ -1516,9 +1469,14 @@ again: if (err && !self->flushing) GST_ELEMENT_WARNING_FROM_ERROR (self, err); g_clear_error (&err); + gst_amc_buffer_free (buf); + buf = NULL; goto buffer_fill_error; } + gst_amc_buffer_free (buf); + buf = NULL; + if (timestamp != GST_CLOCK_TIME_NONE) { buffer_info.presentation_time_us = gst_util_uint64_scale (timestamp + timestamp_offset, 1, GST_USECOND); @@ -1559,10 +1517,9 @@ downstream_error: gst_video_codec_frame_unref (frame); return self->downstream_flow_ret; } -invalid_buffer_index: +failed_to_get_input_buffer: { - GST_ELEMENT_ERROR (self, LIBRARY, FAILED, (NULL), - ("Invalid input buffer index %d of %d", idx, self->n_input_buffers)); + GST_ELEMENT_ERROR_FROM_ERROR (self, err); gst_video_codec_frame_unref (frame); return GST_FLOW_ERROR; } @@ -1634,43 +1591,53 @@ gst_amc_video_enc_drain (GstAmcVideoEnc * self) idx = gst_amc_codec_dequeue_input_buffer (self->codec, 500000, &err); GST_VIDEO_ENCODER_STREAM_LOCK (self); - if (idx >= 0 && idx < self->n_input_buffers) { + if (idx >= 0) { + GstAmcBuffer *buf; GstAmcBufferInfo buffer_info; - GST_VIDEO_ENCODER_STREAM_UNLOCK (self); - g_mutex_lock (&self->drain_lock); - self->draining = TRUE; + buf = gst_amc_codec_get_input_buffer (self->codec, idx, &err); + if (buf) { + GST_VIDEO_ENCODER_STREAM_UNLOCK (self); + g_mutex_lock (&self->drain_lock); + self->draining = TRUE; + + memset (&buffer_info, 0, sizeof (buffer_info)); + buffer_info.size = 0; + buffer_info.presentation_time_us = + gst_util_uint64_scale (self->last_upstream_ts, 1, GST_USECOND); + buffer_info.flags |= BUFFER_FLAG_END_OF_STREAM; + + gst_amc_buffer_set_position_and_limit (buf, NULL, 0, 0); + gst_amc_buffer_free (buf); + buf = NULL; + + if (gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info, + &err)) { + GST_DEBUG_OBJECT (self, "Waiting until codec is drained"); + g_cond_wait (&self->drain_cond, &self->drain_lock); + GST_DEBUG_OBJECT (self, "Drained codec"); + ret = GST_FLOW_OK; + } else { + GST_ERROR_OBJECT (self, "Failed to queue input buffer"); + if (self->flushing) { + g_clear_error (&err); + ret = GST_FLOW_FLUSHING; + } else { + GST_ELEMENT_WARNING_FROM_ERROR (self, err); + ret = GST_FLOW_ERROR; + } + } - memset (&buffer_info, 0, sizeof (buffer_info)); - buffer_info.size = 0; - buffer_info.presentation_time_us = - gst_util_uint64_scale (self->last_upstream_ts, 1, GST_USECOND); - buffer_info.flags |= BUFFER_FLAG_END_OF_STREAM; - - if (gst_amc_codec_queue_input_buffer (self->codec, idx, &buffer_info, &err)) { - GST_DEBUG_OBJECT (self, "Waiting until codec is drained"); - g_cond_wait (&self->drain_cond, &self->drain_lock); - GST_DEBUG_OBJECT (self, "Drained codec"); - ret = GST_FLOW_OK; + self->drained = TRUE; + self->draining = FALSE; + g_mutex_unlock (&self->drain_lock); + GST_VIDEO_ENCODER_STREAM_LOCK (self); } else { - GST_ERROR_OBJECT (self, "Failed to queue input buffer"); - if (self->flushing) { - g_clear_error (&err); - ret = GST_FLOW_FLUSHING; - } else { + GST_ERROR_OBJECT (self, "Failed to get buffer for EOS: %d", idx); + if (err) GST_ELEMENT_WARNING_FROM_ERROR (self, err); - ret = GST_FLOW_ERROR; - } + ret = GST_FLOW_ERROR; } - - self->drained = TRUE; - self->draining = FALSE; - g_mutex_unlock (&self->drain_lock); - GST_VIDEO_ENCODER_STREAM_LOCK (self); - } else if (idx >= self->n_input_buffers) { - GST_ERROR_OBJECT (self, "Invalid input buffer index %d of %d", - idx, self->n_input_buffers); - ret = GST_FLOW_ERROR; } else { GST_ERROR_OBJECT (self, "Failed to acquire buffer for EOS: %d", idx); if (err) |