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> 
   98 #define MAX_DELAYED_FRAMES 16 
  104         mmal_pool_destroy(ref->
pool);
 
  113     mmal_buffer_header_release(ref->
buffer);
 
  122                           MMAL_BUFFER_HEADER_T *
buffer)
 
  134     if (!frame->
buf[0]) {
 
  140     mmal_buffer_header_acquire(buffer);
 
  151     MMAL_BUFFER_HEADER_T *
buffer;
 
  153     mmal_port_disable(decoder->input[0]);
 
  154     mmal_port_disable(decoder->output[0]);
 
  155     mmal_port_disable(decoder->control);
 
  157     mmal_port_flush(decoder->input[0]);
 
  158     mmal_port_flush(decoder->output[0]);
 
  159     mmal_port_flush(decoder->control);
 
  162         mmal_buffer_header_release(buffer);
 
  169         if (buffer->
flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END)
 
  189     mmal_component_destroy(ctx->
decoder);
 
  192     mmal_pool_destroy(ctx->
pool_in);
 
  208         if (entry->
flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END)
 
  212     mmal_buffer_header_release(buffer);
 
  220     mmal_queue_put(
ctx->queue_decoded_frames, buffer);
 
  226     MMAL_STATUS_T status;
 
  228     if (buffer->cmd == MMAL_EVENT_ERROR) {
 
  229         status = *(uint32_t *)buffer->data;
 
  236     mmal_buffer_header_release(buffer);
 
  243     MMAL_BUFFER_HEADER_T *
buffer;
 
  244     MMAL_STATUS_T status;
 
  249     while ((buffer = mmal_queue_get(ctx->
pool_out->
pool->queue))) {
 
  250         if ((status = mmal_port_send_buffer(ctx->
decoder->output[0], buffer))) {
 
  251             mmal_buffer_header_release(buffer);
 
  252             av_log(avctx, 
AV_LOG_ERROR, 
"MMAL error %d when sending output buffer.\n", (
int)status);
 
  263     case MMAL_COLOR_SPACE_BT470_2_BG:
 
  264     case MMAL_COLOR_SPACE_BT470_2_M:
 
  276     MMAL_STATUS_T status;
 
  279     MMAL_ES_FORMAT_T *format_out = decoder->output[0]->format;
 
  280     MMAL_PARAMETER_VIDEO_INTERLACE_TYPE_T interlace_type;
 
  292     if ((status = mmal_port_parameter_set_uint32(decoder->output[0], MMAL_PARAMETER_EXTRA_BUFFERS, ctx->
extra_buffers)))
 
  295     if ((status = mmal_port_parameter_set_boolean(decoder->output[0], MMAL_PARAMETER_VIDEO_INTERPOLATE_TIMESTAMPS, 0)))
 
  299         format_out->encoding = MMAL_ENCODING_OPAQUE;
 
  301         format_out->encoding_variant = format_out->encoding = MMAL_ENCODING_I420;
 
  304     if ((status = mmal_port_format_commit(decoder->output[0])))
 
  307     interlace_type.hdr.id = MMAL_PARAMETER_VIDEO_INTERLACE_TYPE;
 
  308     interlace_type.hdr.size = 
sizeof(MMAL_PARAMETER_VIDEO_INTERLACE_TYPE_T);
 
  309     status = mmal_port_parameter_get(decoder->output[0], &interlace_type.hdr);
 
  310     if (status != MMAL_SUCCESS) {
 
  313         ctx->
interlaced_frame = (interlace_type.eMode != MMAL_InterlaceProgressive);
 
  314         ctx->
top_field_first = (interlace_type.eMode == MMAL_InterlaceFieldsInterleavedUpperFirst);
 
  318                                         format_out->es->video.crop.y + format_out->es->video.crop.height)) < 0)
 
  321     if (format_out->es->video.par.num && format_out->es->video.par.den) {
 
  325     if (format_out->es->video.frame_rate.num && format_out->es->video.frame_rate.den) {
 
  326         avctx->
framerate.
num = format_out->es->video.frame_rate.num;
 
  327         avctx->
framerate.
den = format_out->es->video.frame_rate.den;
 
  332     decoder->output[0]->buffer_size =
 
  333         FFMAX(decoder->output[0]->buffer_size_min, decoder->output[0]->buffer_size_recommended);
 
  334     decoder->output[0]->buffer_num =
 
  335         FFMAX(decoder->output[0]->buffer_num_min, decoder->output[0]->buffer_num_recommended) + ctx->
extra_buffers;
 
  336     ctx->
pool_out->
pool = mmal_pool_create(decoder->output[0]->buffer_num,
 
  337                                            decoder->output[0]->buffer_size);
 
  352     MMAL_STATUS_T status;
 
  353     MMAL_ES_FORMAT_T *format_in;
 
  359     if (mmal_vc_init()) {
 
  369     if ((status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, &ctx->
decoder)))
 
  374     format_in = decoder->input[0]->format;
 
  375     format_in->type = MMAL_ES_TYPE_VIDEO;
 
  378         format_in->encoding = MMAL_ENCODING_MP2V;
 
  381         format_in->encoding = MMAL_ENCODING_MP4V;
 
  384         format_in->encoding = MMAL_ENCODING_WVC1;
 
  388         format_in->encoding = MMAL_ENCODING_H264;
 
  393     format_in->es->video.crop.width = avctx->
width;
 
  394     format_in->es->video.crop.height = avctx->
height;
 
  395     format_in->es->video.frame_rate.num = 24000;
 
  396     format_in->es->video.frame_rate.den = 1001;
 
  399     format_in->flags = MMAL_ES_FORMAT_FLAG_FRAMED;
 
  404 #if HAVE_MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS 
  405     if (mmal_port_parameter_set_uint32(decoder->input[0], MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS,
 
  411     if ((status = mmal_port_format_commit(decoder->input[0])))
 
  414     decoder->input[0]->buffer_num =
 
  415         FFMAX(decoder->input[0]->buffer_num_min, 20);
 
  416     decoder->input[0]->buffer_size =
 
  417         FFMAX(decoder->input[0]->buffer_size_min, 512 * 1024);
 
  418     ctx->
pool_in = mmal_pool_create(decoder->input[0]->buffer_num, 0);
 
  431     decoder->input[0]->userdata = (
void*)avctx;
 
  432     decoder->output[0]->userdata = (
void*)avctx;
 
  433     decoder->control->userdata = (
void*)avctx;
 
  437     if ((status = mmal_port_enable(decoder->input[0], 
input_callback)))
 
  442     if ((status = mmal_component_enable(decoder)))
 
  456     MMAL_STATUS_T status;
 
  462     if ((status = mmal_port_enable(decoder->input[0], 
input_callback)))
 
  532             buffer->
flags |= MMAL_BUFFER_HEADER_FLAG_CONFIG;
 
  535             buffer->
flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_START;
 
  544             buffer->
flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_END;
 
  549             buffer->
flags |= MMAL_BUFFER_HEADER_FLAG_EOS;
 
  581         MMAL_BUFFER_HEADER_T *mbuffer;
 
  583         MMAL_STATUS_T status;
 
  585         mbuffer = mmal_queue_get(ctx->
pool_in->queue);
 
  591         mmal_buffer_header_reset(mbuffer);
 
  593         mbuffer->pts = buffer->
pts;
 
  594         mbuffer->dts = buffer->
dts;
 
  595         mbuffer->flags = buffer->
flags;
 
  596         mbuffer->data = buffer->
data;
 
  597         mbuffer->length = buffer->
length;
 
  598         mbuffer->user_data = 
buffer;
 
  599         mbuffer->alloc_size = ctx->
decoder->input[0]->buffer_size;
 
  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)
 
  624                             MMAL_BUFFER_HEADER_T *
buffer)
 
  651                              buffer->data + buffer->type->video.offset[0],
 
  674     MMAL_STATUS_T status = 0;
 
  710         ctx->
eos_received |= !!(buffer->flags & MMAL_BUFFER_HEADER_FLAG_EOS);
 
  714         if (buffer->cmd == MMAL_EVENT_FORMAT_CHANGED) {
 
  716             MMAL_EVENT_FORMAT_CHANGED_T *ev = mmal_event_format_changed_get(buffer);
 
  717             MMAL_BUFFER_HEADER_T *stale_buffer;
 
  721             if ((status = mmal_port_disable(decoder->output[0])))
 
  725                 mmal_buffer_header_release(stale_buffer);
 
  727             mmal_format_copy(decoder->output[0]->format, ev->format);
 
  741             mmal_buffer_header_release(buffer);
 
  743         } 
else if (buffer->cmd) {
 
  747         } 
else if (buffer->length == 0) {
 
  749             mmal_buffer_header_release(buffer);
 
  764         mmal_buffer_header_release(buffer);
 
  765     if (status && ret >= 0)
 
  818     {
"extra_decoder_buffers", 
"extra MMAL internal buffered frames", offsetof(
MMALDecodeContext, extra_decoder_buffers), 
AV_OPT_TYPE_INT, {.i64 = 10}, 0, 256, 0},
 
  822 #define FFMMAL_DEC_CLASS(NAME) \ 
  823     static const AVClass ffmmal_##NAME##_dec_class = { \ 
  824         .class_name = "mmal_" #NAME "_dec", \ 
  825         .item_name  = av_default_item_name, \ 
  827         .version    = LIBAVUTIL_VERSION_INT, \ 
  830 #define FFMMAL_DEC(NAME, ID) \ 
  831     FFMMAL_DEC_CLASS(NAME) \ 
  832     AVCodec ff_##NAME##_mmal_decoder = { \ 
  833         .name           = #NAME "_mmal", \ 
  834         .long_name      = NULL_IF_CONFIG_SMALL(#NAME " (mmal)"), \ 
  835         .type           = AVMEDIA_TYPE_VIDEO, \ 
  837         .priv_data_size = sizeof(MMALDecodeContext), \ 
  838         .init           = ffmmal_init_decoder, \ 
  839         .close          = ffmmal_close_decoder, \ 
  840         .decode         = ffmmal_decode, \ 
  841         .flush          = ffmmal_flush, \ 
  842         .priv_class     = &ffmmal_##NAME##_dec_class, \ 
  843         .capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE, \ 
  844         .caps_internal  = FF_CODEC_CAP_SETS_PKT_DTS, \ 
  845         .pix_fmts       = (const enum AVPixelFormat[]) { AV_PIX_FMT_MMAL, \ 
  846                                                          AV_PIX_FMT_YUV420P, \ 
  848         .hw_configs     = mmal_hw_configs, \ 
  849         .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...
 
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. 
 
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)
 
#define HW_CONFIG_INTERNAL(format)
 
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. 
 
#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. 
 
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 ref[MAX_W *MAX_W]
 
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)
 
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. 
 
static const AVCodecHWConfigInternal * mmal_hw_configs[]