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>
94 #define MAX_DELAYED_FRAMES 16
99 mmal_pool_destroy(ref->
pool);
108 mmal_buffer_header_release(ref->
buffer);
117 MMAL_BUFFER_HEADER_T *
buffer)
129 if (!frame->
buf[0]) {
135 mmal_buffer_header_acquire(buffer);
146 MMAL_BUFFER_HEADER_T *
buffer;
148 mmal_port_disable(decoder->input[0]);
149 mmal_port_disable(decoder->output[0]);
150 mmal_port_disable(decoder->control);
152 mmal_port_flush(decoder->input[0]);
153 mmal_port_flush(decoder->output[0]);
154 mmal_port_flush(decoder->control);
157 mmal_buffer_header_release(buffer);
164 if (buffer->
flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END)
184 mmal_component_destroy(ctx->
decoder);
187 mmal_pool_destroy(ctx->
pool_in);
203 if (entry->
flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END)
207 mmal_buffer_header_release(buffer);
215 mmal_queue_put(
ctx->queue_decoded_frames, buffer);
221 MMAL_STATUS_T status;
223 if (buffer->cmd == MMAL_EVENT_ERROR) {
224 status = *(uint32_t *)buffer->data;
232 mmal_buffer_header_release(buffer);
239 MMAL_BUFFER_HEADER_T *
buffer;
240 MMAL_STATUS_T status;
245 while ((buffer = mmal_queue_get(ctx->
pool_out->
pool->queue))) {
246 if ((status = mmal_port_send_buffer(ctx->
decoder->output[0], buffer))) {
247 mmal_buffer_header_release(buffer);
248 av_log(avctx,
AV_LOG_ERROR,
"MMAL error %d when sending output buffer.\n", (
int)status);
259 case MMAL_COLOR_SPACE_BT470_2_BG:
260 case MMAL_COLOR_SPACE_BT470_2_M:
272 MMAL_STATUS_T status;
275 MMAL_ES_FORMAT_T *format_out = decoder->output[0]->format;
287 if ((status = mmal_port_parameter_set_uint32(decoder->output[0], MMAL_PARAMETER_EXTRA_BUFFERS, ctx->
extra_buffers)))
290 if ((status = mmal_port_parameter_set_boolean(decoder->output[0], MMAL_PARAMETER_VIDEO_INTERPOLATE_TIMESTAMPS, 0)))
294 format_out->encoding = MMAL_ENCODING_OPAQUE;
296 format_out->encoding_variant = format_out->encoding = MMAL_ENCODING_I420;
299 if ((status = mmal_port_format_commit(decoder->output[0])))
303 format_out->es->video.crop.y + format_out->es->video.crop.height)) < 0)
306 if (format_out->es->video.par.num && format_out->es->video.par.den) {
313 decoder->output[0]->buffer_size =
314 FFMAX(decoder->output[0]->buffer_size_min, decoder->output[0]->buffer_size_recommended);
315 decoder->output[0]->buffer_num =
316 FFMAX(decoder->output[0]->buffer_num_min, decoder->output[0]->buffer_num_recommended) + ctx->
extra_buffers;
317 ctx->
pool_out->
pool = mmal_pool_create(decoder->output[0]->buffer_num,
318 decoder->output[0]->buffer_size);
333 MMAL_STATUS_T status;
334 MMAL_ES_FORMAT_T *format_in;
341 if (mmal_vc_init()) {
351 if ((status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, &ctx->
decoder)))
356 format_in = decoder->input[0]->format;
357 format_in->type = MMAL_ES_TYPE_VIDEO;
360 format_in->encoding = MMAL_ENCODING_MP2V;
363 format_in->encoding = MMAL_ENCODING_MP4V;
366 format_in->encoding = MMAL_ENCODING_WVC1;
370 format_in->encoding = MMAL_ENCODING_H264;
375 format_in->es->video.crop.width = avctx->
width;
376 format_in->es->video.crop.height = avctx->
height;
377 format_in->es->video.frame_rate.num = 24000;
378 format_in->es->video.frame_rate.den = 1001;
381 format_in->flags = MMAL_ES_FORMAT_FLAG_FRAMED;
386 if (mmal_port_parameter_set_uint32(decoder->input[0], MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS,
391 if ((status = mmal_port_format_commit(decoder->input[0])))
394 decoder->input[0]->buffer_num =
395 FFMAX(decoder->input[0]->buffer_num_min, 20);
396 decoder->input[0]->buffer_size =
397 FFMAX(decoder->input[0]->buffer_size_min, 512 * 1024);
398 ctx->
pool_in = mmal_pool_create(decoder->input[0]->buffer_num, 0);
411 decoder->input[0]->userdata = (
void*)avctx;
412 decoder->output[0]->userdata = (
void*)avctx;
413 decoder->control->userdata = (
void*)avctx;
417 if ((status = mmal_port_enable(decoder->input[0],
input_callback)))
422 if ((status = mmal_component_enable(decoder)))
436 MMAL_STATUS_T status;
442 if ((status = mmal_port_enable(decoder->input[0],
input_callback)))
512 buffer->
flags |= MMAL_BUFFER_HEADER_FLAG_CONFIG;
515 buffer->
flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_START;
524 buffer->
flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_END;
529 buffer->
flags |= MMAL_BUFFER_HEADER_FLAG_EOS;
561 MMAL_BUFFER_HEADER_T *mbuffer;
563 MMAL_STATUS_T status;
565 mbuffer = mmal_queue_get(ctx->
pool_in->queue);
571 mmal_buffer_header_reset(mbuffer);
573 mbuffer->pts = buffer->
pts;
574 mbuffer->dts = buffer->
dts;
575 mbuffer->flags = buffer->
flags;
576 mbuffer->data = buffer->
data;
577 mbuffer->length = buffer->
length;
578 mbuffer->user_data =
buffer;
579 mbuffer->alloc_size = ctx->
decoder->input[0]->buffer_size;
586 if ((status = mmal_port_send_buffer(ctx->
decoder->input[0], mbuffer))) {
587 mmal_buffer_header_release(mbuffer);
589 if (buffer->
flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END)
604 MMAL_BUFFER_HEADER_T *
buffer)
628 ptr = buffer->data + buffer->type->video.offset[0];
629 for (i = 0; i < avctx->
height; i++)
634 for (plane = 1; plane < 3; plane++) {
635 for (i = 0; i < avctx->
height / 2; i++)
636 memcpy(frame->
data[plane] + frame->
linesize[plane] * i, ptr + w / 2 * i, (avctx->
width + 1) / 2);
637 ptr += w / 2 * h / 2;
653 MMAL_STATUS_T status = 0;
689 ctx->
eos_received |= !!(buffer->flags & MMAL_BUFFER_HEADER_FLAG_EOS);
693 if (buffer->cmd == MMAL_EVENT_FORMAT_CHANGED) {
695 MMAL_EVENT_FORMAT_CHANGED_T *ev = mmal_event_format_changed_get(buffer);
696 MMAL_BUFFER_HEADER_T *stale_buffer;
700 if ((status = mmal_port_disable(decoder->output[0])))
704 mmal_buffer_header_release(stale_buffer);
706 mmal_format_copy(decoder->output[0]->format, ev->format);
720 mmal_buffer_header_release(buffer);
722 }
else if (buffer->cmd) {
727 }
else if (buffer->length == 0) {
729 mmal_buffer_header_release(buffer);
744 mmal_buffer_header_release(buffer);
745 if (status && ret >= 0)
799 .
name =
"mpeg2_mmal",
806 .
name =
"mpeg4_mmal",
821 {
"extra_decoder_buffers",
"extra MMAL internal buffered frames", offsetof(
MMALDecodeContext, extra_decoder_buffers),
AV_OPT_TYPE_INT, {.i64 = 10}, 0, 256, 0},
825 #define FFMMAL_DEC_CLASS(NAME) \
826 static const AVClass ffmmal_##NAME##_dec_class = { \
827 .class_name = "mmal_" #NAME "_dec", \
829 .version = LIBAVUTIL_VERSION_INT, \
832 #define FFMMAL_DEC(NAME, ID) \
833 FFMMAL_DEC_CLASS(NAME) \
834 AVCodec ff_##NAME##_mmal_decoder = { \
835 .name = #NAME "_mmal", \
836 .long_name = NULL_IF_CONFIG_SMALL(#NAME " (mmal)"), \
837 .type = AVMEDIA_TYPE_VIDEO, \
839 .priv_data_size = sizeof(MMALDecodeContext), \
840 .init = ffmmal_init_decoder, \
841 .close = ffmmal_close_decoder, \
842 .decode = ffmmal_decode, \
843 .flush = ffmmal_flush, \
844 .priv_class = &ffmmal_##NAME##_dec_class, \
845 .capabilities = AV_CODEC_CAP_DELAY, \
846 .caps_internal = FF_CODEC_CAP_SETS_PKT_DTS, \
847 .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_MMAL, \
848 AV_PIX_FMT_YUV420P, \
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
const struct AVCodec * codec
#define avpriv_atomic_int_add_and_fetch
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.
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 ...
AVHWAccel ff_h264_mmal_hwaccel
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)
size_t av_get_codec_tag_string(char *buf, size_t buf_size, unsigned int codec_tag)
Put a string representing the codec tag codec_tag in buf.
static int ffmmal_fill_input_port(AVCodecContext *avctx)
static int ffmmal_decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
#define av_assert0(cond)
assert() equivalent, that is always enabled.
MMAL_BUFFER_HEADER_T * buffer
AVColorSpace
YUV colorspace type.
int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
Set various frame properties from the codec context / packet data.
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)
#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 avpriv_atomic_int_get
static void ffmmal_poolref_unref(FFPoolRef *ref)
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
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)
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
const char * name
Name of the hardware accelerated codec.
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
int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
Select the (possibly hardware accelerated) pixel format.
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
AVHWAccel ff_mpeg2_mmal_hwaccel
#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.
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
static void input_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
AVHWAccel ff_vc1_mmal_hwaccel
Describe the class of an AVClass context structure.
enum AVColorSpace colorspace
YUV colorspace type.
refcounted data buffer API
int64_t pkt_pts
PTS copied from the AVPacket that was decoded to produce this frame.
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.
AVHWAccel ff_mpeg4_mmal_hwaccel
int64_t pkt_dts
DTS copied from the AVPacket that triggered returning this frame.
A reference to a data buffer.
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)
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...
volatile int packets_buffered
HW acceleration though MMAL, data[3] contains a pointer to the MMAL_BUFFER_HEADER_T structure...
This structure stores compressed data.
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
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.