28 #include <interface/mmal/mmal.h>
29 #include <interface/mmal/mmal_parameters_video.h>
30 #include <interface/mmal/util/mmal_util.h>
31 #include <interface/mmal/util/mmal_util_params.h>
32 #include <interface/mmal/util/mmal_default_components.h>
33 #include <interface/mmal/vc/mmal_vc_api.h>
34 #include <stdatomic.h>
98 #define MAX_DELAYED_FRAMES 16
104 mmal_pool_destroy(
ref->pool);
113 mmal_buffer_header_release(
ref->buffer);
122 MMAL_BUFFER_HEADER_T *
buffer)
134 if (!
frame->buf[0]) {
140 mmal_buffer_header_acquire(
buffer);
151 MMAL_BUFFER_HEADER_T *
buffer;
153 mmal_port_disable(
decoder->input[0]);
154 mmal_port_disable(
decoder->output[0]);
155 mmal_port_disable(
decoder->control);
157 mmal_port_flush(
decoder->input[0]);
158 mmal_port_flush(
decoder->output[0]);
159 mmal_port_flush(
decoder->control);
161 while ((
buffer = mmal_queue_get(
ctx->queue_decoded_frames)))
162 mmal_buffer_header_release(
buffer);
164 while (
ctx->waiting_buffers) {
169 if (
buffer->
flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END)
175 ctx->waiting_buffers_tail =
NULL;
179 ctx->frames_output =
ctx->eos_received =
ctx->eos_sent =
ctx->packets_sent =
ctx->extradata_sent = 0;
189 mmal_component_destroy(
ctx->decoder);
191 mmal_queue_destroy(
ctx->queue_decoded_frames);
192 mmal_pool_destroy(
ctx->pool_in);
208 if (entry->
flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END)
212 mmal_buffer_header_release(
buffer);
220 mmal_queue_put(
ctx->queue_decoded_frames,
buffer);
228 if (
buffer->cmd == MMAL_EVENT_ERROR) {
236 mmal_buffer_header_release(
buffer);
243 MMAL_BUFFER_HEADER_T *
buffer;
249 while ((
buffer = mmal_queue_get(
ctx->pool_out->pool->queue))) {
250 if ((
status = mmal_port_send_buffer(
ctx->decoder->output[0],
buffer))) {
251 mmal_buffer_header_release(
buffer);
263 case MMAL_COLOR_SPACE_BT470_2_BG:
264 case MMAL_COLOR_SPACE_BT470_2_M:
279 MMAL_ES_FORMAT_T *format_out =
decoder->output[0]->format;
280 MMAL_PARAMETER_VIDEO_INTERLACE_TYPE_T interlace_type;
292 if ((
status = mmal_port_parameter_set_uint32(
decoder->output[0], MMAL_PARAMETER_EXTRA_BUFFERS,
ctx->extra_buffers)))
295 if ((
status = mmal_port_parameter_set_boolean(
decoder->output[0], MMAL_PARAMETER_VIDEO_INTERPOLATE_TIMESTAMPS, 0)))
299 format_out->encoding = MMAL_ENCODING_OPAQUE;
301 format_out->encoding_variant = format_out->encoding = MMAL_ENCODING_I420;
307 interlace_type.hdr.id = MMAL_PARAMETER_VIDEO_INTERLACE_TYPE;
308 interlace_type.hdr.size =
sizeof(MMAL_PARAMETER_VIDEO_INTERLACE_TYPE_T);
309 status = mmal_port_parameter_get(
decoder->output[0], &interlace_type.hdr);
310 if (
status != MMAL_SUCCESS) {
313 ctx->interlaced_frame = (interlace_type.eMode != MMAL_InterlaceProgressive);
314 ctx->top_field_first = (interlace_type.eMode == MMAL_InterlaceFieldsInterleavedUpperFirst);
318 format_out->es->video.crop.y + format_out->es->video.crop.height)) < 0)
321 if (format_out->es->video.par.num && format_out->es->video.par.den) {
325 if (format_out->es->video.frame_rate.num && format_out->es->video.frame_rate.den) {
326 avctx->
framerate.
num = format_out->es->video.frame_rate.num;
327 avctx->
framerate.
den = format_out->es->video.frame_rate.den;
332 decoder->output[0]->buffer_size =
334 decoder->output[0]->buffer_num =
335 FFMAX(
decoder->output[0]->buffer_num_min,
decoder->output[0]->buffer_num_recommended) +
ctx->extra_buffers;
336 ctx->pool_out->pool = mmal_pool_create(
decoder->output[0]->buffer_num,
337 decoder->output[0]->buffer_size);
338 if (!
ctx->pool_out->pool) {
353 MMAL_ES_FORMAT_T *format_in;
359 if (mmal_vc_init()) {
369 if ((
status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, &
ctx->decoder)))
374 format_in =
decoder->input[0]->format;
375 format_in->type = MMAL_ES_TYPE_VIDEO;
378 format_in->encoding = MMAL_ENCODING_MP2V;
381 format_in->encoding = MMAL_ENCODING_MP4V;
384 format_in->encoding = MMAL_ENCODING_WVC1;
388 format_in->encoding = MMAL_ENCODING_H264;
393 format_in->es->video.crop.width = avctx->
width;
394 format_in->es->video.crop.height = avctx->
height;
395 format_in->es->video.frame_rate.num = 24000;
396 format_in->es->video.frame_rate.den = 1001;
399 format_in->flags = MMAL_ES_FORMAT_FLAG_FRAMED;
404 #if HAVE_MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS
405 if (mmal_port_parameter_set_uint32(
decoder->input[0], MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS,
406 -1 -
ctx->extra_decoder_buffers)) {
414 decoder->input[0]->buffer_num =
416 decoder->input[0]->buffer_size =
418 ctx->pool_in = mmal_pool_create(
decoder->input[0]->buffer_num, 0);
427 ctx->queue_decoded_frames = mmal_queue_create();
428 if (!
ctx->queue_decoded_frames)
431 decoder->input[0]->userdata = (
void*)avctx;
432 decoder->output[0]->userdata = (
void*)avctx;
433 decoder->control->userdata = (
void*)avctx;
511 if (!
ctx->packets_sent) {
514 ctx->eos_received = 1;
535 buffer->
flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_START;
544 buffer->
flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_END;
563 if (!
ctx->waiting_buffers)
565 if (
ctx->waiting_buffers_tail)
566 ctx->waiting_buffers_tail->next =
buffer;
580 while (
ctx->waiting_buffers) {
581 MMAL_BUFFER_HEADER_T *mbuffer;
585 mbuffer = mmal_queue_get(
ctx->pool_in->queue);
591 mmal_buffer_header_reset(mbuffer);
594 mbuffer->dts =
buffer->dts;
597 mbuffer->length =
buffer->length;
598 mbuffer->user_data =
buffer;
599 mbuffer->alloc_size =
ctx->decoder->input[0]->buffer_size;
604 ctx->waiting_buffers_tail =
NULL;
606 if ((
status = mmal_port_send_buffer(
ctx->decoder->input[0], mbuffer))) {
607 mmal_buffer_header_release(mbuffer);
609 if (
buffer->
flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END)
624 MMAL_BUFFER_HEADER_T *
buffer)
629 frame->interlaced_frame =
ctx->interlaced_frame;
630 frame->top_field_first =
ctx->top_field_first;
677 if (
ctx->eos_received)
693 (
ctx->packets_sent &&
ctx->eos_sent)) {
698 buffer = mmal_queue_timedwait(
ctx->queue_decoded_frames, 100);
705 buffer = mmal_queue_get(
ctx->queue_decoded_frames);
710 ctx->eos_received |= !!(
buffer->
flags & MMAL_BUFFER_HEADER_FLAG_EOS);
711 if (
ctx->eos_received)
714 if (
buffer->cmd == MMAL_EVENT_FORMAT_CHANGED) {
716 MMAL_EVENT_FORMAT_CHANGED_T *ev = mmal_event_format_changed_get(
buffer);
717 MMAL_BUFFER_HEADER_T *stale_buffer;
724 while ((stale_buffer = mmal_queue_get(
ctx->queue_decoded_frames)))
725 mmal_buffer_header_release(stale_buffer);
727 mmal_format_copy(
decoder->output[0]->format, ev->format);
741 mmal_buffer_header_release(
buffer);
747 }
else if (
buffer->length == 0) {
749 mmal_buffer_header_release(
buffer);
753 ctx->frames_output++;
764 mmal_buffer_header_release(
buffer);
782 ctx->extradata_sent = 1;
818 {
"extra_decoder_buffers",
"extra MMAL internal buffered frames", offsetof(
MMALDecodeContext, extra_decoder_buffers),
AV_OPT_TYPE_INT, {.i64 = 10}, 0, 256, 0},
822 #define FFMMAL_DEC_CLASS(NAME) \
823 static const AVClass ffmmal_##NAME##_dec_class = { \
824 .class_name = "mmal_" #NAME "_dec", \
825 .item_name = av_default_item_name, \
827 .version = LIBAVUTIL_VERSION_INT, \
830 #define FFMMAL_DEC(NAME, ID) \
831 FFMMAL_DEC_CLASS(NAME) \
832 AVCodec ff_##NAME##_mmal_decoder = { \
833 .name = #NAME "_mmal", \
834 .long_name = NULL_IF_CONFIG_SMALL(#NAME " (mmal)"), \
835 .type = AVMEDIA_TYPE_VIDEO, \
837 .priv_data_size = sizeof(MMALDecodeContext), \
838 .init = ffmmal_init_decoder, \
839 .close = ffmmal_close_decoder, \
840 .decode = ffmmal_decode, \
841 .flush = ffmmal_flush, \
842 .priv_class = &ffmmal_##NAME##_dec_class, \
843 .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE, \
844 .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS, \
845 .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_MMAL, \
846 AV_PIX_FMT_YUV420P, \
848 .hw_configs = mmal_hw_configs, \
849 .wrapper_name = "mmal", \