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
47
56
57 // MMAL_POOL_T destroys all of its MMAL_BUFFER_HEADER_Ts. If we want correct
58 // refcounting for AVFrames, we can free the MMAL_POOL_T only after all AVFrames
59 // have been unreferenced.
64
69
74
79
80 // Waiting input packets. Because the libavcodec API requires decoding and
81 // returning packets in lockstep, it can happen that queue_decoded_frames
82 // contains almost all surfaces - then the decoder input queue can quickly
83 // fill up and won't accept new input either. Without consuming input, the
84 // libavcodec API can't return new frames, and we have a logical deadlock.
85 // This is avoided by queuing such buffers here.
87 /* Packet used to hold received packets temporarily; not owned by us. */
89
99
100 // Assume decoder is guaranteed to produce output after at least this many
101 // packets (where each packet contains 1 frame).
102 #define MAX_DELAYED_FRAMES 16
103
105 {
108 mmal_pool_destroy(
ref->pool);
110 }
111 }
112
114 {
116
117 mmal_buffer_header_release(
ref->buffer);
119
121 }
122
123 // Setup frame with a new reference to buffer. The buffer must have been
124 // allocated from the given pool.
126 MMAL_BUFFER_HEADER_T *
buffer)
127 {
131
134
138 if (!
frame->buf[0]) {
141 }
142
144 mmal_buffer_header_acquire(
buffer);
145
147 frame->data[3] = (uint8_t *)
ref->buffer;
148 return 0;
149 }
150
152 {
155 MMAL_BUFFER_HEADER_T *
buffer;
156
157 mmal_port_disable(
decoder->input[0]);
158 mmal_port_disable(
decoder->output[0]);
159 mmal_port_disable(
decoder->control);
160
161 mmal_port_flush(
decoder->input[0]);
162 mmal_port_flush(
decoder->output[0]);
163 mmal_port_flush(
decoder->control);
164
165 while ((
buffer = mmal_queue_get(
ctx->queue_decoded_frames)))
166 mmal_buffer_header_release(
buffer);
167
168 while (
ctx->waiting_buffers) {
170
172
173 if (
buffer->
flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END)
175
178 }
179 ctx->waiting_buffers_tail =
NULL;
180
182
183 ctx->frames_output =
ctx->eos_received =
ctx->eos_sent =
ctx->packets_sent =
ctx->extradata_sent = 0;
184 }
185
187 {
189
192
193 mmal_component_destroy(
ctx->decoder);
195 mmal_queue_destroy(
ctx->queue_decoded_frames);
196 mmal_pool_destroy(
ctx->pool_in);
198
199 mmal_vc_deinit();
200
201 return 0;
202 }
203
205 {
208
212 if (entry->
flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END)
215 }
216 mmal_buffer_header_release(
buffer);
217 }
218
220 {
223
224 mmal_queue_put(
ctx->queue_decoded_frames,
buffer);
225 }
226
228 {
231
232 if (
buffer->cmd == MMAL_EVENT_ERROR) {
235 } else {
238 }
239
240 mmal_buffer_header_release(
buffer);
241 }
242
243 // Feed free output buffers to the decoder.
245 {
247 MMAL_BUFFER_HEADER_T *
buffer;
249
251 return AVERROR_UNKNOWN;
// format change code failed with OOM previously
252
253 while ((
buffer = mmal_queue_get(
ctx->pool_out->pool->queue))) {
254 if ((
status = mmal_port_send_buffer(
ctx->decoder->output[0],
buffer))) {
255 mmal_buffer_header_release(
buffer);
258 }
259 }
260
261 return 0;
262 }
263
265 {
267 case MMAL_COLOR_SPACE_BT470_2_BG:
268 case MMAL_COLOR_SPACE_BT470_2_M:
274 }
275 }
276
278 {
283 MMAL_ES_FORMAT_T *format_out =
decoder->output[0]->format;
284 MMAL_PARAMETER_VIDEO_INTERLACE_TYPE_T interlace_type;
285
290 }
292
293 if (!format_out)
295
296 if ((
status = mmal_port_parameter_set_uint32(
decoder->output[0], MMAL_PARAMETER_EXTRA_BUFFERS,
ctx->extra_buffers)))
298
299 if ((
status = mmal_port_parameter_set_boolean(
decoder->output[0], MMAL_PARAMETER_VIDEO_INTERPOLATE_TIMESTAMPS, 0)))
301
303 format_out->encoding = MMAL_ENCODING_OPAQUE;
304 } else {
305 format_out->encoding_variant = format_out->encoding = MMAL_ENCODING_I420;
306 }
307
310
311 interlace_type.hdr.id = MMAL_PARAMETER_VIDEO_INTERLACE_TYPE;
312 interlace_type.hdr.size = sizeof(MMAL_PARAMETER_VIDEO_INTERLACE_TYPE_T);
313 status = mmal_port_parameter_get(
decoder->output[0], &interlace_type.hdr);
314 if (
status != MMAL_SUCCESS) {
316 } else {
317 ctx->interlaced_frame = (interlace_type.eMode != MMAL_InterlaceProgressive);
318 ctx->top_field_first = (interlace_type.eMode == MMAL_InterlaceFieldsInterleavedUpperFirst);
319 }
320
322 format_out->es->video.crop.y + format_out->es->video.crop.height)) < 0)
324
325 if (format_out->es->video.par.num && format_out->es->video.par.den) {
328 }
329 if (format_out->es->video.frame_rate.num && format_out->es->video.frame_rate.den) {
330 avctx->
framerate.
num = format_out->es->video.frame_rate.num;
331 avctx->
framerate.
den = format_out->es->video.frame_rate.den;
332 }
333
335
336 decoder->output[0]->buffer_size =
338 decoder->output[0]->buffer_num =
339 FFMAX(
decoder->output[0]->buffer_num_min,
decoder->output[0]->buffer_num_recommended) +
ctx->extra_buffers;
340 ctx->pool_out->pool = mmal_pool_create(
decoder->output[0]->buffer_num,
341 decoder->output[0]->buffer_size);
342 if (!
ctx->pool_out->pool) {
345 }
346
347 return 0;
348
351 }
352
354 {
357 MMAL_ES_FORMAT_T *format_in;
360
362
363 bcm_host_init();
364
365 if (mmal_vc_init()) {
368 }
369
372
374
375 if ((
status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, &
ctx->decoder)))
377
379
380 format_in =
decoder->input[0]->format;
381 format_in->type = MMAL_ES_TYPE_VIDEO;
384 format_in->encoding = MMAL_ENCODING_MP2V;
385 break;
387 format_in->encoding = MMAL_ENCODING_MP4V;
388 break;
390 format_in->encoding = MMAL_ENCODING_WVC1;
391 break;
393 default:
394 format_in->encoding = MMAL_ENCODING_H264;
395 break;
396 }
399 format_in->es->video.crop.width = avctx->
width;
400 format_in->es->video.crop.height = avctx->
height;
401 format_in->es->video.frame_rate.num = 24000;
402 format_in->es->video.frame_rate.den = 1001;
405 format_in->flags = MMAL_ES_FORMAT_FLAG_FRAMED;
406
409
410 #if HAVE_MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS
411 if (mmal_port_parameter_set_uint32(
decoder->input[0], MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS,
412 -1 -
ctx->extra_decoder_buffers)) {
414 }
415 #endif
416
419
420 decoder->input[0]->buffer_num =
422 decoder->input[0]->buffer_size =
424 ctx->pool_in = mmal_pool_create(
decoder->input[0]->buffer_num, 0);
428 }
429
432
433 ctx->queue_decoded_frames = mmal_queue_create();
434 if (!
ctx->queue_decoded_frames)
436
437 decoder->input[0]->userdata = (
void*)avctx;
438 decoder->output[0]->userdata = (
void*)avctx;
439 decoder->control->userdata = (
void*)avctx;
440
447
450
451 return 0;
452
456 }
457
459 {
463
465
472
473 return;
474
477 }
478
479 // Split packets and add them to the waiting_buffers list. We don't queue them
480 // immediately, because it can happen that the decoder is temporarily blocked
481 // (due to us not reading/returning enough output buffers) and won't accept
482 // new input. (This wouldn't be an issue if MMAL input buffers always were
483 // complete frames - then the input buffer just would have to be big enough.)
484 // If is_extradata is set, send it as MMAL_BUFFER_HEADER_FLAG_CONFIG.
486 int is_extradata)
487 {
491 uint8_t *
data = (uint8_t *)
"";
492 uint8_t *start;
494
498 goto done;
502 if (!is_extradata)
504 } else {
506 goto done;
507 if (!
ctx->packets_sent) {
508 // Short-cut the flush logic to avoid upsetting MMAL.
510 ctx->eos_received = 1;
511 goto done;
512 }
513 }
514
516
517 do {
521 goto done;
522 }
523
526
527 if (is_extradata)
529
531 buffer->
flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_START;
532
535
538
540 buffer->
flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_END;
542 }
543
547 }
548
549 if (buf) {
554 goto done;
555 }
556 }
557
558 // Insert at end of the list
559 if (!
ctx->waiting_buffers)
561 if (
ctx->waiting_buffers_tail)
562 ctx->waiting_buffers_tail->next =
buffer;
565
566 done:
569 }
570
571 // Move prepared/split packets from waiting_buffers to the MMAL decoder.
573 {
575
576 while (
ctx->waiting_buffers) {
577 MMAL_BUFFER_HEADER_T *mbuffer;
580
581 mbuffer = mmal_queue_get(
ctx->pool_in->queue);
582 if (!mbuffer)
583 return 0;
584
586
587 mmal_buffer_header_reset(mbuffer);
588 mbuffer->cmd = 0;
590 mbuffer->dts =
buffer->dts;
593 mbuffer->length =
buffer->length;
594 mbuffer->user_data =
buffer;
595 mbuffer->alloc_size =
ctx->decoder->input[0]->buffer_size;
596
597 // Remove from start of the list
600 ctx->waiting_buffers_tail =
NULL;
601
602 if ((
status = mmal_port_send_buffer(
ctx->decoder->input[0], mbuffer))) {
603 mmal_buffer_header_release(mbuffer);
605 if (
buffer->
flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END)
608 }
609
613 }
614 }
615
616 return 0;
617 }
618
620 MMAL_BUFFER_HEADER_T *
buffer)
621 {
624
625 frame->interlaced_frame =
ctx->interlaced_frame;
626 frame->top_field_first =
ctx->top_field_first;
627
630 return AVERROR_UNKNOWN;
// format change code failed with OOM previously
631
633 goto done;
634
636 goto done;
637 } else {
641 int linesize[4];
642
644 goto done;
645
651 }
652
658
661
662 done:
664 }
665
666 // Fetch a decoded buffer and place it into the frame parameter.
668 {
673
674 if (
ctx->eos_received)
675 goto done;
676
677 while (1) {
678 // To ensure decoding in lockstep with a constant delay between fed packets
679 // and output frames, we always wait until an output buffer is available.
680 // Except during start we don't know after how many input packets the decoder
681 // is going to return the first buffer, and we can't distinguish decoder
682 // being busy from decoder waiting for input. So just poll at the start and
683 // keep feeding new data to the buffer.
684 // We are pretty sure the decoder will produce output if we sent more input
685 // frames than what a H.264 decoder could logically delay. This avoids too
686 // excessive buffering.
687 // We also wait if we sent eos, but didn't receive it yet (think of decoding
688 // stream with a very low number of frames).
690 (
ctx->packets_sent &&
ctx->eos_sent)) {
691 // MMAL will ignore broken input packets, which means the frame we
692 // expect here may never arrive. Dealing with this correctly is
693 // complicated, so here's a hack to avoid that it freezes forever
694 // in this unlikely situation.
695 buffer = mmal_queue_timedwait(
ctx->queue_decoded_frames, 100);
699 goto done;
700 }
701 } else {
702 buffer = mmal_queue_get(
ctx->queue_decoded_frames);
704 goto done;
705 }
706
707 ctx->eos_received |= !!(
buffer->
flags & MMAL_BUFFER_HEADER_FLAG_EOS);
708 if (
ctx->eos_received)
709 goto done;
710
711 if (
buffer->cmd == MMAL_EVENT_FORMAT_CHANGED) {
713 MMAL_EVENT_FORMAT_CHANGED_T *ev = mmal_event_format_changed_get(
buffer);
714 MMAL_BUFFER_HEADER_T *stale_buffer;
715
717
719 goto done;
720
721 while ((stale_buffer = mmal_queue_get(
ctx->queue_decoded_frames)))
722 mmal_buffer_header_release(stale_buffer);
723
724 mmal_format_copy(
decoder->output[0]->format, ev->format);
725
727 goto done;
728
730 goto done;
731
733 goto done;
734
736 goto done;
737
738 mmal_buffer_header_release(
buffer);
739 continue;
743 goto done;
744 }
else if (
buffer->length == 0) {
745 // Unused output buffer that got drained after format change.
746 mmal_buffer_header_release(
buffer);
747 continue;
748 }
749
750 ctx->frames_output++;
751
753 goto done;
754
755 *got_frame = 1;
756 break;
757 }
758
759 done:
761 mmal_buffer_header_release(
buffer);
765 }
766
768 {
772 int got_frame = 0;
773
777 ctx->extradata_sent = 1;
780 }
781
788
791
794
797
798 // ffmmal_read_frame() can block for a while. Since the decoder is
799 // asynchronous, it's a good idea to fill the ports again.
800
803
806
807 if (!got_frame &&
ret == 0)
809 else
811 }
812
816 };
817
820 {
"extra_decoder_buffers",
"extra MMAL internal buffered frames", offsetof(
MMALDecodeContext, extra_decoder_buffers),
AV_OPT_TYPE_INT, {.i64 = 10}, 0, 256, 0},
822 };
823
829 };
830
831 #define FFMMAL_DEC(NAME, ID) \
832 const FFCodec ff_##NAME##_mmal_decoder = { \
833 .p.name = #NAME "_mmal", \
834 CODEC_LONG_NAME(#NAME " (mmal)"), \
835 .p.type = AVMEDIA_TYPE_VIDEO, \
836 .p.id = ID, \
837 .priv_data_size = sizeof(MMALDecodeContext), \
838 .init = ffmmal_init_decoder, \
839 .close = ffmmal_close_decoder, \
840 FF_CODEC_RECEIVE_FRAME_CB(ffmmal_receive_frame), \
841 .flush = ffmmal_flush, \
842 .p.priv_class = &ffmmal_dec_class, \
843 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE, \
844 .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE | \
845 FF_CODEC_CAP_SETS_PKT_DTS, \
846 .p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_MMAL, \
847 AV_PIX_FMT_YUV420P, \
848 AV_PIX_FMT_NONE}, \
849 .hw_configs = mmal_hw_configs, \
850 .p.wrapper_name = "mmal", \
851 };
852