vlc | branch: master | Julian Scheel <[email protected]> | Wed Jun 3 09:50:34 2015 +0200| [f9dde8b80995ad9de1e0945242614afbdeb68e40] | committer: Jean-Baptiste Kempf
mmal/codec: Do not use local buffer pool in opaque mode When running in opaque mode the codec must be used together with the mmal vout. In this case each picture contains a mmal_buffer_header within the picture_sys_t. That buffer header can be used instead of locally allocated headers with the advantage of reducing complexity and avoiding possibly error-prone mangling of buffer headers. Furthermore it is a prerequisite to enable zero_copy mode on the ports. Signed-off-by: Julian Scheel <[email protected]> Signed-off-by: Jean-Baptiste Kempf <[email protected]> > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=f9dde8b80995ad9de1e0945242614afbdeb68e40 --- modules/hw/mmal/codec.c | 122 ++++++++++++++++++++++++++++++----------------- 1 file changed, 77 insertions(+), 45 deletions(-) diff --git a/modules/hw/mmal/codec.c b/modules/hw/mmal/codec.c index 7f20a17..e89b81d 100644 --- a/modules/hw/mmal/codec.c +++ b/modules/hw/mmal/codec.c @@ -68,7 +68,7 @@ struct decoder_sys_t { MMAL_PORT_T *input; MMAL_POOL_T *input_pool; MMAL_PORT_T *output; - MMAL_POOL_T *output_pool; + MMAL_POOL_T *output_pool; /* only used for non-opaque mode */ MMAL_ES_FORMAT_T *output_format; MMAL_QUEUE_T *decoded_pictures; vlc_mutex_t mutex; @@ -78,6 +78,7 @@ struct decoder_sys_t { /* statistics */ int output_in_transit; + atomic_bool started; }; /* Utilities */ @@ -262,10 +263,12 @@ static void CloseDecoder(decoder_t *dec) picture_t *pic = (picture_t *)buffer->user_data; picture_Release(pic); - buffer->user_data = NULL; - buffer->alloc_size = 0; - buffer->data = NULL; - mmal_buffer_header_release(buffer); + if (sys->output_pool) { + buffer->user_data = NULL; + buffer->alloc_size = 0; + buffer->data = NULL; + mmal_buffer_header_release(buffer); + } } if (sys->decoded_pictures) @@ -290,7 +293,7 @@ static int change_output_format(decoder_t *dec) int pool_size; int ret = 0; - if (sys->output_pool) { + if (atomic_load(&sys->started)) { mmal_format_full_copy(sys->output->format, sys->output_format); status = mmal_port_format_commit(sys->output); if (status != MMAL_SUCCESS) { @@ -340,9 +343,13 @@ port_reset: goto out; } - if (!sys->output_pool) { - sys->output_pool = mmal_pool_create(pool_size, 0); - msg_Dbg(dec, "Created output pool with %d pictures", sys->output_pool->headers_num); + if (!atomic_load(&sys->started)) { + if (!sys->opaque) { + sys->output_pool = mmal_port_pool_create(sys->output, pool_size, 0); + msg_Dbg(dec, "Created output pool with %d pictures", sys->output_pool->headers_num); + } + + atomic_store(&sys->started, true); /* we need one picture from vout for each buffer header on the output * port */ @@ -407,10 +414,14 @@ static int send_output_buffer(decoder_t *dec) if (!sys->output->is_enabled) return VLC_EGENERIC; - buffer = mmal_queue_get(sys->output_pool->queue); - if (!buffer) { - msg_Warn(dec, "Failed to get new buffer"); - return VLC_EGENERIC; + /* If local output pool is allocated, use it - this is only the case for + * non-opaque modes */ + if (sys->output_pool) { + buffer = mmal_queue_get(sys->output_pool->queue); + if (!buffer) { + msg_Warn(dec, "Failed to get new buffer"); + return VLC_EGENERIC; + } } picture = decoder_NewPicture(dec); @@ -424,27 +435,29 @@ static int send_output_buffer(decoder_t *dec) for (int i = 0; i < picture->i_planes; i++) buffer_size += picture->p[i].i_lines * picture->p[i].i_pitch; - mmal_buffer_header_reset(buffer); - buffer->user_data = picture; - buffer->cmd = 0; - buffer->alloc_size = sys->output->buffer_size; - - if (sys->opaque) { - if (p_sys->buffer == NULL) { - msg_Err(dec, "Retrieved picture without opaque handle"); - ret = VLC_EGENERIC; - goto err; - } - buffer->data = p_sys->buffer->data; - } else { + if (sys->output_pool) { + mmal_buffer_header_reset(buffer); + buffer->user_data = picture; + buffer->alloc_size = sys->output->buffer_size; if (buffer_size < sys->output->buffer_size) { msg_Err(dec, "Retrieved picture with too small data block (%d < %d)", buffer_size, sys->output->buffer_size); ret = VLC_EGENERIC; goto err; } - buffer->data = picture->p[0].p_pixels; + + if (!sys->opaque) + buffer->data = picture->p[0].p_pixels; + } else { + buffer = p_sys->buffer; + if (!buffer) { + msg_Warn(dec, "Picture has no buffer attached"); + picture_Release(picture); + return VLC_EGENERIC; + } + buffer->data = p_sys->buffer->data; } + buffer->cmd = 0; status = mmal_port_send_buffer(sys->output, buffer); if (status != MMAL_SUCCESS) { @@ -460,27 +473,42 @@ static int send_output_buffer(decoder_t *dec) err: if (picture) picture_Release(picture); - buffer->data = NULL; - mmal_buffer_header_release(buffer); + if (sys->output_pool && buffer) { + buffer->data = NULL; + mmal_buffer_header_release(buffer); + } return ret; } static void fill_output_port(decoder_t *dec) { decoder_sys_t *sys = dec->p_sys; - /* allow at least 2 buffers in transit */ - unsigned max_buffers_in_transit = __MAX(sys->output_pool->headers_num, - MIN_NUM_BUFFERS_IN_TRANSIT); - unsigned buffers_available = mmal_queue_length(sys->output_pool->queue); - unsigned buffers_to_send = max_buffers_in_transit - atomic_load(&sys->output_in_transit); - unsigned i; + + unsigned max_buffers_in_transit = 0; + int buffers_available = 0; + int buffers_to_send = 0; + int i; + + if (sys->output_pool) { + max_buffers_in_transit = __MAX(sys->output_pool->headers_num, + MIN_NUM_BUFFERS_IN_TRANSIT); + buffers_available = mmal_queue_length(sys->output_pool->queue); + } else { + max_buffers_in_transit = __MAX(sys->output->buffer_num, MIN_NUM_BUFFERS_IN_TRANSIT); + buffers_available = NUM_DECODER_BUFFER_HEADERS - atomic_load(&sys->output_in_transit) - + mmal_queue_length(sys->decoded_pictures); + } + buffers_to_send = max_buffers_in_transit - atomic_load(&sys->output_in_transit); if (buffers_to_send > buffers_available) buffers_to_send = buffers_available; #ifndef NDEBUG - msg_Dbg(dec, "Send %d buffers to output port (available: %d, in_transit: %d, buffer_num: %d)", - buffers_to_send, buffers_available, atomic_load(&sys->output_in_transit), + msg_Dbg(dec, "Send %d buffers to output port (available: %d, " + "in_transit: %d, decoded: %d, buffer_num: %d)", + buffers_to_send, buffers_available, + atomic_load(&sys->output_in_transit), + mmal_queue_length(sys->decoded_pictures), sys->output->buffer_num); #endif for (i = 0; i < buffers_to_send; ++i) @@ -522,7 +550,7 @@ static picture_t *decode(decoder_t *dec, block_t **pblock) /* * Send output buffers */ - if (sys->output_pool) { + if (atomic_load(&sys->started)) { buffer = mmal_queue_get(sys->decoded_pictures); if (buffer) { ret = (picture_t *)buffer->user_data; @@ -530,9 +558,11 @@ static picture_t *decode(decoder_t *dec, block_t **pblock) ret->b_progressive = sys->b_progressive; ret->b_top_field_first = sys->b_top_field_first; - buffer->data = NULL; - mmal_buffer_header_reset(buffer); - mmal_buffer_header_release(buffer); + if (sys->output_pool) { + buffer->data = NULL; + mmal_buffer_header_reset(buffer); + mmal_buffer_header_release(buffer); + } } fill_output_port(dec); @@ -648,10 +678,12 @@ static void output_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) } else { picture = (picture_t *)buffer->user_data; picture_Release(picture); - buffer->user_data = NULL; - buffer->alloc_size = 0; - buffer->data = NULL; - mmal_buffer_header_release(buffer); + if (sys->output_pool) { + buffer->user_data = NULL; + buffer->alloc_size = 0; + buffer->data = NULL; + mmal_buffer_header_release(buffer); + } } atomic_fetch_sub(&sys->output_in_transit, 1); } else if (buffer->cmd == MMAL_EVENT_FORMAT_CHANGED) { _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
