FFmpeg
mmaldec.c
Go to the documentation of this file.
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 
36 #include "avcodec.h"
37 #include "codec_internal.h"
38 #include "decode.h"
39 #include "hwconfig.h"
40 #include "internal.h"
41 #include "libavutil/avassert.h"
42 #include "libavutil/buffer.h"
43 #include "libavutil/common.h"
44 #include "libavutil/imgutils.h"
45 #include "libavutil/opt.h"
46 #include "libavutil/log.h"
47 
48 typedef struct FFBufferEntry {
50  void *data;
51  size_t length;
52  int64_t pts, dts;
53  int flags;
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.
60 typedef struct FFPoolRef {
62  MMAL_POOL_T *pool;
63 } FFPoolRef;
64 
65 typedef struct FFBufferRef {
66  MMAL_BUFFER_HEADER_T *buffer;
68 } FFBufferRef;
69 
70 typedef struct MMALDecodeContext {
74 
75  MMAL_COMPONENT_T *decoder;
76  MMAL_QUEUE_T *queue_decoded_frames;
77  MMAL_POOL_T *pool_in;
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 
90  int64_t packets_sent;
92  int64_t frames_output;
94  int eos_sent;
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 
105 {
106  if (ref &&
107  atomic_fetch_add_explicit(&ref->refcount, -1, memory_order_acq_rel) == 1) {
108  mmal_pool_destroy(ref->pool);
109  av_free(ref);
110  }
111 }
112 
113 static void ffmmal_release_frame(void *opaque, uint8_t *data)
114 {
115  FFBufferRef *ref = (void *)data;
116 
117  mmal_buffer_header_release(ref->buffer);
118  ffmmal_poolref_unref(ref->pool);
119 
120  av_free(ref);
121 }
122 
123 // Setup frame with a new reference to buffer. The buffer must have been
124 // allocated from the given pool.
126  MMAL_BUFFER_HEADER_T *buffer)
127 {
128  FFBufferRef *ref = av_mallocz(sizeof(*ref));
129  if (!ref)
130  return AVERROR(ENOMEM);
131 
132  ref->pool = pool;
133  ref->buffer = buffer;
134 
135  frame->buf[0] = av_buffer_create((void *)ref, sizeof(*ref),
138  if (!frame->buf[0]) {
139  av_free(ref);
140  return AVERROR(ENOMEM);
141  }
142 
143  atomic_fetch_add_explicit(&ref->pool->refcount, 1, memory_order_relaxed);
144  mmal_buffer_header_acquire(buffer);
145 
147  frame->data[3] = (uint8_t *)ref->buffer;
148  return 0;
149 }
150 
152 {
153  MMALDecodeContext *ctx = avctx->priv_data;
154  MMAL_COMPONENT_T *decoder = ctx->decoder;
155  MMAL_BUFFER_HEADER_T *buffer;
156 
157  mmal_port_disable(decoder->input[0]);
158  mmal_port_disable(decoder->output[0]);
159  mmal_port_disable(decoder->control);
160 
161  mmal_port_flush(decoder->input[0]);
162  mmal_port_flush(decoder->output[0]);
163  mmal_port_flush(decoder->control);
164 
165  while ((buffer = mmal_queue_get(ctx->queue_decoded_frames)))
166  mmal_buffer_header_release(buffer);
167 
168  while (ctx->waiting_buffers) {
169  FFBufferEntry *buffer = ctx->waiting_buffers;
170 
171  ctx->waiting_buffers = buffer->next;
172 
173  if (buffer->flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END)
174  atomic_fetch_add(&ctx->packets_buffered, -1);
175 
176  av_buffer_unref(&buffer->ref);
177  av_free(buffer);
178  }
179  ctx->waiting_buffers_tail = NULL;
180 
181  av_assert0(atomic_load(&ctx->packets_buffered) == 0);
182 
183  ctx->frames_output = ctx->eos_received = ctx->eos_sent = ctx->packets_sent = ctx->extradata_sent = 0;
184 }
185 
187 {
188  MMALDecodeContext *ctx = avctx->priv_data;
189 
190  if (ctx->decoder)
191  ffmmal_stop_decoder(avctx);
192 
193  mmal_component_destroy(ctx->decoder);
194  ctx->decoder = NULL;
195  mmal_queue_destroy(ctx->queue_decoded_frames);
196  mmal_pool_destroy(ctx->pool_in);
197  ffmmal_poolref_unref(ctx->pool_out);
198 
199  mmal_vc_deinit();
200 
201  return 0;
202 }
203 
204 static void input_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
205 {
206  AVCodecContext *avctx = (AVCodecContext*)port->userdata;
207  MMALDecodeContext *ctx = avctx->priv_data;
208 
209  if (!buffer->cmd) {
210  FFBufferEntry *entry = buffer->user_data;
211  av_buffer_unref(&entry->ref);
212  if (entry->flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END)
213  atomic_fetch_add(&ctx->packets_buffered, -1);
214  av_free(entry);
215  }
216  mmal_buffer_header_release(buffer);
217 }
218 
219 static void output_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
220 {
221  AVCodecContext *avctx = (AVCodecContext*)port->userdata;
222  MMALDecodeContext *ctx = avctx->priv_data;
223 
224  mmal_queue_put(ctx->queue_decoded_frames, buffer);
225 }
226 
227 static void control_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
228 {
229  AVCodecContext *avctx = (AVCodecContext*)port->userdata;
230  MMAL_STATUS_T status;
231 
232  if (buffer->cmd == MMAL_EVENT_ERROR) {
233  status = *(uint32_t *)buffer->data;
234  av_log(avctx, AV_LOG_ERROR, "MMAL error %d on control port\n", (int)status);
235  } else {
236  av_log(avctx, AV_LOG_WARNING, "Unknown MMAL event %s on control port\n",
237  av_fourcc2str(buffer->cmd));
238  }
239 
240  mmal_buffer_header_release(buffer);
241 }
242 
243 // Feed free output buffers to the decoder.
245 {
246  MMALDecodeContext *ctx = avctx->priv_data;
247  MMAL_BUFFER_HEADER_T *buffer;
248  MMAL_STATUS_T status;
249 
250  if (!ctx->pool_out)
251  return AVERROR_UNKNOWN; // format change code failed with OOM previously
252 
253  while ((buffer = mmal_queue_get(ctx->pool_out->pool->queue))) {
254  if ((status = mmal_port_send_buffer(ctx->decoder->output[0], buffer))) {
255  mmal_buffer_header_release(buffer);
256  av_log(avctx, AV_LOG_ERROR, "MMAL error %d when sending output buffer.\n", (int)status);
257  return AVERROR_UNKNOWN;
258  }
259  }
260 
261  return 0;
262 }
263 
264 static enum AVColorSpace ffmmal_csp_to_av_csp(MMAL_FOURCC_T fourcc)
265 {
266  switch (fourcc) {
267  case MMAL_COLOR_SPACE_BT470_2_BG:
268  case MMAL_COLOR_SPACE_BT470_2_M:
269  case MMAL_COLOR_SPACE_ITUR_BT601: return AVCOL_SPC_BT470BG;
270  case MMAL_COLOR_SPACE_ITUR_BT709: return AVCOL_SPC_BT709;
271  case MMAL_COLOR_SPACE_FCC: return AVCOL_SPC_FCC;
272  case MMAL_COLOR_SPACE_SMPTE240M: return AVCOL_SPC_SMPTE240M;
273  default: return AVCOL_SPC_UNSPECIFIED;
274  }
275 }
276 
278 {
279  MMALDecodeContext *ctx = avctx->priv_data;
280  MMAL_STATUS_T status;
281  int ret = 0;
282  MMAL_COMPONENT_T *decoder = ctx->decoder;
283  MMAL_ES_FORMAT_T *format_out = decoder->output[0]->format;
284  MMAL_PARAMETER_VIDEO_INTERLACE_TYPE_T interlace_type;
285 
286  ffmmal_poolref_unref(ctx->pool_out);
287  if (!(ctx->pool_out = av_mallocz(sizeof(*ctx->pool_out)))) {
288  ret = AVERROR(ENOMEM);
289  goto fail;
290  }
291  atomic_init(&ctx->pool_out->refcount, 1);
292 
293  if (!format_out)
294  goto fail;
295 
296  if ((status = mmal_port_parameter_set_uint32(decoder->output[0], MMAL_PARAMETER_EXTRA_BUFFERS, ctx->extra_buffers)))
297  goto fail;
298 
299  if ((status = mmal_port_parameter_set_boolean(decoder->output[0], MMAL_PARAMETER_VIDEO_INTERPOLATE_TIMESTAMPS, 0)))
300  goto fail;
301 
302  if (avctx->pix_fmt == AV_PIX_FMT_MMAL) {
303  format_out->encoding = MMAL_ENCODING_OPAQUE;
304  } else {
305  format_out->encoding_variant = format_out->encoding = MMAL_ENCODING_I420;
306  }
307 
308  if ((status = mmal_port_format_commit(decoder->output[0])))
309  goto fail;
310 
311  interlace_type.hdr.id = MMAL_PARAMETER_VIDEO_INTERLACE_TYPE;
312  interlace_type.hdr.size = sizeof(MMAL_PARAMETER_VIDEO_INTERLACE_TYPE_T);
313  status = mmal_port_parameter_get(decoder->output[0], &interlace_type.hdr);
314  if (status != MMAL_SUCCESS) {
315  av_log(avctx, AV_LOG_ERROR, "Cannot read MMAL interlace information!\n");
316  } else {
317  ctx->interlaced_frame = (interlace_type.eMode != MMAL_InterlaceProgressive);
318  ctx->top_field_first = (interlace_type.eMode == MMAL_InterlaceFieldsInterleavedUpperFirst);
319  }
320 
321  if ((ret = ff_set_dimensions(avctx, format_out->es->video.crop.x + format_out->es->video.crop.width,
322  format_out->es->video.crop.y + format_out->es->video.crop.height)) < 0)
323  goto fail;
324 
325  if (format_out->es->video.par.num && format_out->es->video.par.den) {
326  avctx->sample_aspect_ratio.num = format_out->es->video.par.num;
327  avctx->sample_aspect_ratio.den = format_out->es->video.par.den;
328  }
329  if (format_out->es->video.frame_rate.num && format_out->es->video.frame_rate.den) {
330  avctx->framerate.num = format_out->es->video.frame_rate.num;
331  avctx->framerate.den = format_out->es->video.frame_rate.den;
332  }
333 
334  avctx->colorspace = ffmmal_csp_to_av_csp(format_out->es->video.color_space);
335 
336  decoder->output[0]->buffer_size =
337  FFMAX(decoder->output[0]->buffer_size_min, decoder->output[0]->buffer_size_recommended);
338  decoder->output[0]->buffer_num =
339  FFMAX(decoder->output[0]->buffer_num_min, decoder->output[0]->buffer_num_recommended) + ctx->extra_buffers;
340  ctx->pool_out->pool = mmal_pool_create(decoder->output[0]->buffer_num,
341  decoder->output[0]->buffer_size);
342  if (!ctx->pool_out->pool) {
343  ret = AVERROR(ENOMEM);
344  goto fail;
345  }
346 
347  return 0;
348 
349 fail:
350  return ret < 0 ? ret : AVERROR_UNKNOWN;
351 }
352 
354 {
355  MMALDecodeContext *ctx = avctx->priv_data;
356  MMAL_STATUS_T status;
357  MMAL_ES_FORMAT_T *format_in;
358  MMAL_COMPONENT_T *decoder;
359  int ret = 0;
360 
361  ctx->pkt = avctx->internal->in_pkt;
362 
363  bcm_host_init();
364 
365  if (mmal_vc_init()) {
366  av_log(avctx, AV_LOG_ERROR, "Cannot initialize MMAL VC driver!\n");
367  return AVERROR(ENOSYS);
368  }
369 
370  if ((ret = ff_get_format(avctx, avctx->codec->pix_fmts)) < 0)
371  return ret;
372 
373  avctx->pix_fmt = ret;
374 
375  if ((status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, &ctx->decoder)))
376  goto fail;
377 
378  decoder = ctx->decoder;
379 
380  format_in = decoder->input[0]->format;
381  format_in->type = MMAL_ES_TYPE_VIDEO;
382  switch (avctx->codec_id) {
384  format_in->encoding = MMAL_ENCODING_MP2V;
385  break;
386  case AV_CODEC_ID_MPEG4:
387  format_in->encoding = MMAL_ENCODING_MP4V;
388  break;
389  case AV_CODEC_ID_VC1:
390  format_in->encoding = MMAL_ENCODING_WVC1;
391  break;
392  case AV_CODEC_ID_H264:
393  default:
394  format_in->encoding = MMAL_ENCODING_H264;
395  break;
396  }
397  format_in->es->video.width = FFALIGN(avctx->width, 32);
398  format_in->es->video.height = FFALIGN(avctx->height, 16);
399  format_in->es->video.crop.width = avctx->width;
400  format_in->es->video.crop.height = avctx->height;
401  format_in->es->video.frame_rate.num = 24000;
402  format_in->es->video.frame_rate.den = 1001;
403  format_in->es->video.par.num = avctx->sample_aspect_ratio.num;
404  format_in->es->video.par.den = avctx->sample_aspect_ratio.den;
405  format_in->flags = MMAL_ES_FORMAT_FLAG_FRAMED;
406 
407  av_log(avctx, AV_LOG_DEBUG, "Using MMAL %s encoding.\n",
408  av_fourcc2str(format_in->encoding));
409 
410 #if HAVE_MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS
411  if (mmal_port_parameter_set_uint32(decoder->input[0], MMAL_PARAMETER_VIDEO_MAX_NUM_CALLBACKS,
412  -1 - ctx->extra_decoder_buffers)) {
413  av_log(avctx, AV_LOG_WARNING, "Could not set input buffering limit.\n");
414  }
415 #endif
416 
417  if ((status = mmal_port_format_commit(decoder->input[0])))
418  goto fail;
419 
420  decoder->input[0]->buffer_num =
421  FFMAX(decoder->input[0]->buffer_num_min, 20);
422  decoder->input[0]->buffer_size =
423  FFMAX(decoder->input[0]->buffer_size_min, 512 * 1024);
424  ctx->pool_in = mmal_pool_create(decoder->input[0]->buffer_num, 0);
425  if (!ctx->pool_in) {
426  ret = AVERROR(ENOMEM);
427  goto fail;
428  }
429 
430  if ((ret = ffmal_update_format(avctx)) < 0)
431  goto fail;
432 
433  ctx->queue_decoded_frames = mmal_queue_create();
434  if (!ctx->queue_decoded_frames)
435  goto fail;
436 
437  decoder->input[0]->userdata = (void*)avctx;
438  decoder->output[0]->userdata = (void*)avctx;
439  decoder->control->userdata = (void*)avctx;
440 
441  if ((status = mmal_port_enable(decoder->control, control_port_cb)))
442  goto fail;
443  if ((status = mmal_port_enable(decoder->input[0], input_callback)))
444  goto fail;
445  if ((status = mmal_port_enable(decoder->output[0], output_callback)))
446  goto fail;
447 
448  if ((status = mmal_component_enable(decoder)))
449  goto fail;
450 
451  return 0;
452 
453 fail:
454  ffmmal_close_decoder(avctx);
455  return ret < 0 ? ret : AVERROR_UNKNOWN;
456 }
457 
458 static void ffmmal_flush(AVCodecContext *avctx)
459 {
460  MMALDecodeContext *ctx = avctx->priv_data;
461  MMAL_COMPONENT_T *decoder = ctx->decoder;
462  MMAL_STATUS_T status;
463 
464  ffmmal_stop_decoder(avctx);
465 
466  if ((status = mmal_port_enable(decoder->control, control_port_cb)))
467  goto fail;
468  if ((status = mmal_port_enable(decoder->input[0], input_callback)))
469  goto fail;
470  if ((status = mmal_port_enable(decoder->output[0], output_callback)))
471  goto fail;
472 
473  return;
474 
475 fail:
476  av_log(avctx, AV_LOG_ERROR, "MMAL flush error: %i\n", (int)status);
477 }
478 
479 // Split packets and add them to the waiting_buffers list. We don't queue them
480 // immediately, because it can happen that the decoder is temporarily blocked
481 // (due to us not reading/returning enough output buffers) and won't accept
482 // new input. (This wouldn't be an issue if MMAL input buffers always were
483 // complete frames - then the input buffer just would have to be big enough.)
484 // If is_extradata is set, send it as MMAL_BUFFER_HEADER_FLAG_CONFIG.
485 static int ffmmal_add_packet(AVCodecContext *avctx, AVPacket *avpkt,
486  int is_extradata)
487 {
488  MMALDecodeContext *ctx = avctx->priv_data;
489  const AVBufferRef *buf = NULL;
490  int size = 0;
491  uint8_t *data = (uint8_t *)"";
492  uint8_t *start;
493  int ret = 0;
494 
495  if (avpkt->size) {
497  if (ret < 0)
498  goto done;
499  buf = avpkt->buf;
500  data = avpkt->data;
501  size = avpkt->size;
502  if (!is_extradata)
503  ctx->packets_sent++;
504  } else {
505  if (ctx->eos_sent)
506  goto done;
507  if (!ctx->packets_sent) {
508  // Short-cut the flush logic to avoid upsetting MMAL.
509  ctx->eos_sent = 1;
510  ctx->eos_received = 1;
511  goto done;
512  }
513  }
514 
515  start = data;
516 
517  do {
518  FFBufferEntry *buffer = av_mallocz(sizeof(*buffer));
519  if (!buffer) {
520  ret = AVERROR(ENOMEM);
521  goto done;
522  }
523 
524  buffer->data = data;
525  buffer->length = FFMIN(size, ctx->decoder->input[0]->buffer_size);
526 
527  if (is_extradata)
528  buffer->flags |= MMAL_BUFFER_HEADER_FLAG_CONFIG;
529 
530  if (data == start)
531  buffer->flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_START;
532 
533  data += buffer->length;
534  size -= buffer->length;
535 
536  buffer->pts = avpkt->pts == AV_NOPTS_VALUE ? MMAL_TIME_UNKNOWN : avpkt->pts;
537  buffer->dts = avpkt->dts == AV_NOPTS_VALUE ? MMAL_TIME_UNKNOWN : avpkt->dts;
538 
539  if (!size) {
540  buffer->flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_END;
541  atomic_fetch_add(&ctx->packets_buffered, 1);
542  }
543 
544  if (!buffer->length) {
545  buffer->flags |= MMAL_BUFFER_HEADER_FLAG_EOS;
546  ctx->eos_sent = 1;
547  }
548 
549  if (buf) {
550  buffer->ref = av_buffer_ref(buf);
551  if (!buffer->ref) {
552  av_free(buffer);
553  ret = AVERROR(ENOMEM);
554  goto done;
555  }
556  }
557 
558  // Insert at end of the list
559  if (!ctx->waiting_buffers)
560  ctx->waiting_buffers = buffer;
561  if (ctx->waiting_buffers_tail)
562  ctx->waiting_buffers_tail->next = buffer;
563  ctx->waiting_buffers_tail = buffer;
564  } while (size);
565 
566 done:
567  av_packet_unref(avpkt);
568  return ret;
569 }
570 
571 // Move prepared/split packets from waiting_buffers to the MMAL decoder.
573 {
574  MMALDecodeContext *ctx = avctx->priv_data;
575 
576  while (ctx->waiting_buffers) {
577  MMAL_BUFFER_HEADER_T *mbuffer;
579  MMAL_STATUS_T status;
580 
581  mbuffer = mmal_queue_get(ctx->pool_in->queue);
582  if (!mbuffer)
583  return 0;
584 
585  buffer = ctx->waiting_buffers;
586 
587  mmal_buffer_header_reset(mbuffer);
588  mbuffer->cmd = 0;
589  mbuffer->pts = buffer->pts;
590  mbuffer->dts = buffer->dts;
591  mbuffer->flags = buffer->flags;
592  mbuffer->data = buffer->data;
593  mbuffer->length = buffer->length;
594  mbuffer->user_data = buffer;
595  mbuffer->alloc_size = ctx->decoder->input[0]->buffer_size;
596 
597  // Remove from start of the list
598  ctx->waiting_buffers = buffer->next;
599  if (ctx->waiting_buffers_tail == buffer)
600  ctx->waiting_buffers_tail = NULL;
601 
602  if ((status = mmal_port_send_buffer(ctx->decoder->input[0], mbuffer))) {
603  mmal_buffer_header_release(mbuffer);
604  av_buffer_unref(&buffer->ref);
605  if (buffer->flags & MMAL_BUFFER_HEADER_FLAG_FRAME_END)
606  atomic_fetch_add(&ctx->packets_buffered, -1);
607  av_free(buffer);
608  }
609 
610  if (status) {
611  av_log(avctx, AV_LOG_ERROR, "MMAL error %d when sending input\n", (int)status);
612  return AVERROR_UNKNOWN;
613  }
614  }
615 
616  return 0;
617 }
618 
620  MMAL_BUFFER_HEADER_T *buffer)
621 {
622  MMALDecodeContext *ctx = avctx->priv_data;
623  int ret = 0;
624 
625  if (ctx->interlaced_frame)
627  if (ctx->top_field_first)
629 
630  if (avctx->pix_fmt == AV_PIX_FMT_MMAL) {
631  if (!ctx->pool_out)
632  return AVERROR_UNKNOWN; // format change code failed with OOM previously
633 
634  if ((ret = ff_decode_frame_props(avctx, frame)) < 0)
635  goto done;
636 
637  if ((ret = ffmmal_set_ref(frame, ctx->pool_out, buffer)) < 0)
638  goto done;
639  } else {
640  int w = FFALIGN(avctx->width, 32);
641  int h = FFALIGN(avctx->height, 16);
642  uint8_t *src[4];
643  int linesize[4];
644 
645  if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
646  goto done;
647 
648  av_image_fill_arrays(src, linesize,
649  buffer->data + buffer->type->video.offset[0],
650  avctx->pix_fmt, w, h, 1);
651  av_image_copy2(frame->data, frame->linesize, src, linesize,
652  avctx->pix_fmt, avctx->width, avctx->height);
653  }
654 
656  frame->width = avctx->width;
657  frame->width = avctx->width;
658  frame->height = avctx->height;
659  frame->format = avctx->pix_fmt;
660 
661  frame->pts = buffer->pts == MMAL_TIME_UNKNOWN ? AV_NOPTS_VALUE : buffer->pts;
663 
664 done:
665  return ret;
666 }
667 
668 // Fetch a decoded buffer and place it into the frame parameter.
669 static int ffmmal_read_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame)
670 {
671  MMALDecodeContext *ctx = avctx->priv_data;
672  MMAL_BUFFER_HEADER_T *buffer = NULL;
673  MMAL_STATUS_T status = 0;
674  int ret = 0;
675 
676  if (ctx->eos_received)
677  goto done;
678 
679  while (1) {
680  // To ensure decoding in lockstep with a constant delay between fed packets
681  // and output frames, we always wait until an output buffer is available.
682  // Except during start we don't know after how many input packets the decoder
683  // is going to return the first buffer, and we can't distinguish decoder
684  // being busy from decoder waiting for input. So just poll at the start and
685  // keep feeding new data to the buffer.
686  // We are pretty sure the decoder will produce output if we sent more input
687  // frames than what a H.264 decoder could logically delay. This avoids too
688  // excessive buffering.
689  // We also wait if we sent eos, but didn't receive it yet (think of decoding
690  // stream with a very low number of frames).
691  if (atomic_load(&ctx->packets_buffered) > MAX_DELAYED_FRAMES ||
692  (ctx->packets_sent && ctx->eos_sent)) {
693  // MMAL will ignore broken input packets, which means the frame we
694  // expect here may never arrive. Dealing with this correctly is
695  // complicated, so here's a hack to avoid that it freezes forever
696  // in this unlikely situation.
697  buffer = mmal_queue_timedwait(ctx->queue_decoded_frames, 100);
698  if (!buffer) {
699  av_log(avctx, AV_LOG_ERROR, "Did not get output frame from MMAL.\n");
701  goto done;
702  }
703  } else {
704  buffer = mmal_queue_get(ctx->queue_decoded_frames);
705  if (!buffer)
706  goto done;
707  }
708 
709  ctx->eos_received |= !!(buffer->flags & MMAL_BUFFER_HEADER_FLAG_EOS);
710  if (ctx->eos_received)
711  goto done;
712 
713  if (buffer->cmd == MMAL_EVENT_FORMAT_CHANGED) {
714  MMAL_COMPONENT_T *decoder = ctx->decoder;
715  MMAL_EVENT_FORMAT_CHANGED_T *ev = mmal_event_format_changed_get(buffer);
716  MMAL_BUFFER_HEADER_T *stale_buffer;
717 
718  av_log(avctx, AV_LOG_INFO, "Changing output format.\n");
719 
720  if ((status = mmal_port_disable(decoder->output[0])))
721  goto done;
722 
723  while ((stale_buffer = mmal_queue_get(ctx->queue_decoded_frames)))
724  mmal_buffer_header_release(stale_buffer);
725 
726  mmal_format_copy(decoder->output[0]->format, ev->format);
727 
728  if ((ret = ffmal_update_format(avctx)) < 0)
729  goto done;
730 
731  if ((status = mmal_port_enable(decoder->output[0], output_callback)))
732  goto done;
733 
734  if ((ret = ffmmal_fill_output_port(avctx)) < 0)
735  goto done;
736 
737  if ((ret = ffmmal_fill_input_port(avctx)) < 0)
738  goto done;
739 
740  mmal_buffer_header_release(buffer);
741  continue;
742  } else if (buffer->cmd) {
743  av_log(avctx, AV_LOG_WARNING, "Unknown MMAL event %s on output port\n",
744  av_fourcc2str(buffer->cmd));
745  goto done;
746  } else if (buffer->length == 0) {
747  // Unused output buffer that got drained after format change.
748  mmal_buffer_header_release(buffer);
749  continue;
750  }
751 
752  ctx->frames_output++;
753 
754  if ((ret = ffmal_copy_frame(avctx, frame, buffer)) < 0)
755  goto done;
756 
757  *got_frame = 1;
758  break;
759  }
760 
761 done:
762  if (buffer)
763  mmal_buffer_header_release(buffer);
764  if (status && ret >= 0)
766  return ret;
767 }
768 
770 {
771  MMALDecodeContext *ctx = avctx->priv_data;
772  AVPacket *const avpkt = ctx->pkt;
773  int ret = 0;
774  int got_frame = 0;
775 
776  if (avctx->extradata_size && !ctx->extradata_sent) {
777  avpkt->data = avctx->extradata;
778  avpkt->size = avctx->extradata_size;
779  ctx->extradata_sent = 1;
780  if ((ret = ffmmal_add_packet(avctx, avpkt, 1)) < 0)
781  return ret;
782  }
783 
784  ret = ff_decode_get_packet(avctx, avpkt);
785  if (ret == 0) {
786  if ((ret = ffmmal_add_packet(avctx, avpkt, 0)) < 0)
787  return ret;
788  } else if (ret < 0 && !(ret == AVERROR(EAGAIN)))
789  return ret;
790 
791  if ((ret = ffmmal_fill_input_port(avctx)) < 0)
792  return ret;
793 
794  if ((ret = ffmmal_fill_output_port(avctx)) < 0)
795  return ret;
796 
797  if ((ret = ffmmal_read_frame(avctx, frame, &got_frame)) < 0)
798  return ret;
799 
800  // ffmmal_read_frame() can block for a while. Since the decoder is
801  // asynchronous, it's a good idea to fill the ports again.
802 
803  if ((ret = ffmmal_fill_output_port(avctx)) < 0)
804  return ret;
805 
806  if ((ret = ffmmal_fill_input_port(avctx)) < 0)
807  return ret;
808 
809  if (!got_frame && ret == 0)
810  return AVERROR(EAGAIN);
811  else
812  return ret;
813 }
814 
815 static const AVCodecHWConfigInternal *const mmal_hw_configs[] = {
816  HW_CONFIG_INTERNAL(MMAL),
817  NULL
818 };
819 
820 static const AVOption options[]={
821  {"extra_buffers", "extra buffers", offsetof(MMALDecodeContext, extra_buffers), AV_OPT_TYPE_INT, {.i64 = 10}, 0, 256, 0},
822  {"extra_decoder_buffers", "extra MMAL internal buffered frames", offsetof(MMALDecodeContext, extra_decoder_buffers), AV_OPT_TYPE_INT, {.i64 = 10}, 0, 256, 0},
823  {NULL}
824 };
825 
826 static const AVClass ffmmal_dec_class = {
827  .class_name = "mmal_dec",
828  .item_name = av_default_item_name,
829  .option = options,
830  .version = LIBAVUTIL_VERSION_INT,
831 };
832 
833 #define FFMMAL_DEC(NAME, ID) \
834  const FFCodec ff_##NAME##_mmal_decoder = { \
835  .p.name = #NAME "_mmal", \
836  CODEC_LONG_NAME(#NAME " (mmal)"), \
837  .p.type = AVMEDIA_TYPE_VIDEO, \
838  .p.id = ID, \
839  .priv_data_size = sizeof(MMALDecodeContext), \
840  .init = ffmmal_init_decoder, \
841  .close = ffmmal_close_decoder, \
842  FF_CODEC_RECEIVE_FRAME_CB(ffmmal_receive_frame), \
843  .flush = ffmmal_flush, \
844  .p.priv_class = &ffmmal_dec_class, \
845  .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_HARDWARE, \
846  .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE \
847  .p.pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_MMAL, \
848  AV_PIX_FMT_YUV420P, \
849  AV_PIX_FMT_NONE}, \
850  .hw_configs = mmal_hw_configs, \
851  .p.wrapper_name = "mmal", \
852  };
853 
FFMMAL_DEC
#define FFMMAL_DEC(NAME, ID)
Definition: mmaldec.c:833
hwconfig.h
av_packet_unref
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:423
ffmmal_fill_input_port
static int ffmmal_fill_input_port(AVCodecContext *avctx)
Definition: mmaldec.c:572
ff_decode_get_packet
int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt)
Called by decoders to get the next packet for decoding.
Definition: decode.c:241
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
MMALDecodeContext::top_field_first
int top_field_first
Definition: mmaldec.c:97
ffmmal_receive_frame
static int ffmmal_receive_frame(AVCodecContext *avctx, AVFrame *frame)
Definition: mmaldec.c:769
AVERROR
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
opt.h
MMALDecodeContext::extra_decoder_buffers
int extra_decoder_buffers
Definition: mmaldec.c:73
AVCodecContext::colorspace
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:1029
ff_get_format
int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
Select the (possibly hardware accelerated) pixel format.
Definition: decode.c:1264
MMALDecodeContext::frames_output
int64_t frames_output
Definition: mmaldec.c:92
AV_PIX_FMT_MMAL
@ AV_PIX_FMT_MMAL
HW acceleration though MMAL, data[3] contains a pointer to the MMAL_BUFFER_HEADER_T structure.
Definition: pixfmt.h:245
FFBufferRef::buffer
MMAL_BUFFER_HEADER_T * buffer
Definition: mmaldec.c:66
AVCodec::pix_fmts
enum AVPixelFormat * pix_fmts
array of supported pixel formats, or NULL if unknown, array is terminated by -1
Definition: codec.h:209
AV_CODEC_ID_MPEG4
@ AV_CODEC_ID_MPEG4
Definition: codec_id.h:64
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:340
AVFrame::pts
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:452
AVFrame::width
int width
Definition: frame.h:412
w
uint8_t w
Definition: llviddspenc.c:38
MMALDecodeContext::decoder
MMAL_COMPONENT_T * decoder
Definition: mmaldec.c:75
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:491
MMALDecodeContext::packets_sent
int64_t packets_sent
Definition: mmaldec.c:90
AVOption
AVOption.
Definition: opt.h:251
data
const char data[16]
Definition: mxf.c:148
atomic_int
intptr_t atomic_int
Definition: stdatomic.h:55
AVFrame::flags
int flags
Frame flags, a combination of AV_FRAME_FLAGS.
Definition: frame.h:649
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
av_buffer_ref
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:103
AVERROR_UNKNOWN
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:73
ffmmal_fill_output_port
static int ffmmal_fill_output_port(AVCodecContext *avctx)
Definition: mmaldec.c:244
AVFrame::buf
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
Definition: frame.h:590
ff_set_dimensions
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.
Definition: utils.c:94
MMALDecodeContext::av_class
AVClass * av_class
Definition: mmaldec.c:71
MMALDecodeContext::eos_sent
int eos_sent
Definition: mmaldec.c:94
FFPoolRef::pool
MMAL_POOL_T * pool
Definition: mmaldec.c:62
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:361
FFBufferEntry::flags
int flags
Definition: mmaldec.c:53
AV_FRAME_FLAG_TOP_FIELD_FIRST
#define AV_FRAME_FLAG_TOP_FIELD_FIRST
A flag to mark frames where the top field is displayed first if the content is interlaced.
Definition: frame.h:641
AVCodecContext::framerate
AVRational framerate
Definition: avcodec.h:1803
AVCOL_SPC_BT470BG
@ AVCOL_SPC_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
Definition: pixfmt.h:605
decoder
static const chunk_decoder decoder[8]
Definition: dfa.c:331
ffmmal_poolref_unref
static void ffmmal_poolref_unref(FFPoolRef *ref)
Definition: mmaldec.c:104
AVCodecContext::codec
const struct AVCodec * codec
Definition: avcodec.h:450
fail
#define fail()
Definition: checkasm.h:138
mmal_hw_configs
static const AVCodecHWConfigInternal *const mmal_hw_configs[]
Definition: mmaldec.c:815
options
static const AVOption options[]
Definition: mmaldec.c:820
AVRational::num
int num
Numerator.
Definition: rational.h:59
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:543
FFBufferEntry::next
struct FFBufferEntry * next
Definition: mmaldec.c:54
AV_BUFFER_FLAG_READONLY
#define AV_BUFFER_FLAG_READONLY
Always treat the buffer as read-only, even when it has only one reference.
Definition: buffer.h:114
ffmmal_flush
static void ffmmal_flush(AVCodecContext *avctx)
Definition: mmaldec.c:458
ffmmal_csp_to_av_csp
static enum AVColorSpace ffmmal_csp_to_av_csp(MMAL_FOURCC_T fourcc)
Definition: mmaldec.c:264
FFBufferEntry::pts
int64_t pts
Definition: mmaldec.c:52
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
ffmmal_set_ref
static int ffmmal_set_ref(AVFrame *frame, FFPoolRef *pool, MMAL_BUFFER_HEADER_T *buffer)
Definition: mmaldec.c:125
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
ctx
AVFormatContext * ctx
Definition: movenc.c:48
decode.h
MMALDecodeContext::queue_decoded_frames
MMAL_QUEUE_T * queue_decoded_frames
Definition: mmaldec.c:76
atomic_load
#define atomic_load(object)
Definition: stdatomic.h:93
MAX_DELAYED_FRAMES
#define MAX_DELAYED_FRAMES
Definition: mmaldec.c:102
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
MMALDecodeContext::interlaced_frame
int interlaced_frame
Definition: mmaldec.c:96
frame
static AVFrame * frame
Definition: demux_decode.c:54
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:451
control_port_cb
static void control_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
Definition: mmaldec.c:227
if
if(ret)
Definition: filter_design.txt:179
output_callback
static void output_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
Definition: mmaldec.c:219
ffmmal_init_decoder
static av_cold int ffmmal_init_decoder(AVCodecContext *avctx)
Definition: mmaldec.c:353
AVPacket::buf
AVBufferRef * buf
A reference to the reference-counted buffer where the packet data is stored.
Definition: packet.h:474
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
ffmal_copy_frame
static int ffmal_copy_frame(AVCodecContext *avctx, AVFrame *frame, MMAL_BUFFER_HEADER_T *buffer)
Definition: mmaldec.c:619
av_buffer_unref
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition: buffer.c:139
AVCodecContext::internal
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:476
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
ffmmal_close_decoder
static av_cold int ffmmal_close_decoder(AVCodecContext *avctx)
Definition: mmaldec.c:186
AVFrame::pkt_dts
int64_t pkt_dts
DTS copied from the AVPacket that triggered returning this frame.
Definition: frame.h:459
ffmmal_stop_decoder
static void ffmmal_stop_decoder(AVCodecContext *avctx)
Definition: mmaldec.c:151
av_buffer_create
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition: buffer.c:55
ff_get_buffer
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1617
AVPacket::size
int size
Definition: packet.h:492
av_image_fill_arrays
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.
Definition: imgutils.c:446
codec_internal.h
size
int size
Definition: twinvq_data.h:10344
atomic_fetch_add_explicit
#define atomic_fetch_add_explicit(object, operand, order)
Definition: stdatomic.h:149
FFBufferEntry::ref
AVBufferRef * ref
Definition: mmaldec.c:49
AV_NOPTS_VALUE
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:248
HW_CONFIG_INTERNAL
#define HW_CONFIG_INTERNAL(format)
Definition: hwconfig.h:54
ffmmal_read_frame
static int ffmmal_read_frame(AVCodecContext *avctx, AVFrame *frame, int *got_frame)
Definition: mmaldec.c:669
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:427
AVCodecHWConfigInternal
Definition: hwconfig.h:25
buffer.h
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:490
MMALDecodeContext::waiting_buffers_tail
FFBufferEntry * waiting_buffers_tail
Definition: mmaldec.c:86
av_packet_make_refcounted
int av_packet_make_refcounted(AVPacket *pkt)
Ensure the data described by a given packet is reference counted.
Definition: avpacket.c:486
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
AVCOL_SPC_SMPTE240M
@ AVCOL_SPC_SMPTE240M
derived from 170M primaries and D65 white point, 170M is derived from BT470 System M's primaries
Definition: pixfmt.h:607
log.h
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:484
AVCodecContext::extradata
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:542
MMALDecodeContext::extradata_sent
int extradata_sent
Definition: mmaldec.c:95
MMALDecodeContext::pool_out
FFPoolRef * pool_out
Definition: mmaldec.c:78
AVColorSpace
AVColorSpace
YUV colorspace type.
Definition: pixfmt.h:599
common.h
AVCodecInternal::in_pkt
AVPacket * in_pkt
This packet is used to hold the packet given to decoders implementing the .decode API; it is unused b...
Definition: internal.h:77
FFBufferEntry::dts
int64_t dts
Definition: mmaldec.c:52
MMALDecodeContext
Definition: mmaldec.c:70
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:254
AV_CODEC_ID_VC1
@ AV_CODEC_ID_VC1
Definition: codec_id.h:122
AVCOL_SPC_UNSPECIFIED
@ AVCOL_SPC_UNSPECIFIED
Definition: pixfmt.h:602
AVCodecContext::height
int height
Definition: avcodec.h:621
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:658
AV_FRAME_FLAG_INTERLACED
#define AV_FRAME_FLAG_INTERLACED
A flag to mark frames whose content is interlaced.
Definition: frame.h:636
avcodec.h
FFPoolRef
Definition: mmaldec.c:60
ret
ret
Definition: filter_design.txt:187
MMALDecodeContext::extra_buffers
int extra_buffers
Definition: mmaldec.c:72
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:71
ffmal_update_format
static int ffmal_update_format(AVCodecContext *avctx)
Definition: mmaldec.c:277
AVFrame::sample_aspect_ratio
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition: frame.h:447
MMALDecodeContext::pkt
AVPacket * pkt
Definition: mmaldec.c:88
ff_decode_frame_props
int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
Set various frame properties from the codec context / packet data.
Definition: decode.c:1504
AVCodecContext
main external API structure.
Definition: avcodec.h:441
AVFrame::height
int height
Definition: frame.h:412
FFBufferEntry::data
void * data
Definition: mmaldec.c:50
status
ov_status_e status
Definition: dnn_backend_openvino.c:119
input_callback
static void input_callback(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
Definition: mmaldec.c:204
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
av_image_copy2
static void av_image_copy2(uint8_t *const dst_data[4], const int dst_linesizes[4], uint8_t *const src_data[4], const int src_linesizes[4], enum AVPixelFormat pix_fmt, int width, int height)
Wrapper around av_image_copy() to workaround the limitation that the conversion from uint8_t * const ...
Definition: imgutils.h:184
MMALDecodeContext::waiting_buffers
FFBufferEntry * waiting_buffers
Definition: mmaldec.c:86
AVRational::den
int den
Denominator.
Definition: rational.h:60
atomic_fetch_add
#define atomic_fetch_add(object, operand)
Definition: stdatomic.h:131
AVCOL_SPC_FCC
@ AVCOL_SPC_FCC
FCC Title 47 Code of Federal Regulations 73.682 (a)(20)
Definition: pixfmt.h:604
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:112
FFBufferEntry
Definition: mmaldec.c:48
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
MMALDecodeContext::packets_buffered
atomic_int packets_buffered
Definition: mmaldec.c:91
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:468
AVPacket
This structure stores compressed data.
Definition: packet.h:468
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
ffmmal_release_frame
static void ffmmal_release_frame(void *opaque, uint8_t *data)
Definition: mmaldec.c:113
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:621
imgutils.h
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:385
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
FFPoolRef::refcount
atomic_int refcount
Definition: mmaldec.c:61
h
h
Definition: vp9dsp_template.c:2038
ffmmal_add_packet
static int ffmmal_add_packet(AVCodecContext *avctx, AVPacket *avpkt, int is_extradata)
Definition: mmaldec.c:485
atomic_init
#define atomic_init(obj, value)
Definition: stdatomic.h:33
FFBufferRef::pool
FFPoolRef * pool
Definition: mmaldec.c:67
MMALDecodeContext::eos_received
int eos_received
Definition: mmaldec.c:93
AVCOL_SPC_BT709
@ AVCOL_SPC_BT709
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / derived in SMPTE RP 177 Annex B
Definition: pixfmt.h:601
AV_CODEC_ID_MPEG2VIDEO
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
Definition: codec_id.h:54
FFBufferRef
Definition: mmaldec.c:65
fourcc
uint32_t fourcc
Definition: vaapi_decode.c:242
FFBufferEntry::length
size_t length
Definition: mmaldec.c:51
ffmmal_dec_class
static const AVClass ffmmal_dec_class
Definition: mmaldec.c:826
AVCodecContext::sample_aspect_ratio
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown) That is the width of a pixel divided by the height of the pixel.
Definition: avcodec.h:822
MMALDecodeContext::pool_in
MMAL_POOL_T * pool_in
Definition: mmaldec.c:77
av_fourcc2str
#define av_fourcc2str(fourcc)
Definition: avutil.h:358