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
106 };
107
109 {
112 mmal_pool_destroy(
ref->pool);
114 }
115 }
116
118 {
120
121 mmal_buffer_header_release(
ref->buffer);
123
125 }
126
127 // Setup frame with a new reference to buffer. The buffer must have been
128 // allocated from the given pool.
130 MMAL_BUFFER_HEADER_T *
buffer)
131 {
135
138
145 }
146
148 mmal_buffer_header_acquire(
buffer);
149
152 return 0;
153 }
154
156 {
159 MMAL_BUFFER_HEADER_T *
buffer;
160
161 mmal_port_disable(
decoder->input[0]);
162 mmal_port_disable(
decoder->output[0]);
163 mmal_port_disable(
decoder->control);
164
165 mmal_port_flush(
decoder->input[0]);
166 mmal_port_flush(
decoder->output[0]);
167 mmal_port_flush(
decoder->control);
168
169 while ((
buffer = mmal_queue_get(
ctx->queue_decoded_frames)))
170 mmal_buffer_header_release(
buffer);
171
172 while (
ctx->waiting_buffers) {
174
176
177 if (
buffer->
flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END)
179
182 }
183 ctx->waiting_buffers_tail =
NULL;
184
186
187 ctx->frames_output =
ctx->eos_received =
ctx->eos_sent =
ctx->packets_sent =
ctx->extradata_sent = 0;
188 }
189
191 {
193
196
197 mmal_component_destroy(
ctx->decoder);
199 mmal_queue_destroy(
ctx->queue_decoded_frames);
200 mmal_pool_destroy(
ctx->pool_in);
202
203 mmal_vc_deinit();
204
205 return 0;
206 }
207
209 {
212
216 if (
entry->flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END)
219 }
220 mmal_buffer_header_release(
buffer);
221 }
222
224 {
227
228 mmal_queue_put(
ctx->queue_decoded_frames,
buffer);
229 }
230
232 {
235
236 if (
buffer->cmd == MMAL_EVENT_ERROR) {
239 } else {
242 }
243
244 mmal_buffer_header_release(
buffer);
245 }
246
247 // Feed free output buffers to the decoder.
249 {
251 MMAL_BUFFER_HEADER_T *
buffer;
253
255 return AVERROR_UNKNOWN;
// format change code failed with OOM previously
256
257 while ((
buffer = mmal_queue_get(
ctx->pool_out->pool->queue))) {
258 if ((
status = mmal_port_send_buffer(
ctx->decoder->output[0],
buffer))) {
259 mmal_buffer_header_release(
buffer);
262 }
263 }
264
265 return 0;
266 }
267
269 {
271 case MMAL_COLOR_SPACE_BT470_2_BG:
272 case MMAL_COLOR_SPACE_BT470_2_M:
278 }
279 }
280
282 {
287 MMAL_ES_FORMAT_T *format_out =
decoder->output[0]->format;
288 MMAL_PARAMETER_VIDEO_INTERLACE_TYPE_T interlace_type;
289
294 }
296
297 if (!format_out)
299
300 if ((
status = mmal_port_parameter_set_uint32(
decoder->output[0], MMAL_PARAMETER_EXTRA_BUFFERS,
ctx->extra_buffers)))
302
303 if ((
status = mmal_port_parameter_set_boolean(
decoder->output[0], MMAL_PARAMETER_VIDEO_INTERPOLATE_TIMESTAMPS, 0)))
305
307 format_out->encoding = MMAL_ENCODING_OPAQUE;
308 } else {
309 format_out->encoding_variant = format_out->encoding = MMAL_ENCODING_I420;
310 }
311
314
315 interlace_type.hdr.id = MMAL_PARAMETER_VIDEO_INTERLACE_TYPE;
316 interlace_type.hdr.size = sizeof(MMAL_PARAMETER_VIDEO_INTERLACE_TYPE_T);
317 status = mmal_port_parameter_get(
decoder->output[0], &interlace_type.hdr);
318 if (
status != MMAL_SUCCESS) {
320 } else {
321 ctx->interlaced_frame = (interlace_type.eMode != MMAL_InterlaceProgressive);
322 ctx->top_field_first = (interlace_type.eMode == MMAL_InterlaceFieldsInterleavedUpperFirst);
323 }
324
326 format_out->es->video.crop.y + format_out->es->video.crop.height)) < 0)
328
329 if (format_out->es->video.par.num && format_out->es->video.par.den) {
332 }
333 if (format_out->es->video.frame_rate.num && format_out->es->video.frame_rate.den) {
334 avctx->
framerate.
num = format_out->es->video.frame_rate.num;
335 avctx->
framerate.
den = format_out->es->video.frame_rate.den;
336 }
337
339
340 decoder->output[0]->buffer_size =
342 decoder->output[0]->buffer_num =
343 FFMAX(
decoder->output[0]->buffer_num_min,
decoder->output[0]->buffer_num_recommended) +
ctx->extra_buffers;
344 ctx->pool_out->pool = mmal_pool_create(
decoder->output[0]->buffer_num,
345 decoder->output[0]->buffer_size);
346 if (!
ctx->pool_out->pool) {
349 }
350
351 return 0;
352
355 }
356
358 {
361 MMAL_ES_FORMAT_T *format_in;
364
366
367 bcm_host_init();
368
369 if (mmal_vc_init()) {
372 }
373
376
378
379 if ((
status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, &
ctx->decoder)))
381
383
384 format_in =
decoder->input[0]->format;
385 format_in->type = MMAL_ES_TYPE_VIDEO;
388 format_in->encoding = MMAL_ENCODING_MP2V;
389 break;
391 format_in->encoding = MMAL_ENCODING_MP4V;
392 break;
394 format_in->encoding = MMAL_ENCODING_WVC1;
395 break;
397 default:
398 format_in->encoding = MMAL_ENCODING_H264;
399 break;
400 }
403 format_in->es->video.crop.width = avctx->
width;
404 format_in->es->video.crop.height = avctx->
height;
405 format_in->es->video.frame_rate.num = 24000;
406 format_in->es->video.frame_rate.den = 1001;
409 format_in->flags = MMAL_ES_FORMAT_FLAG_FRAMED;
410
413
414 #if HAVE_MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS
415 if (mmal_port_parameter_set_uint32(
decoder->input[0], MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS,
416 -1 -
ctx->extra_decoder_buffers)) {
418 }
419 #endif
420
423
424 decoder->input[0]->buffer_num =
426 decoder->input[0]->buffer_size =
428 ctx->pool_in = mmal_pool_create(
decoder->input[0]->buffer_num, 0);
432 }
433
436
437 ctx->queue_decoded_frames = mmal_queue_create();
438 if (!
ctx->queue_decoded_frames)
440
441 decoder->input[0]->userdata = (
void*)avctx;
442 decoder->output[0]->userdata = (
void*)avctx;
443 decoder->control->userdata = (
void*)avctx;
444
451
454
455 return 0;
456
460 }
461
463 {
467
469
476
477 return;
478
481 }
482
483 // Split packets and add them to the waiting_buffers list. We don't queue them
484 // immediately, because it can happen that the decoder is temporarily blocked
485 // (due to us not reading/returning enough output buffers) and won't accept
486 // new input. (This wouldn't be an issue if MMAL input buffers always were
487 // complete frames - then the input buffer just would have to be big enough.)
488 // If is_extradata is set, send it as MMAL_BUFFER_HEADER_FLAG_CONFIG.
490 int is_extradata)
491 {
495 uint8_t *
data = (uint8_t *)
"";
496 uint8_t *start;
498
502 goto done;
506 if (!is_extradata)
508 } else {
510 goto done;
511 if (!
ctx->packets_sent) {
512 // Short-cut the flush logic to avoid upsetting MMAL.
514 ctx->eos_received = 1;
515 goto done;
516 }
517 }
518
520
521 do {
525 goto done;
526 }
527
530
531 if (is_extradata)
533
535 buffer->
flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_START;
536
539
542
544 buffer->
flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_END;
546 }
547
551 }
552
553 if (buf) {
558 goto done;
559 }
560 }
561
562 // Insert at end of the list
563 if (!
ctx->waiting_buffers)
565 if (
ctx->waiting_buffers_tail)
566 ctx->waiting_buffers_tail->next =
buffer;
569
570 done:
573 }
574
575 // Move prepared/split packets from waiting_buffers to the MMAL decoder.
577 {
579
580 while (
ctx->waiting_buffers) {
581 MMAL_BUFFER_HEADER_T *mbuffer;
584
585 mbuffer = mmal_queue_get(
ctx->pool_in->queue);
586 if (!mbuffer)
587 return 0;
588
590
591 mmal_buffer_header_reset(mbuffer);
592 mbuffer->cmd = 0;
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;
600
601 // Remove from start of the list
604 ctx->waiting_buffers_tail =
NULL;
605
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)
612 }
613
617 }
618 }
619
620 return 0;
621 }
622
624 MMAL_BUFFER_HEADER_T *
buffer)
625 {
628
629 if (
ctx->interlaced_frame)
631 if (
ctx->top_field_first)
633
636 return AVERROR_UNKNOWN;
// format change code failed with OOM previously
637
639 goto done;
640
642 goto done;
643 } else {
647 int linesize[4];
648
650 goto done;
651
657 }
658
664
667
668 done:
670 }
671
672 // Fetch a decoded buffer and place it into the frame parameter.
674 {
679
680 if (
ctx->eos_received)
681 goto done;
682
683 while (1) {
684 // To ensure decoding in lockstep with a constant delay between fed packets
685 // and output frames, we always wait until an output buffer is available.
686 // Except during start we don't know after how many input packets the decoder
687 // is going to return the first buffer, and we can't distinguish decoder
688 // being busy from decoder waiting for input. So just poll at the start and
689 // keep feeding new data to the buffer.
690 // We are pretty sure the decoder will produce output if we sent more input
691 // frames than what a H.264 decoder could logically delay. This avoids too
692 // excessive buffering.
693 // We also wait if we sent eos, but didn't receive it yet (think of decoding
694 // stream with a very low number of frames).
696 (
ctx->packets_sent &&
ctx->eos_sent)) {
697 // MMAL will ignore broken input packets, which means the frame we
698 // expect here may never arrive. Dealing with this correctly is
699 // complicated, so here's a hack to avoid that it freezes forever
700 // in this unlikely situation.
701 buffer = mmal_queue_timedwait(
ctx->queue_decoded_frames, 100);
705 goto done;
706 }
707 } else {
708 buffer = mmal_queue_get(
ctx->queue_decoded_frames);
710 goto done;
711 }
712
713 ctx->eos_received |= !!(
buffer->
flags & MMAL_BUFFER_HEADER_FLAG_EOS);
714 if (
ctx->eos_received)
715 goto done;
716
717 if (
buffer->cmd == MMAL_EVENT_FORMAT_CHANGED) {
719 MMAL_EVENT_FORMAT_CHANGED_T *ev = mmal_event_format_changed_get(
buffer);
720 MMAL_BUFFER_HEADER_T *stale_buffer;
721
723
725 goto done;
726
727 while ((stale_buffer = mmal_queue_get(
ctx->queue_decoded_frames)))
728 mmal_buffer_header_release(stale_buffer);
729
730 mmal_format_copy(
decoder->output[0]->format, ev->format);
731
733 goto done;
734
736 goto done;
737
739 goto done;
740
742 goto done;
743
744 mmal_buffer_header_release(
buffer);
745 continue;
749 goto done;
750 }
else if (
buffer->length == 0) {
751 // Unused output buffer that got drained after format change.
752 mmal_buffer_header_release(
buffer);
753 continue;
754 }
755
756 ctx->frames_output++;
757
759 goto done;
760
761 *got_frame = 1;
762 break;
763 }
764
765 done:
767 mmal_buffer_header_release(
buffer);
771 }
772
774 {
778 int got_frame = 0;
779
783 ctx->extradata_sent = 1;
786 }
787
794
797
800
803
804 // ffmmal_read_frame() can block for a while. Since the decoder is
805 // asynchronous, it's a good idea to fill the ports again.
806
809
812
813 if (!got_frame &&
ret == 0)
815 else
817 }
818
822 };
823
826 {
"extra_decoder_buffers",
"extra MMAL internal buffered frames", offsetof(
MMALDecodeContext, extra_decoder_buffers),
AV_OPT_TYPE_INT, {.i64 = 10}, 0, 256, 0},
828 };
829
835 };
836
837 #define FFMMAL_DEC(NAME, ID) \
838 const FFCodec ff_##NAME##_mmal_decoder = { \
839 .p.name = #NAME "_mmal", \
840 CODEC_LONG_NAME(#NAME " (mmal)"), \
841 .p.type = AVMEDIA_TYPE_VIDEO, \
842 .p.id = ID, \
843 .priv_data_size = sizeof(MMALDecodeContext), \
844 .init = ffmmal_init_decoder, \
845 .close = ffmmal_close_decoder, \
846 FF_CODEC_RECEIVE_FRAME_CB(ffmmal_receive_frame), \
847 .flush = ffmmal_flush, \
848 .p.priv_class = &ffmmal_dec_class, \
849 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE, \
850 .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE, \
851 .hw_configs = mmal_hw_configs, \
852 .p.wrapper_name = "mmal", \
853 };
854