1 /*
2 * MMAL Video Decoder
3 * Copyright (c) 2015 rcombs
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 /**
23 * @file
24 * MMAL Video Decoder
25 */
26
27 #include <bcm_host.h>
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>
35
48
57
58 // MMAL_POOL_T destroys all of its MMAL_BUFFER_HEADER_Ts. If we want correct
59 // refcounting for AVFrames, we can free the MMAL_POOL_T only after all AVFrames
60 // have been unreferenced.
65
70
75
80
81 // Waiting input packets. Because the libavcodec API requires decoding and
82 // returning packets in lockstep, it can happen that queue_decoded_frames
83 // contains almost all surfaces - then the decoder input queue can quickly
84 // fill up and won't accept new input either. Without consuming input, the
85 // libavcodec API can't return new frames, and we have a logical deadlock.
86 // This is avoided by queuing such buffers here.
88 /* Packet used to hold received packets temporarily; not owned by us. */
90
100
101 // Assume decoder is guaranteed to produce output after at least this many
102 // packets (where each packet contains 1 frame).
103 #define MAX_DELAYED_FRAMES 16
104
107 };
108
110 {
113 mmal_pool_destroy(
ref->pool);
115 }
116 }
117
119 {
121
122 mmal_buffer_header_release(
ref->buffer);
124
126 }
127
128 // Setup frame with a new reference to buffer. The buffer must have been
129 // allocated from the given pool.
131 MMAL_BUFFER_HEADER_T *
buffer)
132 {
136
139
143 if (!
frame->buf[0]) {
146 }
147
149 mmal_buffer_header_acquire(
buffer);
150
152 frame->data[3] = (uint8_t *)
ref->buffer;
153 return 0;
154 }
155
157 {
160 MMAL_BUFFER_HEADER_T *
buffer;
161
162 mmal_port_disable(
decoder->input[0]);
163 mmal_port_disable(
decoder->output[0]);
164 mmal_port_disable(
decoder->control);
165
166 mmal_port_flush(
decoder->input[0]);
167 mmal_port_flush(
decoder->output[0]);
168 mmal_port_flush(
decoder->control);
169
170 while ((
buffer = mmal_queue_get(
ctx->queue_decoded_frames)))
171 mmal_buffer_header_release(
buffer);
172
173 while (
ctx->waiting_buffers) {
175
177
178 if (
buffer->
flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END)
180
183 }
184 ctx->waiting_buffers_tail =
NULL;
185
187
188 ctx->frames_output =
ctx->eos_received =
ctx->eos_sent =
ctx->packets_sent =
ctx->extradata_sent = 0;
189 }
190
192 {
194
197
198 mmal_component_destroy(
ctx->decoder);
200 mmal_queue_destroy(
ctx->queue_decoded_frames);
201 mmal_pool_destroy(
ctx->pool_in);
203
204 mmal_vc_deinit();
205
206 return 0;
207 }
208
210 {
213
217 if (
entry->flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END)
220 }
221 mmal_buffer_header_release(
buffer);
222 }
223
225 {
228
229 mmal_queue_put(
ctx->queue_decoded_frames,
buffer);
230 }
231
233 {
236
237 if (
buffer->cmd == MMAL_EVENT_ERROR) {
240 } else {
243 }
244
245 mmal_buffer_header_release(
buffer);
246 }
247
248 // Feed free output buffers to the decoder.
250 {
252 MMAL_BUFFER_HEADER_T *
buffer;
254
256 return AVERROR_UNKNOWN;
// format change code failed with OOM previously
257
258 while ((
buffer = mmal_queue_get(
ctx->pool_out->pool->queue))) {
259 if ((
status = mmal_port_send_buffer(
ctx->decoder->output[0],
buffer))) {
260 mmal_buffer_header_release(
buffer);
263 }
264 }
265
266 return 0;
267 }
268
270 {
272 case MMAL_COLOR_SPACE_BT470_2_BG:
273 case MMAL_COLOR_SPACE_BT470_2_M:
279 }
280 }
281
283 {
288 MMAL_ES_FORMAT_T *format_out =
decoder->output[0]->format;
289 MMAL_PARAMETER_VIDEO_INTERLACE_TYPE_T interlace_type;
290
295 }
297
298 if (!format_out)
300
301 if ((
status = mmal_port_parameter_set_uint32(
decoder->output[0], MMAL_PARAMETER_EXTRA_BUFFERS,
ctx->extra_buffers)))
303
304 if ((
status = mmal_port_parameter_set_boolean(
decoder->output[0], MMAL_PARAMETER_VIDEO_INTERPOLATE_TIMESTAMPS, 0)))
306
308 format_out->encoding = MMAL_ENCODING_OPAQUE;
309 } else {
310 format_out->encoding_variant = format_out->encoding = MMAL_ENCODING_I420;
311 }
312
315
316 interlace_type.hdr.id = MMAL_PARAMETER_VIDEO_INTERLACE_TYPE;
317 interlace_type.hdr.size = sizeof(MMAL_PARAMETER_VIDEO_INTERLACE_TYPE_T);
318 status = mmal_port_parameter_get(
decoder->output[0], &interlace_type.hdr);
319 if (
status != MMAL_SUCCESS) {
321 } else {
322 ctx->interlaced_frame = (interlace_type.eMode != MMAL_InterlaceProgressive);
323 ctx->top_field_first = (interlace_type.eMode == MMAL_InterlaceFieldsInterleavedUpperFirst);
324 }
325
327 format_out->es->video.crop.y + format_out->es->video.crop.height)) < 0)
329
330 if (format_out->es->video.par.num && format_out->es->video.par.den) {
333 }
334 if (format_out->es->video.frame_rate.num && format_out->es->video.frame_rate.den) {
335 avctx->
framerate.
num = format_out->es->video.frame_rate.num;
336 avctx->
framerate.
den = format_out->es->video.frame_rate.den;
337 }
338
340
341 decoder->output[0]->buffer_size =
343 decoder->output[0]->buffer_num =
344 FFMAX(
decoder->output[0]->buffer_num_min,
decoder->output[0]->buffer_num_recommended) +
ctx->extra_buffers;
345 ctx->pool_out->pool = mmal_pool_create(
decoder->output[0]->buffer_num,
346 decoder->output[0]->buffer_size);
347 if (!
ctx->pool_out->pool) {
350 }
351
352 return 0;
353
356 }
357
359 {
362 MMAL_ES_FORMAT_T *format_in;
365
367
368 bcm_host_init();
369
370 if (mmal_vc_init()) {
373 }
374
377
379
380 if ((
status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, &
ctx->decoder)))
382
384
385 format_in =
decoder->input[0]->format;
386 format_in->type = MMAL_ES_TYPE_VIDEO;
389 format_in->encoding = MMAL_ENCODING_MP2V;
390 break;
392 format_in->encoding = MMAL_ENCODING_MP4V;
393 break;
395 format_in->encoding = MMAL_ENCODING_WVC1;
396 break;
398 default:
399 format_in->encoding = MMAL_ENCODING_H264;
400 break;
401 }
404 format_in->es->video.crop.width = avctx->
width;
405 format_in->es->video.crop.height = avctx->
height;
406 format_in->es->video.frame_rate.num = 24000;
407 format_in->es->video.frame_rate.den = 1001;
410 format_in->flags = MMAL_ES_FORMAT_FLAG_FRAMED;
411
414
415 #if HAVE_MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS
416 if (mmal_port_parameter_set_uint32(
decoder->input[0], MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS,
417 -1 -
ctx->extra_decoder_buffers)) {
419 }
420 #endif
421
424
425 decoder->input[0]->buffer_num =
427 decoder->input[0]->buffer_size =
429 ctx->pool_in = mmal_pool_create(
decoder->input[0]->buffer_num, 0);
433 }
434
437
438 ctx->queue_decoded_frames = mmal_queue_create();
439 if (!
ctx->queue_decoded_frames)
441
442 decoder->input[0]->userdata = (
void*)avctx;
443 decoder->output[0]->userdata = (
void*)avctx;
444 decoder->control->userdata = (
void*)avctx;
445
452
455
456 return 0;
457
461 }
462
464 {
468
470
477
478 return;
479
482 }
483
484 // Split packets and add them to the waiting_buffers list. We don't queue them
485 // immediately, because it can happen that the decoder is temporarily blocked
486 // (due to us not reading/returning enough output buffers) and won't accept
487 // new input. (This wouldn't be an issue if MMAL input buffers always were
488 // complete frames - then the input buffer just would have to be big enough.)
489 // If is_extradata is set, send it as MMAL_BUFFER_HEADER_FLAG_CONFIG.
491 int is_extradata)
492 {
496 uint8_t *
data = (uint8_t *)
"";
497 uint8_t *start;
499
503 goto done;
507 if (!is_extradata)
509 } else {
511 goto done;
512 if (!
ctx->packets_sent) {
513 // Short-cut the flush logic to avoid upsetting MMAL.
515 ctx->eos_received = 1;
516 goto done;
517 }
518 }
519
521
522 do {
526 goto done;
527 }
528
531
532 if (is_extradata)
534
536 buffer->
flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_START;
537
540
543
545 buffer->
flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_END;
547 }
548
552 }
553
554 if (buf) {
559 goto done;
560 }
561 }
562
563 // Insert at end of the list
564 if (!
ctx->waiting_buffers)
566 if (
ctx->waiting_buffers_tail)
567 ctx->waiting_buffers_tail->next =
buffer;
570
571 done:
574 }
575
576 // Move prepared/split packets from waiting_buffers to the MMAL decoder.
578 {
580
581 while (
ctx->waiting_buffers) {
582 MMAL_BUFFER_HEADER_T *mbuffer;
585
586 mbuffer = mmal_queue_get(
ctx->pool_in->queue);
587 if (!mbuffer)
588 return 0;
589
591
592 mmal_buffer_header_reset(mbuffer);
593 mbuffer->cmd = 0;
595 mbuffer->dts =
buffer->dts;
598 mbuffer->length =
buffer->length;
599 mbuffer->user_data =
buffer;
600 mbuffer->alloc_size =
ctx->decoder->input[0]->buffer_size;
601
602 // Remove from start of the list
605 ctx->waiting_buffers_tail =
NULL;
606
607 if ((
status = mmal_port_send_buffer(
ctx->decoder->input[0], mbuffer))) {
608 mmal_buffer_header_release(mbuffer);
610 if (
buffer->
flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END)
613 }
614
618 }
619 }
620
621 return 0;
622 }
623
625 MMAL_BUFFER_HEADER_T *
buffer)
626 {
629
630 if (
ctx->interlaced_frame)
632 if (
ctx->top_field_first)
634
637 return AVERROR_UNKNOWN;
// format change code failed with OOM previously
638
640 goto done;
641
643 goto done;
644 } else {
648 int linesize[4];
649
651 goto done;
652
658 }
659
665
668
669 done:
671 }
672
673 // Fetch a decoded buffer and place it into the frame parameter.
675 {
680
681 if (
ctx->eos_received)
682 goto done;
683
684 while (1) {
685 // To ensure decoding in lockstep with a constant delay between fed packets
686 // and output frames, we always wait until an output buffer is available.
687 // Except during start we don't know after how many input packets the decoder
688 // is going to return the first buffer, and we can't distinguish decoder
689 // being busy from decoder waiting for input. So just poll at the start and
690 // keep feeding new data to the buffer.
691 // We are pretty sure the decoder will produce output if we sent more input
692 // frames than what a H.264 decoder could logically delay. This avoids too
693 // excessive buffering.
694 // We also wait if we sent eos, but didn't receive it yet (think of decoding
695 // stream with a very low number of frames).
697 (
ctx->packets_sent &&
ctx->eos_sent)) {
698 // MMAL will ignore broken input packets, which means the frame we
699 // expect here may never arrive. Dealing with this correctly is
700 // complicated, so here's a hack to avoid that it freezes forever
701 // in this unlikely situation.
702 buffer = mmal_queue_timedwait(
ctx->queue_decoded_frames, 100);
706 goto done;
707 }
708 } else {
709 buffer = mmal_queue_get(
ctx->queue_decoded_frames);
711 goto done;
712 }
713
714 ctx->eos_received |= !!(
buffer->
flags & MMAL_BUFFER_HEADER_FLAG_EOS);
715 if (
ctx->eos_received)
716 goto done;
717
718 if (
buffer->cmd == MMAL_EVENT_FORMAT_CHANGED) {
720 MMAL_EVENT_FORMAT_CHANGED_T *ev = mmal_event_format_changed_get(
buffer);
721 MMAL_BUFFER_HEADER_T *stale_buffer;
722
724
726 goto done;
727
728 while ((stale_buffer = mmal_queue_get(
ctx->queue_decoded_frames)))
729 mmal_buffer_header_release(stale_buffer);
730
731 mmal_format_copy(
decoder->output[0]->format, ev->format);
732
734 goto done;
735
737 goto done;
738
740 goto done;
741
743 goto done;
744
745 mmal_buffer_header_release(
buffer);
746 continue;
750 goto done;
751 }
else if (
buffer->length == 0) {
752 // Unused output buffer that got drained after format change.
753 mmal_buffer_header_release(
buffer);
754 continue;
755 }
756
757 ctx->frames_output++;
758
760 goto done;
761
762 *got_frame = 1;
763 break;
764 }
765
766 done:
768 mmal_buffer_header_release(
buffer);
772 }
773
775 {
779 int got_frame = 0;
780
784 ctx->extradata_sent = 1;
787 }
788
795
798
801
804
805 // ffmmal_read_frame() can block for a while. Since the decoder is
806 // asynchronous, it's a good idea to fill the ports again.
807
810
813
814 if (!got_frame &&
ret == 0)
816 else
818 }
819
823 };
824
827 {
"extra_decoder_buffers",
"extra MMAL internal buffered frames", offsetof(
MMALDecodeContext, extra_decoder_buffers),
AV_OPT_TYPE_INT, {.i64 = 10}, 0, 256, 0},
829 };
830
836 };
837
838 #define FFMMAL_DEC(NAME, ID) \
839 const FFCodec ff_##NAME##_mmal_decoder = { \
840 .p.name = #NAME "_mmal", \
841 CODEC_LONG_NAME(#NAME " (mmal)"), \
842 .p.type = AVMEDIA_TYPE_VIDEO, \
843 .p.id = ID, \
844 .priv_data_size = sizeof(MMALDecodeContext), \
845 .init = ffmmal_init_decoder, \
846 .close = ffmmal_close_decoder, \
847 FF_CODEC_RECEIVE_FRAME_CB(ffmmal_receive_frame), \
848 .flush = ffmmal_flush, \
849 .p.priv_class = &ffmmal_dec_class, \
850 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE, \
851 .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE, \
852 .hw_configs = mmal_hw_configs, \
853 .p.wrapper_name = "mmal", \
854 };
855