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> 99 #define MAX_DELAYED_FRAMES 16 105 mmal_pool_destroy(ref->
pool);
114 mmal_buffer_header_release(ref->
buffer);
123 MMAL_BUFFER_HEADER_T *
buffer)
135 if (!frame->
buf[0]) {
141 mmal_buffer_header_acquire(buffer);
152 MMAL_BUFFER_HEADER_T *
buffer;
154 mmal_port_disable(decoder->input[0]);
155 mmal_port_disable(decoder->output[0]);
156 mmal_port_disable(decoder->control);
158 mmal_port_flush(decoder->input[0]);
159 mmal_port_flush(decoder->output[0]);
160 mmal_port_flush(decoder->control);
163 mmal_buffer_header_release(buffer);
170 if (buffer->
flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END)
190 mmal_component_destroy(ctx->
decoder);
193 mmal_pool_destroy(ctx->
pool_in);
209 if (entry->
flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END)
213 mmal_buffer_header_release(buffer);
221 mmal_queue_put(
ctx->queue_decoded_frames, buffer);
229 if (buffer->cmd == MMAL_EVENT_ERROR) {
230 status = *(uint32_t *)buffer->data;
237 mmal_buffer_header_release(buffer);
244 MMAL_BUFFER_HEADER_T *
buffer;
250 while ((buffer = mmal_queue_get(ctx->
pool_out->
pool->queue))) {
251 if ((status = mmal_port_send_buffer(ctx->
decoder->output[0], buffer))) {
252 mmal_buffer_header_release(buffer);
253 av_log(avctx,
AV_LOG_ERROR,
"MMAL error %d when sending output buffer.\n", (
int)status);
264 case MMAL_COLOR_SPACE_BT470_2_BG:
265 case MMAL_COLOR_SPACE_BT470_2_M:
280 MMAL_ES_FORMAT_T *format_out = decoder->output[0]->format;
281 MMAL_PARAMETER_VIDEO_INTERLACE_TYPE_T interlace_type;
293 if ((status = mmal_port_parameter_set_uint32(decoder->output[0], MMAL_PARAMETER_EXTRA_BUFFERS, ctx->
extra_buffers)))
296 if ((status = mmal_port_parameter_set_boolean(decoder->output[0], MMAL_PARAMETER_VIDEO_INTERPOLATE_TIMESTAMPS, 0)))
300 format_out->encoding = MMAL_ENCODING_OPAQUE;
302 format_out->encoding_variant = format_out->encoding = MMAL_ENCODING_I420;
305 if ((status = mmal_port_format_commit(decoder->output[0])))
308 interlace_type.hdr.id = MMAL_PARAMETER_VIDEO_INTERLACE_TYPE;
309 interlace_type.hdr.size =
sizeof(MMAL_PARAMETER_VIDEO_INTERLACE_TYPE_T);
310 status = mmal_port_parameter_get(decoder->output[0], &interlace_type.hdr);
311 if (status != MMAL_SUCCESS) {
314 ctx->
interlaced_frame = (interlace_type.eMode != MMAL_InterlaceProgressive);
315 ctx->
top_field_first = (interlace_type.eMode == MMAL_InterlaceFieldsInterleavedUpperFirst);
319 format_out->es->video.crop.y + format_out->es->video.crop.height)) < 0)
322 if (format_out->es->video.par.num && format_out->es->video.par.den) {
326 if (format_out->es->video.frame_rate.num && format_out->es->video.frame_rate.den) {
327 avctx->
framerate.
num = format_out->es->video.frame_rate.num;
328 avctx->
framerate.
den = format_out->es->video.frame_rate.den;
333 decoder->output[0]->buffer_size =
334 FFMAX(decoder->output[0]->buffer_size_min, decoder->output[0]->buffer_size_recommended);
335 decoder->output[0]->buffer_num =
336 FFMAX(decoder->output[0]->buffer_num_min, decoder->output[0]->buffer_num_recommended) + ctx->
extra_buffers;
337 ctx->
pool_out->
pool = mmal_pool_create(decoder->output[0]->buffer_num,
338 decoder->output[0]->buffer_size);
354 MMAL_ES_FORMAT_T *format_in;
360 if (mmal_vc_init()) {
370 if ((status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, &ctx->
decoder)))
375 format_in = decoder->input[0]->format;
376 format_in->type = MMAL_ES_TYPE_VIDEO;
379 format_in->encoding = MMAL_ENCODING_MP2V;
382 format_in->encoding = MMAL_ENCODING_MP4V;
385 format_in->encoding = MMAL_ENCODING_WVC1;
389 format_in->encoding = MMAL_ENCODING_H264;
394 format_in->es->video.crop.width = avctx->
width;
395 format_in->es->video.crop.height = avctx->
height;
396 format_in->es->video.frame_rate.num = 24000;
397 format_in->es->video.frame_rate.den = 1001;
400 format_in->flags = MMAL_ES_FORMAT_FLAG_FRAMED;
405 #if HAVE_MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS 406 if (mmal_port_parameter_set_uint32(decoder->input[0], MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS,
412 if ((status = mmal_port_format_commit(decoder->input[0])))
415 decoder->input[0]->buffer_num =
416 FFMAX(decoder->input[0]->buffer_num_min, 20);
417 decoder->input[0]->buffer_size =
418 FFMAX(decoder->input[0]->buffer_size_min, 512 * 1024);
419 ctx->
pool_in = mmal_pool_create(decoder->input[0]->buffer_num, 0);
432 decoder->input[0]->userdata = (
void*)avctx;
433 decoder->output[0]->userdata = (
void*)avctx;
434 decoder->control->userdata = (
void*)avctx;
438 if ((status = mmal_port_enable(decoder->input[0],
input_callback)))
443 if ((status = mmal_component_enable(decoder)))
463 if ((status = mmal_port_enable(decoder->input[0],
input_callback)))
533 buffer->
flags |= MMAL_BUFFER_HEADER_FLAG_CONFIG;
536 buffer->
flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_START;
545 buffer->
flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_END;
550 buffer->
flags |= MMAL_BUFFER_HEADER_FLAG_EOS;
582 MMAL_BUFFER_HEADER_T *mbuffer;
586 mbuffer = mmal_queue_get(ctx->
pool_in->queue);
592 mmal_buffer_header_reset(mbuffer);
594 mbuffer->pts = buffer->
pts;
595 mbuffer->dts = buffer->
dts;
596 mbuffer->flags = buffer->
flags;
597 mbuffer->data = buffer->
data;
598 mbuffer->length = buffer->
length;
599 mbuffer->user_data =
buffer;
600 mbuffer->alloc_size = ctx->
decoder->input[0]->buffer_size;
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)
625 MMAL_BUFFER_HEADER_T *
buffer)
652 buffer->data + buffer->type->video.offset[0],
711 ctx->
eos_received |= !!(buffer->flags & MMAL_BUFFER_HEADER_FLAG_EOS);
715 if (buffer->cmd == MMAL_EVENT_FORMAT_CHANGED) {
717 MMAL_EVENT_FORMAT_CHANGED_T *ev = mmal_event_format_changed_get(buffer);
718 MMAL_BUFFER_HEADER_T *stale_buffer;
722 if ((status = mmal_port_disable(decoder->output[0])))
726 mmal_buffer_header_release(stale_buffer);
728 mmal_format_copy(decoder->output[0]->format, ev->format);
742 mmal_buffer_header_release(buffer);
744 }
else if (buffer->cmd) {
748 }
else if (buffer->length == 0) {
750 mmal_buffer_header_release(buffer);
765 mmal_buffer_header_release(buffer);
766 if (status && ret >= 0)
819 {
"extra_decoder_buffers",
"extra MMAL internal buffered frames", offsetof(
MMALDecodeContext, extra_decoder_buffers),
AV_OPT_TYPE_INT, {.i64 = 10}, 0, 256, 0},
823 #define FFMMAL_DEC_CLASS(NAME) \ 824 static const AVClass ffmmal_##NAME##_dec_class = { \ 825 .class_name = "mmal_" #NAME "_dec", \ 826 .item_name = av_default_item_name, \ 828 .version = LIBAVUTIL_VERSION_INT, \ 831 #define FFMMAL_DEC(NAME, ID) \ 832 FFMMAL_DEC_CLASS(NAME) \ 833 AVCodec ff_##NAME##_mmal_decoder = { \ 834 .name = #NAME "_mmal", \ 835 .long_name = NULL_IF_CONFIG_SMALL(#NAME " (mmal)"), \ 836 .type = AVMEDIA_TYPE_VIDEO, \ 838 .priv_data_size = sizeof(MMALDecodeContext), \ 839 .init = ffmmal_init_decoder, \ 840 .close = ffmmal_close_decoder, \ 841 .decode = ffmmal_decode, \ 842 .flush = ffmmal_flush, \ 843 .priv_class = &ffmmal_##NAME##_dec_class, \ 844 .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE, \ 845 .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS, \ 846 .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_MMAL, \ 847 AV_PIX_FMT_YUV420P, \ 849 .hw_configs = mmal_hw_configs, \ 850 .wrapper_name = "mmal", \ also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
Select the (possibly hardware accelerated) pixel format.
const struct AVCodec * codec
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it...
This structure describes decoded (raw) audio or video data.
#define FFMMAL_DEC(NAME, ID)
ptrdiff_t const GLvoid * data
#define AV_LOG_WARNING
Something somehow does not look correct.
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
atomic_int packets_buffered
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 ...
int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4], const uint8_t *src, enum AVPixelFormat pix_fmt, int width, int height, int align)
Setup the data pointers and linesizes based on the specified image parameters and the provided array...
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown) That is the width of a pixel divided by the height of the pixel...
static const AVCodecHWConfigInternal *const mmal_hw_configs[]
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
static int ffmmal_fill_output_port(AVCodecContext *avctx)
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
Set various frame properties from the codec context / packet data.
#define HW_CONFIG_INTERNAL(format)
static int ffmmal_fill_input_port(AVCodecContext *avctx)
static int ffmmal_decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
functionally identical to above
#define av_assert0(cond)
assert() equivalent, that is always enabled.
MMAL_BUFFER_HEADER_T * buffer
AVColorSpace
YUV colorspace type.
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
static void ffmmal_flush(AVCodecContext *avctx)
static av_cold int ffmmal_init_decoder(AVCodecContext *avctx)
static const AVOption options[]
static av_cold int ffmmal_close_decoder(AVCodecContext *avctx)
int interlaced_frame
The content of the picture is interlaced.
#define AV_BUFFER_FLAG_READONLY
Always treat the buffer as read-only, even when it has only one reference.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static void output_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
#define atomic_load(object)
static void ffmmal_poolref_unref(FFPoolRef *ref)
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define av_fourcc2str(fourcc)
AVBufferRef * buf
A reference to the reference-counted buffer where the packet data is stored.
simple assert() macros that are a bit more flexible than ISO C assert().
static int ffmmal_set_ref(AVFrame *frame, FFPoolRef *pool, MMAL_BUFFER_HEADER_T *buffer)
FFBufferEntry * waiting_buffers_tail
AVBufferRef * av_buffer_create(uint8_t *data, int size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
int extra_decoder_buffers
static void control_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], const uint8_t *src_data[4], const int src_linesizes[4], enum AVPixelFormat pix_fmt, int width, int height)
Copy image in src_data to dst_data.
static int ffmal_copy_frame(AVCodecContext *avctx, AVFrame *frame, MMAL_BUFFER_HEADER_T *buffer)
static enum AVColorSpace ffmmal_csp_to_av_csp(MMAL_FOURCC_T fourcc)
enum AVPixelFormat * pix_fmts
array of supported pixel formats, or NULL if unknown, array is terminated by -1
FFBufferEntry * waiting_buffers
static const chunk_decoder decoder[8]
int width
picture width / height.
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
#define MAX_DELAYED_FRAMES
preferred ID for MPEG-1/2 video decoding
FCC Title 47 Code of Federal Regulations 73.682 (a)(20)
static void ffmmal_stop_decoder(AVCodecContext *avctx)
MMAL_QUEUE_T * queue_decoded_frames
#define atomic_fetch_add_explicit(object, operand, order)
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
#define atomic_fetch_add(object, operand)
#define AV_LOG_INFO
Standard information.
struct FFBufferEntry * next
Libavcodec external API header.
AVBufferRef * av_buffer_alloc(int size)
Allocate an AVBuffer of the given size using av_malloc().
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
main external API structure.
uint8_t * data
The data buffer.
static void input_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Describe the class of an AVClass context structure.
enum AVColorSpace colorspace
YUV colorspace type.
they must not be accessed directly The fifo field contains the frames that are queued in the input for processing by the filter The status_in and status_out fields contains the queued status(EOF or error) of the link
refcounted data buffer API
int size
Size of data in bytes.
static int ffmmal_read_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame)
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
attribute_deprecated int64_t pkt_pts
PTS copied from the AVPacket that was decoded to produce this frame.
int64_t pkt_dts
DTS copied from the AVPacket that triggered returning this frame.
A reference to a data buffer.
#define FF_DISABLE_DEPRECATION_WARNINGS
common internal api header.
common internal and external API header
static int ffmal_update_format(AVCodecContext *avctx)
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
void av_init_packet(AVPacket *pkt)
Initialize optional fields of a packet with default values.
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
static void ffmmal_release_frame(void *opaque, uint8_t *data)
#define FF_ENABLE_DEPRECATION_WARNINGS
int top_field_first
If the content is interlaced, is top field displayed first.
static int ffmmal_add_packet(AVCodecContext *avctx, AVPacket *avpkt, int is_extradata)
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed...
#define atomic_init(obj, value)
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
HW acceleration though MMAL, data[3] contains a pointer to the MMAL_BUFFER_HEADER_T structure...
This structure stores compressed data.
MMAL_COMPONENT_T * decoder
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
#define AV_NOPTS_VALUE
Undefined timestamp value.