3 * Copyright (c) 2015 Rodger Combs
5 * This file is part of Libav.
7 * Libav 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.
12 * Libav 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.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with Libav; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
29 #include "libavutil/atomic.h"
30 #include "libavutil/avassert.h"
31 #include "libavutil/buffer.h"
32 #include "libavutil/common.h"
33 #include "libavutil/opt.h"
34 #include "libavutil/log.h"
37 #include <interface/mmal/mmal.h>
38 #include <interface/mmal/util/mmal_util.h>
39 #include <interface/mmal/util/mmal_util_params.h>
40 #include <interface/mmal/util/mmal_default_components.h>
42 typedef struct FFBufferEntry
{
48 struct FFBufferEntry
*next
;
51 // MMAL_POOL_T destroys all of its MMAL_BUFFER_HEADER_Ts. If we want correct
52 // refcounting for AVFrames, we can free the MMAL_POOL_T only after all AVFrames
53 // have been unreferenced.
54 typedef struct FFPoolRef
{
55 volatile int refcount
;
59 typedef struct FFBufferRef
{
60 MMAL_BUFFER_HEADER_T
*buffer
;
64 typedef struct MMALDecodeContext
{
68 AVBitStreamFilterContext
*bsfc
;
70 MMAL_COMPONENT_T
*decoder
;
71 MMAL_QUEUE_T
*queue_decoded_frames
;
75 // Waiting input packets. Because the libavcodec API requires decoding and
76 // returning packets in lockstep, it can happen that queue_decoded_frames
77 // contains almost all surfaces - then the decoder input queue can quickly
78 // fill up and won't accept new input either. Without consuming input, the
79 // libavcodec API can't return new frames, and we have a logical deadlock.
80 // This is avoided by queuing such buffers here.
81 FFBufferEntry
*waiting_buffers
, *waiting_buffers_tail
;
84 int64_t frames_output
;
89 // Assume decoder is guaranteed to produce output after at least this many
90 // packets (where each packet contains 1 frame).
91 #define MAX_DELAYED_FRAMES 16
93 static void ffmmal_poolref_unref(FFPoolRef
*ref
)
95 if (ref
&& avpriv_atomic_int_add_and_fetch(&ref
->refcount
, -1) == 0) {
96 mmal_pool_destroy(ref
->pool
);
101 static void ffmmal_release_frame(void *opaque
, uint8_t *data
)
103 FFBufferRef
*ref
= (void *)data
;
105 mmal_buffer_header_release(ref
->buffer
);
106 ffmmal_poolref_unref(ref
->pool
);
111 // Setup frame with a new reference to buffer. The buffer must have been
112 // allocated from the given pool.
113 static int ffmmal_set_ref(AVFrame
*frame
, FFPoolRef
*pool
,
114 MMAL_BUFFER_HEADER_T
*buffer
)
116 FFBufferRef
*ref
= av_mallocz(sizeof(*ref
));
118 return AVERROR(ENOMEM
);
121 ref
->buffer
= buffer
;
123 frame
->buf
[0] = av_buffer_create((void *)ref
, sizeof(*ref
),
124 ffmmal_release_frame
, NULL
,
125 AV_BUFFER_FLAG_READONLY
);
126 if (!frame
->buf
[0]) {
128 return AVERROR(ENOMEM
);
131 avpriv_atomic_int_add_and_fetch(&ref
->pool
->refcount
, 1);
132 mmal_buffer_header_acquire(buffer
);
134 frame
->format
= AV_PIX_FMT_MMAL
;
135 frame
->data
[3] = (uint8_t *)ref
->buffer
;
139 static void ffmmal_stop_decoder(AVCodecContext
*avctx
)
141 MMALDecodeContext
*ctx
= avctx
->priv_data
;
142 MMAL_COMPONENT_T
*decoder
= ctx
->decoder
;
143 MMAL_BUFFER_HEADER_T
*buffer
;
145 mmal_port_disable(decoder
->input
[0]);
146 mmal_port_disable(decoder
->output
[0]);
147 mmal_port_disable(decoder
->control
);
149 mmal_port_flush(decoder
->input
[0]);
150 mmal_port_flush(decoder
->output
[0]);
151 mmal_port_flush(decoder
->control
);
153 while ((buffer
= mmal_queue_get(ctx
->queue_decoded_frames
)))
154 mmal_buffer_header_release(buffer
);
156 while (ctx
->waiting_buffers
) {
157 FFBufferEntry
*buffer
= ctx
->waiting_buffers
;
159 ctx
->waiting_buffers
= buffer
->next
;
161 av_buffer_unref(&buffer
->ref
);
164 ctx
->waiting_buffers_tail
= NULL
;
166 ctx
->frames_output
= ctx
->eos_received
= ctx
->eos_sent
= ctx
->packets_sent
= 0;
169 static av_cold
int ffmmal_close_decoder(AVCodecContext
*avctx
)
171 MMALDecodeContext
*ctx
= avctx
->priv_data
;
174 ffmmal_stop_decoder(avctx
);
176 mmal_component_destroy(ctx
->decoder
);
178 mmal_queue_destroy(ctx
->queue_decoded_frames
);
179 mmal_pool_destroy(ctx
->pool_in
);
180 ffmmal_poolref_unref(ctx
->pool_out
);
183 av_bitstream_filter_close(ctx
->bsfc
);
188 static void input_callback(MMAL_PORT_T
*port
, MMAL_BUFFER_HEADER_T
*buffer
)
191 AVBufferRef
*buf
= buffer
->user_data
;
192 av_buffer_unref(&buf
);
194 mmal_buffer_header_release(buffer
);
197 static void output_callback(MMAL_PORT_T
*port
, MMAL_BUFFER_HEADER_T
*buffer
)
199 AVCodecContext
*avctx
= (AVCodecContext
*)port
->userdata
;
200 MMALDecodeContext
*ctx
= avctx
->priv_data
;
202 mmal_queue_put(ctx
->queue_decoded_frames
, buffer
);
205 static void control_port_cb(MMAL_PORT_T
*port
, MMAL_BUFFER_HEADER_T
*buffer
)
207 AVCodecContext
*avctx
= (AVCodecContext
*)port
->userdata
;
208 MMAL_STATUS_T status
;
210 if (buffer
->cmd
== MMAL_EVENT_ERROR
) {
211 status
= *(uint32_t *)buffer
->data
;
212 av_log(avctx
, AV_LOG_ERROR
, "MMAL error %d on control port\n", (int)status
);
215 av_get_codec_tag_string(s
, sizeof(s
), buffer
->cmd
);
216 av_log(avctx
, AV_LOG_WARNING
, "Unknown MMAL event %s on control port\n", s
);
219 mmal_buffer_header_release(buffer
);
222 // Feed free output buffers to the decoder.
223 static int ffmmal_fill_output_port(AVCodecContext
*avctx
)
225 MMALDecodeContext
*ctx
= avctx
->priv_data
;
226 MMAL_BUFFER_HEADER_T
*buffer
;
227 MMAL_STATUS_T status
;
230 return AVERROR_UNKNOWN
; // format change code failed with OOM previously
232 while ((buffer
= mmal_queue_get(ctx
->pool_out
->pool
->queue
))) {
233 if ((status
= mmal_port_send_buffer(ctx
->decoder
->output
[0], buffer
))) {
234 mmal_buffer_header_release(buffer
);
235 av_log(avctx
, AV_LOG_ERROR
, "MMAL error %d when sending output buffer.\n", (int)status
);
236 return AVERROR_UNKNOWN
;
243 static enum AVColorSpace
ffmmal_csp_to_av_csp(MMAL_FOURCC_T fourcc
)
246 case MMAL_COLOR_SPACE_BT470_2_BG
:
247 case MMAL_COLOR_SPACE_BT470_2_M
:
248 case MMAL_COLOR_SPACE_ITUR_BT601
: return AVCOL_SPC_BT470BG
;
249 case MMAL_COLOR_SPACE_ITUR_BT709
: return AVCOL_SPC_BT709
;
250 case MMAL_COLOR_SPACE_FCC
: return AVCOL_SPC_FCC
;
251 case MMAL_COLOR_SPACE_SMPTE240M
: return AVCOL_SPC_SMPTE240M
;
252 default: return AVCOL_SPC_UNSPECIFIED
;
256 static int ffmal_update_format(AVCodecContext
*avctx
)
258 MMALDecodeContext
*ctx
= avctx
->priv_data
;
259 MMAL_STATUS_T status
;
261 MMAL_COMPONENT_T
*decoder
= ctx
->decoder
;
262 MMAL_ES_FORMAT_T
*format_out
= decoder
->output
[0]->format
;
264 ffmmal_poolref_unref(ctx
->pool_out
);
265 if (!(ctx
->pool_out
= av_mallocz(sizeof(*ctx
->pool_out
)))) {
266 ret
= AVERROR(ENOMEM
);
269 ctx
->pool_out
->refcount
= 1;
274 if ((status
= mmal_port_parameter_set_uint32(decoder
->output
[0], MMAL_PARAMETER_EXTRA_BUFFERS
, ctx
->extra_buffers
)))
277 if (avctx
->pix_fmt
== AV_PIX_FMT_MMAL
) {
278 format_out
->encoding
= MMAL_ENCODING_OPAQUE
;
280 format_out
->encoding_variant
= format_out
->encoding
= MMAL_ENCODING_I420
;
283 if ((status
= mmal_port_format_commit(decoder
->output
[0])))
286 if ((ret
= ff_set_dimensions(avctx
, format_out
->es
->video
.crop
.x
+ format_out
->es
->video
.crop
.width
,
287 format_out
->es
->video
.crop
.y
+ format_out
->es
->video
.crop
.height
)) < 0)
290 if (format_out
->es
->video
.par
.num
&& format_out
->es
->video
.par
.den
) {
291 avctx
->sample_aspect_ratio
.num
= format_out
->es
->video
.par
.num
;
292 avctx
->sample_aspect_ratio
.den
= format_out
->es
->video
.par
.den
;
295 avctx
->colorspace
= ffmmal_csp_to_av_csp(format_out
->es
->video
.color_space
);
297 decoder
->output
[0]->buffer_size
=
298 FFMAX(decoder
->output
[0]->buffer_size_min
, decoder
->output
[0]->buffer_size_recommended
);
299 decoder
->output
[0]->buffer_num
=
300 FFMAX(decoder
->output
[0]->buffer_num_min
, decoder
->output
[0]->buffer_num_recommended
) + ctx
->extra_buffers
;
301 ctx
->pool_out
->pool
= mmal_pool_create(decoder
->output
[0]->buffer_num
,
302 decoder
->output
[0]->buffer_size
);
303 if (!ctx
->pool_out
->pool
) {
304 ret
= AVERROR(ENOMEM
);
311 return ret
< 0 ? ret
: AVERROR_UNKNOWN
;
314 static av_cold
int ffmmal_init_decoder(AVCodecContext
*avctx
)
316 MMALDecodeContext
*ctx
= avctx
->priv_data
;
317 MMAL_STATUS_T status
;
318 MMAL_ES_FORMAT_T
*format_in
;
319 MMAL_COMPONENT_T
*decoder
;
324 if ((ret
= ff_get_format(avctx
, avctx
->codec
->pix_fmts
)) < 0)
327 avctx
->pix_fmt
= ret
;
329 if ((status
= mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER
, &ctx
->decoder
)))
332 decoder
= ctx
->decoder
;
334 format_in
= decoder
->input
[0]->format
;
335 format_in
->type
= MMAL_ES_TYPE_VIDEO
;
336 format_in
->encoding
= MMAL_ENCODING_H264
;
337 format_in
->es
->video
.width
= FFALIGN(avctx
->width
, 32);
338 format_in
->es
->video
.height
= FFALIGN(avctx
->height
, 16);
339 format_in
->es
->video
.crop
.width
= avctx
->width
;
340 format_in
->es
->video
.crop
.height
= avctx
->height
;
341 format_in
->es
->video
.frame_rate
.num
= 24000;
342 format_in
->es
->video
.frame_rate
.den
= 1001;
343 format_in
->es
->video
.par
.num
= avctx
->sample_aspect_ratio
.num
;
344 format_in
->es
->video
.par
.den
= avctx
->sample_aspect_ratio
.den
;
345 format_in
->flags
= MMAL_ES_FORMAT_FLAG_FRAMED
;
347 if (avctx
->codec
->id
== AV_CODEC_ID_H264
&& avctx
->extradata
&& avctx
->extradata
[0] == 1) {
350 ctx
->bsfc
= av_bitstream_filter_init("h264_mp4toannexb");
352 av_log(avctx
, AV_LOG_ERROR
, "Cannot open the h264_mp4toannexb BSF!\n");
353 ret
= AVERROR(ENOSYS
);
356 av_bitstream_filter_filter(ctx
->bsfc
, avctx
, NULL
, &dummy_p
, &dummy_int
, NULL
, 0, 0);
359 if (avctx
->extradata_size
) {
360 if ((status
= mmal_format_extradata_alloc(format_in
, avctx
->extradata_size
)))
362 format_in
->extradata_size
= avctx
->extradata_size
;
363 memcpy(format_in
->extradata
, avctx
->extradata
, format_in
->extradata_size
);
366 if ((status
= mmal_port_format_commit(decoder
->input
[0])))
369 decoder
->input
[0]->buffer_num
=
370 FFMAX(decoder
->input
[0]->buffer_num_min
, 20);
371 decoder
->input
[0]->buffer_size
=
372 FFMAX(decoder
->input
[0]->buffer_size_min
, 512 * 1024);
373 ctx
->pool_in
= mmal_pool_create(decoder
->input
[0]->buffer_num
, 0);
375 ret
= AVERROR(ENOMEM
);
379 if ((ret
= ffmal_update_format(avctx
)) < 0)
382 ctx
->queue_decoded_frames
= mmal_queue_create();
383 if (!ctx
->queue_decoded_frames
)
386 decoder
->input
[0]->userdata
= (void*)avctx
;
387 decoder
->output
[0]->userdata
= (void*)avctx
;
388 decoder
->control
->userdata
= (void*)avctx
;
390 if ((status
= mmal_port_enable(decoder
->control
, control_port_cb
)))
392 if ((status
= mmal_port_enable(decoder
->input
[0], input_callback
)))
394 if ((status
= mmal_port_enable(decoder
->output
[0], output_callback
)))
397 if ((status
= mmal_component_enable(decoder
)))
403 ffmmal_close_decoder(avctx
);
404 return ret
< 0 ? ret
: AVERROR_UNKNOWN
;
407 static void ffmmal_flush(AVCodecContext
*avctx
)
409 MMALDecodeContext
*ctx
= avctx
->priv_data
;
410 MMAL_COMPONENT_T
*decoder
= ctx
->decoder
;
411 MMAL_STATUS_T status
;
413 ffmmal_stop_decoder(avctx
);
415 if ((status
= mmal_port_enable(decoder
->control
, control_port_cb
)))
417 if ((status
= mmal_port_enable(decoder
->input
[0], input_callback
)))
419 if ((status
= mmal_port_enable(decoder
->output
[0], output_callback
)))
425 av_log(avctx
, AV_LOG_ERROR
, "MMAL flush error: %i\n", (int)status
);
428 // Split packets and add them to the waiting_buffers list. We don't queue them
429 // immediately, because it can happen that the decoder is temporarily blocked
430 // (due to us not reading/returning enough output buffers) and won't accept
431 // new input. (This wouldn't be an issue if MMAL input buffers always were
432 // complete frames - then the input buffer just would have to be big enough.)
433 static int ffmmal_add_packet(AVCodecContext
*avctx
, AVPacket
*avpkt
)
435 MMALDecodeContext
*ctx
= avctx
->priv_data
;
436 AVBufferRef
*buf
= NULL
;
438 uint8_t *data
= (uint8_t *)"";
448 if ((ret
= av_bitstream_filter_filter(ctx
->bsfc
, avctx
, NULL
,
449 &tmp_data
, &tmp_size
,
450 avpkt
->data
, avpkt
->size
,
451 avpkt
->flags
& AV_PKT_FLAG_KEY
)) < 0)
453 buf
= av_buffer_create(tmp_data
, tmp_size
, NULL
, NULL
, 0);
456 buf
= av_buffer_ref(avpkt
->buf
);
458 buf
= av_buffer_alloc(avpkt
->size
);
460 memcpy(buf
->data
, avpkt
->data
, avpkt
->size
);
464 ret
= AVERROR(ENOMEM
);
474 FFBufferEntry
*buffer
= av_mallocz(sizeof(*buffer
));
476 ret
= AVERROR(ENOMEM
);
481 buffer
->length
= FFMIN(size
, ctx
->decoder
->input
[0]->buffer_size
);
484 buffer
->flags
|= MMAL_BUFFER_HEADER_FLAG_FRAME_START
;
486 data
+= buffer
->length
;
487 size
-= buffer
->length
;
489 buffer
->pts
= avpkt
->pts
== AV_NOPTS_VALUE ? MMAL_TIME_UNKNOWN
: avpkt
->pts
;
490 buffer
->dts
= avpkt
->dts
== AV_NOPTS_VALUE ? MMAL_TIME_UNKNOWN
: avpkt
->dts
;
493 buffer
->flags
|= MMAL_BUFFER_HEADER_FLAG_FRAME_END
;
495 if (!buffer
->length
) {
496 buffer
->flags
|= MMAL_BUFFER_HEADER_FLAG_EOS
;
501 buffer
->ref
= av_buffer_ref(buf
);
504 ret
= AVERROR(ENOMEM
);
509 // Insert at end of the list
510 if (!ctx
->waiting_buffers
)
511 ctx
->waiting_buffers
= buffer
;
512 if (ctx
->waiting_buffers_tail
)
513 ctx
->waiting_buffers_tail
->next
= buffer
;
514 ctx
->waiting_buffers_tail
= buffer
;
518 av_buffer_unref(&buf
);
522 // Move prepared/split packets from waiting_buffers to the MMAL decoder.
523 static int ffmmal_fill_input_port(AVCodecContext
*avctx
)
525 MMALDecodeContext
*ctx
= avctx
->priv_data
;
527 while (ctx
->waiting_buffers
) {
528 MMAL_BUFFER_HEADER_T
*mbuffer
;
529 FFBufferEntry
*buffer
;
530 MMAL_STATUS_T status
;
532 mbuffer
= mmal_queue_get(ctx
->pool_in
->queue
);
536 buffer
= ctx
->waiting_buffers
;
538 mmal_buffer_header_reset(mbuffer
);
540 mbuffer
->pts
= buffer
->pts
;
541 mbuffer
->dts
= buffer
->dts
;
542 mbuffer
->flags
= buffer
->flags
;
543 mbuffer
->data
= buffer
->data
;
544 mbuffer
->length
= buffer
->length
;
545 mbuffer
->user_data
= buffer
->ref
;
546 mbuffer
->alloc_size
= ctx
->decoder
->input
[0]->buffer_size
;
548 if ((status
= mmal_port_send_buffer(ctx
->decoder
->input
[0], mbuffer
))) {
549 mmal_buffer_header_release(mbuffer
);
550 av_buffer_unref(&buffer
->ref
);
553 // Remove from start of the list
554 ctx
->waiting_buffers
= buffer
->next
;
555 if (ctx
->waiting_buffers_tail
== buffer
)
556 ctx
->waiting_buffers_tail
= NULL
;
560 av_log(avctx
, AV_LOG_ERROR
, "MMAL error %d when sending input\n", (int)status
);
561 return AVERROR_UNKNOWN
;
568 static int ffmal_copy_frame(AVCodecContext
*avctx
, AVFrame
*frame
,
569 MMAL_BUFFER_HEADER_T
*buffer
)
571 MMALDecodeContext
*ctx
= avctx
->priv_data
;
574 if (avctx
->pix_fmt
== AV_PIX_FMT_MMAL
) {
576 return AVERROR_UNKNOWN
; // format change code failed with OOM previously
578 if ((ret
= ff_decode_frame_props(avctx
, frame
)) < 0)
581 if ((ret
= ffmmal_set_ref(frame
, ctx
->pool_out
, buffer
)) < 0)
584 int w
= FFALIGN(avctx
->width
, 32);
585 int h
= FFALIGN(avctx
->height
, 16);
590 if ((ret
= ff_get_buffer(avctx
, frame
, 0)) < 0)
593 ptr
= buffer
->data
+ buffer
->type
->video
.offset
[0];
594 for (i
= 0; i
< avctx
->height
; i
++)
595 memcpy(frame
->data
[0] + frame
->linesize
[0] * i
, ptr
+ w
* i
, avctx
->width
);
599 for (plane
= 1; plane
< 3; plane
++) {
600 for (i
= 0; i
< avctx
->height
/ 2; i
++)
601 memcpy(frame
->data
[plane
] + frame
->linesize
[plane
] * i
, ptr
+ w
/ 2 * i
, (avctx
->width
+ 1) / 2);
602 ptr
+= w
/ 2 * h
/ 2;
606 if (buffer
->pts
!= MMAL_TIME_UNKNOWN
) {
607 frame
->pkt_pts
= buffer
->pts
;
608 frame
->pts
= buffer
->pts
;
615 // Fetch a decoded buffer and place it into the frame parameter.
616 static int ffmmal_read_frame(AVCodecContext
*avctx
, AVFrame
*frame
, int *got_frame
)
618 MMALDecodeContext
*ctx
= avctx
->priv_data
;
619 MMAL_BUFFER_HEADER_T
*buffer
= NULL
;
620 MMAL_STATUS_T status
= 0;
623 if (ctx
->eos_received
)
627 // To ensure decoding in lockstep with a constant delay between fed packets
628 // and output frames, we always wait until an output buffer is available.
629 // Except during start we don't know after how many input packets the decoder
630 // is going to return the first buffer, and we can't distinguish decoder
631 // being busy from decoder waiting for input. So just poll at the start and
632 // keep feeding new data to the buffer.
633 // We are pretty sure the decoder will produce output if we sent more input
634 // frames than what a h264 decoder could logically delay. This avoids too
635 // excessive buffering.
636 // We also wait if we sent eos, but didn't receive it yet (think of decoding
637 // stream with a very low number of frames).
638 if (ctx
->frames_output
|| ctx
->packets_sent
> MAX_DELAYED_FRAMES
|| ctx
->eos_sent
) {
639 buffer
= mmal_queue_wait(ctx
->queue_decoded_frames
);
641 buffer
= mmal_queue_get(ctx
->queue_decoded_frames
);
646 ctx
->eos_received
|= !!(buffer
->flags
& MMAL_BUFFER_HEADER_FLAG_EOS
);
647 if (ctx
->eos_received
)
650 if (buffer
->cmd
== MMAL_EVENT_FORMAT_CHANGED
) {
651 MMAL_COMPONENT_T
*decoder
= ctx
->decoder
;
652 MMAL_EVENT_FORMAT_CHANGED_T
*ev
= mmal_event_format_changed_get(buffer
);
653 MMAL_BUFFER_HEADER_T
*stale_buffer
;
655 av_log(avctx
, AV_LOG_INFO
, "Changing output format.\n");
657 if ((status
= mmal_port_disable(decoder
->output
[0])))
660 while ((stale_buffer
= mmal_queue_get(ctx
->queue_decoded_frames
)))
661 mmal_buffer_header_release(stale_buffer
);
663 mmal_format_copy(decoder
->output
[0]->format
, ev
->format
);
665 if ((ret
= ffmal_update_format(avctx
)) < 0)
668 if ((status
= mmal_port_enable(decoder
->output
[0], output_callback
)))
671 if ((ret
= ffmmal_fill_output_port(avctx
)) < 0)
674 if ((ret
= ffmmal_fill_input_port(avctx
)) < 0)
677 mmal_buffer_header_release(buffer
);
679 } else if (buffer
->cmd
) {
681 av_get_codec_tag_string(s
, sizeof(s
), buffer
->cmd
);
682 av_log(avctx
, AV_LOG_WARNING
, "Unknown MMAL event %s on output port\n", s
);
684 } else if (buffer
->length
== 0) {
685 // Unused output buffer that got drained after format change.
686 mmal_buffer_header_release(buffer
);
690 ctx
->frames_output
++;
692 if ((ret
= ffmal_copy_frame(avctx
, frame
, buffer
)) < 0)
701 mmal_buffer_header_release(buffer
);
702 if (status
&& ret
>= 0)
703 ret
= AVERROR_UNKNOWN
;
707 static int ffmmal_decode(AVCodecContext
*avctx
, void *data
, int *got_frame
,
710 AVFrame
*frame
= data
;
713 if ((ret
= ffmmal_add_packet(avctx
, avpkt
)) < 0)
716 if ((ret
= ffmmal_fill_input_port(avctx
)) < 0)
719 if ((ret
= ffmmal_fill_output_port(avctx
)) < 0)
722 if ((ret
= ffmmal_read_frame(avctx
, frame
, got_frame
)) < 0)
725 // ffmmal_read_frame() can block for a while. Since the decoder is
726 // asynchronous, it's a good idea to fill the ports again.
728 if ((ret
= ffmmal_fill_output_port(avctx
)) < 0)
731 if ((ret
= ffmmal_fill_input_port(avctx
)) < 0)
737 AVHWAccel ff_h264_mmal_hwaccel
= {
739 .type
= AVMEDIA_TYPE_VIDEO
,
740 .id
= AV_CODEC_ID_H264
,
741 .pix_fmt
= AV_PIX_FMT_MMAL
,
744 static const AVOption options
[]={
745 {"extra_buffers", "extra buffers", offsetof(MMALDecodeContext
, extra_buffers
), AV_OPT_TYPE_INT
, {.i64
= 10}, 0, 256, 0},
749 static const AVClass ffmmaldec_class
= {
750 .class_name
= "mmaldec",
752 .version
= LIBAVUTIL_VERSION_INT
,
755 AVCodec ff_h264_mmal_decoder
= {
757 .long_name
= NULL_IF_CONFIG_SMALL("h264 (mmal)"),
758 .type
= AVMEDIA_TYPE_VIDEO
,
759 .id
= AV_CODEC_ID_H264
,
760 .priv_data_size
= sizeof(MMALDecodeContext
),
761 .init
= ffmmal_init_decoder
,
762 .close
= ffmmal_close_decoder
,
763 .decode
= ffmmal_decode
,
764 .flush
= ffmmal_flush
,
765 .priv_class
= &ffmmaldec_class
,
766 .capabilities
= CODEC_CAP_DELAY
,
767 .pix_fmts
= (const enum AVPixelFormat
[]) { AV_PIX_FMT_MMAL
,