FFmpeg
omx.c
Go to the documentation of this file.
1 /*
2  * OMX Video encoder
3  * Copyright (C) 2011 Martin Storsjo
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 #include "config.h"
23 
24 #if CONFIG_OMX_RPI
25 #define OMX_SKIP64BIT
26 #endif
27 
28 #include <dlfcn.h>
29 #include <OMX_Core.h>
30 #include <OMX_Component.h>
31 #include <pthread.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <sys/time.h>
35 
36 #include "libavutil/avstring.h"
37 #include "libavutil/avutil.h"
38 #include "libavutil/common.h"
39 #include "libavutil/imgutils.h"
40 #include "libavutil/log.h"
41 #include "libavutil/opt.h"
42 
43 #include "avcodec.h"
44 #include "h264.h"
45 #include "internal.h"
46 
47 #ifdef OMX_SKIP64BIT
48 static OMX_TICKS to_omx_ticks(int64_t value)
49 {
50  OMX_TICKS s;
51  s.nLowPart = value & 0xffffffff;
52  s.nHighPart = value >> 32;
53  return s;
54 }
55 static int64_t from_omx_ticks(OMX_TICKS value)
56 {
57  return (((int64_t)value.nHighPart) << 32) | value.nLowPart;
58 }
59 #else
60 #define to_omx_ticks(x) (x)
61 #define from_omx_ticks(x) (x)
62 #endif
63 
64 #define INIT_STRUCT(x) do { \
65  x.nSize = sizeof(x); \
66  x.nVersion = s->version; \
67  } while (0)
68 #define CHECK(x) do { \
69  if (x != OMX_ErrorNone) { \
70  av_log(avctx, AV_LOG_ERROR, \
71  "err %x (%d) on line %d\n", x, x, __LINE__); \
72  return AVERROR_UNKNOWN; \
73  } \
74  } while (0)
75 
76 typedef struct OMXContext {
77  void *lib;
78  void *lib2;
79  OMX_ERRORTYPE (*ptr_Init)(void);
80  OMX_ERRORTYPE (*ptr_Deinit)(void);
81  OMX_ERRORTYPE (*ptr_ComponentNameEnum)(OMX_STRING, OMX_U32, OMX_U32);
82  OMX_ERRORTYPE (*ptr_GetHandle)(OMX_HANDLETYPE*, OMX_STRING, OMX_PTR, OMX_CALLBACKTYPE*);
83  OMX_ERRORTYPE (*ptr_FreeHandle)(OMX_HANDLETYPE);
84  OMX_ERRORTYPE (*ptr_GetComponentsOfRole)(OMX_STRING, OMX_U32*, OMX_U8**);
85  OMX_ERRORTYPE (*ptr_GetRolesOfComponent)(OMX_STRING, OMX_U32*, OMX_U8**);
87 } OMXContext;
88 
89 static av_cold void *dlsym_prefixed(void *handle, const char *symbol, const char *prefix)
90 {
91  char buf[50];
92  snprintf(buf, sizeof(buf), "%s%s", prefix ? prefix : "", symbol);
93  return dlsym(handle, buf);
94 }
95 
96 static av_cold int omx_try_load(OMXContext *s, void *logctx,
97  const char *libname, const char *prefix,
98  const char *libname2)
99 {
100  if (libname2) {
101  s->lib2 = dlopen(libname2, RTLD_NOW | RTLD_GLOBAL);
102  if (!s->lib2) {
103  av_log(logctx, AV_LOG_WARNING, "%s not found\n", libname2);
105  }
106  s->host_init = dlsym(s->lib2, "bcm_host_init");
107  if (!s->host_init) {
108  av_log(logctx, AV_LOG_WARNING, "bcm_host_init not found\n");
109  dlclose(s->lib2);
110  s->lib2 = NULL;
112  }
113  }
114  s->lib = dlopen(libname, RTLD_NOW | RTLD_GLOBAL);
115  if (!s->lib) {
116  av_log(logctx, AV_LOG_WARNING, "%s not found\n", libname);
118  }
119  s->ptr_Init = dlsym_prefixed(s->lib, "OMX_Init", prefix);
120  s->ptr_Deinit = dlsym_prefixed(s->lib, "OMX_Deinit", prefix);
121  s->ptr_ComponentNameEnum = dlsym_prefixed(s->lib, "OMX_ComponentNameEnum", prefix);
122  s->ptr_GetHandle = dlsym_prefixed(s->lib, "OMX_GetHandle", prefix);
123  s->ptr_FreeHandle = dlsym_prefixed(s->lib, "OMX_FreeHandle", prefix);
124  s->ptr_GetComponentsOfRole = dlsym_prefixed(s->lib, "OMX_GetComponentsOfRole", prefix);
125  s->ptr_GetRolesOfComponent = dlsym_prefixed(s->lib, "OMX_GetRolesOfComponent", prefix);
126  if (!s->ptr_Init || !s->ptr_Deinit || !s->ptr_ComponentNameEnum ||
127  !s->ptr_GetHandle || !s->ptr_FreeHandle ||
129  av_log(logctx, AV_LOG_WARNING, "Not all functions found in %s\n", libname);
130  dlclose(s->lib);
131  s->lib = NULL;
132  if (s->lib2)
133  dlclose(s->lib2);
134  s->lib2 = NULL;
136  }
137  return 0;
138 }
139 
140 static av_cold OMXContext *omx_init(void *logctx, const char *libname, const char *prefix)
141 {
142  static const char * const libnames[] = {
143 #if CONFIG_OMX_RPI
144  "/opt/vc/lib/libopenmaxil.so", "/opt/vc/lib/libbcm_host.so",
145 #else
146  "libOMX_Core.so", NULL,
147  "libOmxCore.so", NULL,
148 #endif
149  NULL
150  };
151  const char* const* nameptr;
153  OMXContext *omx_context;
154 
155  omx_context = av_mallocz(sizeof(*omx_context));
156  if (!omx_context)
157  return NULL;
158  if (libname) {
159  ret = omx_try_load(omx_context, logctx, libname, prefix, NULL);
160  if (ret < 0) {
161  av_free(omx_context);
162  return NULL;
163  }
164  } else {
165  for (nameptr = libnames; *nameptr; nameptr += 2)
166  if (!(ret = omx_try_load(omx_context, logctx, nameptr[0], prefix, nameptr[1])))
167  break;
168  if (!*nameptr) {
169  av_free(omx_context);
170  return NULL;
171  }
172  }
173 
174  if (omx_context->host_init)
175  omx_context->host_init();
176  omx_context->ptr_Init();
177  return omx_context;
178 }
179 
180 static av_cold void omx_deinit(OMXContext *omx_context)
181 {
182  if (!omx_context)
183  return;
184  omx_context->ptr_Deinit();
185  dlclose(omx_context->lib);
186  av_free(omx_context);
187 }
188 
189 typedef struct OMXCodecContext {
190  const AVClass *class;
191  char *libname;
192  char *libprefix;
194 
196 
197  char component_name[OMX_MAX_STRINGNAME_SIZE];
198  OMX_VERSIONTYPE version;
199  OMX_HANDLETYPE handle;
200  int in_port, out_port;
201  OMX_COLOR_FORMATTYPE color_format;
202  int stride, plane_size;
203 
204  int num_in_buffers, num_out_buffers;
205  OMX_BUFFERHEADERTYPE **in_buffer_headers;
206  OMX_BUFFERHEADERTYPE **out_buffer_headers;
208  OMX_BUFFERHEADERTYPE **free_in_buffers;
210  OMX_BUFFERHEADERTYPE **done_out_buffers;
215 
218  OMX_STATETYPE state;
219  OMX_ERRORTYPE error;
220 
222 
223  int eos_sent, got_eos;
224 
227 
229  int profile;
231 
233  int* array_size, OMX_BUFFERHEADERTYPE **array,
234  OMX_BUFFERHEADERTYPE *buffer)
235 {
236  pthread_mutex_lock(mutex);
237  array[(*array_size)++] = buffer;
239  pthread_mutex_unlock(mutex);
240 }
241 
242 static OMX_BUFFERHEADERTYPE *get_buffer(pthread_mutex_t *mutex, pthread_cond_t *cond,
243  int* array_size, OMX_BUFFERHEADERTYPE **array,
244  int wait)
245 {
246  OMX_BUFFERHEADERTYPE *buffer;
247  pthread_mutex_lock(mutex);
248  if (wait) {
249  while (!*array_size)
250  pthread_cond_wait(cond, mutex);
251  }
252  if (*array_size > 0) {
253  buffer = array[0];
254  (*array_size)--;
255  memmove(&array[0], &array[1], (*array_size) * sizeof(OMX_BUFFERHEADERTYPE*));
256  } else {
257  buffer = NULL;
258  }
259  pthread_mutex_unlock(mutex);
260  return buffer;
261 }
262 
263 static OMX_ERRORTYPE event_handler(OMX_HANDLETYPE component, OMX_PTR app_data, OMX_EVENTTYPE event,
264  OMX_U32 data1, OMX_U32 data2, OMX_PTR event_data)
265 {
266  OMXCodecContext *s = app_data;
267  // This uses casts in the printfs, since OMX_U32 actually is a typedef for
268  // unsigned long in official header versions (but there are also modified
269  // versions where it is something else).
270  switch (event) {
271  case OMX_EventError:
273  av_log(s->avctx, AV_LOG_ERROR, "OMX error %"PRIx32"\n", (uint32_t) data1);
274  s->error = data1;
277  break;
278  case OMX_EventCmdComplete:
279  if (data1 == OMX_CommandStateSet) {
281  s->state = data2;
282  av_log(s->avctx, AV_LOG_VERBOSE, "OMX state changed to %"PRIu32"\n", (uint32_t) data2);
285  } else if (data1 == OMX_CommandPortDisable) {
286  av_log(s->avctx, AV_LOG_VERBOSE, "OMX port %"PRIu32" disabled\n", (uint32_t) data2);
287  } else if (data1 == OMX_CommandPortEnable) {
288  av_log(s->avctx, AV_LOG_VERBOSE, "OMX port %"PRIu32" enabled\n", (uint32_t) data2);
289  } else {
290  av_log(s->avctx, AV_LOG_VERBOSE, "OMX command complete, command %"PRIu32", value %"PRIu32"\n",
291  (uint32_t) data1, (uint32_t) data2);
292  }
293  break;
294  case OMX_EventPortSettingsChanged:
295  av_log(s->avctx, AV_LOG_VERBOSE, "OMX port %"PRIu32" settings changed\n", (uint32_t) data1);
296  break;
297  default:
298  av_log(s->avctx, AV_LOG_VERBOSE, "OMX event %d %"PRIx32" %"PRIx32"\n",
299  event, (uint32_t) data1, (uint32_t) data2);
300  break;
301  }
302  return OMX_ErrorNone;
303 }
304 
305 static OMX_ERRORTYPE empty_buffer_done(OMX_HANDLETYPE component, OMX_PTR app_data,
306  OMX_BUFFERHEADERTYPE *buffer)
307 {
308  OMXCodecContext *s = app_data;
309  if (s->input_zerocopy) {
310  if (buffer->pAppPrivate) {
311  if (buffer->pOutputPortPrivate)
312  av_free(buffer->pAppPrivate);
313  else
314  av_frame_free((AVFrame**)&buffer->pAppPrivate);
315  buffer->pAppPrivate = NULL;
316  }
317  }
319  &s->num_free_in_buffers, s->free_in_buffers, buffer);
320  return OMX_ErrorNone;
321 }
322 
323 static OMX_ERRORTYPE fill_buffer_done(OMX_HANDLETYPE component, OMX_PTR app_data,
324  OMX_BUFFERHEADERTYPE *buffer)
325 {
326  OMXCodecContext *s = app_data;
328  &s->num_done_out_buffers, s->done_out_buffers, buffer);
329  return OMX_ErrorNone;
330 }
331 
332 static const OMX_CALLBACKTYPE callbacks = {
336 };
337 
338 static av_cold int find_component(OMXContext *omx_context, void *logctx,
339  const char *role, char *str, int str_size)
340 {
341  OMX_U32 i, num = 0;
342  char **components;
343  int ret = 0;
344 
345 #if CONFIG_OMX_RPI
346  if (av_strstart(role, "video_encoder.", NULL)) {
347  av_strlcpy(str, "OMX.broadcom.video_encode", str_size);
348  return 0;
349  }
350 #endif
351  omx_context->ptr_GetComponentsOfRole((OMX_STRING) role, &num, NULL);
352  if (!num) {
353  av_log(logctx, AV_LOG_WARNING, "No component for role %s found\n", role);
355  }
356  components = av_mallocz_array(num, sizeof(*components));
357  if (!components)
358  return AVERROR(ENOMEM);
359  for (i = 0; i < num; i++) {
360  components[i] = av_mallocz(OMX_MAX_STRINGNAME_SIZE);
361  if (!components[i]) {
362  ret = AVERROR(ENOMEM);
363  goto end;
364  }
365  }
366  omx_context->ptr_GetComponentsOfRole((OMX_STRING) role, &num, (OMX_U8**) components);
367  av_strlcpy(str, components[0], str_size);
368 end:
369  for (i = 0; i < num; i++)
370  av_free(components[i]);
371  av_free(components);
372  return ret;
373 }
374 
375 static av_cold int wait_for_state(OMXCodecContext *s, OMX_STATETYPE state)
376 {
377  int ret = 0;
379  while (s->state != state && s->error == OMX_ErrorNone)
381  if (s->error != OMX_ErrorNone)
384  return ret;
385 }
386 
387 static av_cold int omx_component_init(AVCodecContext *avctx, const char *role)
388 {
389  OMXCodecContext *s = avctx->priv_data;
390  OMX_PARAM_COMPONENTROLETYPE role_params = { 0 };
391  OMX_PORT_PARAM_TYPE video_port_params = { 0 };
392  OMX_PARAM_PORTDEFINITIONTYPE in_port_params = { 0 }, out_port_params = { 0 };
393  OMX_VIDEO_PARAM_PORTFORMATTYPE video_port_format = { 0 };
394  OMX_VIDEO_PARAM_BITRATETYPE vid_param_bitrate = { 0 };
395  OMX_ERRORTYPE err;
396  int i;
397 
398  s->version.s.nVersionMajor = 1;
399  s->version.s.nVersionMinor = 1;
400  s->version.s.nRevision = 2;
401 
402  err = s->omx_context->ptr_GetHandle(&s->handle, s->component_name, s, (OMX_CALLBACKTYPE*) &callbacks);
403  if (err != OMX_ErrorNone) {
404  av_log(avctx, AV_LOG_ERROR, "OMX_GetHandle(%s) failed: %x\n", s->component_name, err);
405  return AVERROR_UNKNOWN;
406  }
407 
408  // This one crashes the mediaserver on qcom, if used over IOMX
409  INIT_STRUCT(role_params);
410  av_strlcpy(role_params.cRole, role, sizeof(role_params.cRole));
411  // Intentionally ignore errors on this one
412  OMX_SetParameter(s->handle, OMX_IndexParamStandardComponentRole, &role_params);
413 
414  INIT_STRUCT(video_port_params);
415  err = OMX_GetParameter(s->handle, OMX_IndexParamVideoInit, &video_port_params);
416  CHECK(err);
417 
418  s->in_port = s->out_port = -1;
419  for (i = 0; i < video_port_params.nPorts; i++) {
420  int port = video_port_params.nStartPortNumber + i;
421  OMX_PARAM_PORTDEFINITIONTYPE port_params = { 0 };
422  INIT_STRUCT(port_params);
423  port_params.nPortIndex = port;
424  err = OMX_GetParameter(s->handle, OMX_IndexParamPortDefinition, &port_params);
425  if (err != OMX_ErrorNone) {
426  av_log(avctx, AV_LOG_WARNING, "port %d error %x\n", port, err);
427  break;
428  }
429  if (port_params.eDir == OMX_DirInput && s->in_port < 0) {
430  in_port_params = port_params;
431  s->in_port = port;
432  } else if (port_params.eDir == OMX_DirOutput && s->out_port < 0) {
433  out_port_params = port_params;
434  s->out_port = port;
435  }
436  }
437  if (s->in_port < 0 || s->out_port < 0) {
438  av_log(avctx, AV_LOG_ERROR, "No in or out port found (in %d out %d)\n", s->in_port, s->out_port);
439  return AVERROR_UNKNOWN;
440  }
441 
442  s->color_format = 0;
443  for (i = 0; ; i++) {
444  INIT_STRUCT(video_port_format);
445  video_port_format.nIndex = i;
446  video_port_format.nPortIndex = s->in_port;
447  if (OMX_GetParameter(s->handle, OMX_IndexParamVideoPortFormat, &video_port_format) != OMX_ErrorNone)
448  break;
449  if (video_port_format.eColorFormat == OMX_COLOR_FormatYUV420Planar ||
450  video_port_format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar) {
451  s->color_format = video_port_format.eColorFormat;
452  break;
453  }
454  }
455  if (s->color_format == 0) {
456  av_log(avctx, AV_LOG_ERROR, "No supported pixel formats (%d formats available)\n", i);
457  return AVERROR_UNKNOWN;
458  }
459 
460  in_port_params.bEnabled = OMX_TRUE;
461  in_port_params.bPopulated = OMX_FALSE;
462  in_port_params.eDomain = OMX_PortDomainVideo;
463 
464  in_port_params.format.video.pNativeRender = NULL;
465  in_port_params.format.video.bFlagErrorConcealment = OMX_FALSE;
466  in_port_params.format.video.eColorFormat = s->color_format;
467  s->stride = avctx->width;
468  s->plane_size = avctx->height;
469  // If specific codecs need to manually override the stride/plane_size,
470  // that can be done here.
471  in_port_params.format.video.nStride = s->stride;
472  in_port_params.format.video.nSliceHeight = s->plane_size;
473  in_port_params.format.video.nFrameWidth = avctx->width;
474  in_port_params.format.video.nFrameHeight = avctx->height;
475  if (avctx->framerate.den > 0 && avctx->framerate.num > 0)
476  in_port_params.format.video.xFramerate = (1 << 16) * avctx->framerate.num / avctx->framerate.den;
477  else
478  in_port_params.format.video.xFramerate = (1 << 16) * avctx->time_base.den / avctx->time_base.num;
479 
480  err = OMX_SetParameter(s->handle, OMX_IndexParamPortDefinition, &in_port_params);
481  CHECK(err);
482  err = OMX_GetParameter(s->handle, OMX_IndexParamPortDefinition, &in_port_params);
483  CHECK(err);
484  s->stride = in_port_params.format.video.nStride;
485  s->plane_size = in_port_params.format.video.nSliceHeight;
486  s->num_in_buffers = in_port_params.nBufferCountActual;
487 
488  err = OMX_GetParameter(s->handle, OMX_IndexParamPortDefinition, &out_port_params);
489  out_port_params.bEnabled = OMX_TRUE;
490  out_port_params.bPopulated = OMX_FALSE;
491  out_port_params.eDomain = OMX_PortDomainVideo;
492  out_port_params.format.video.pNativeRender = NULL;
493  out_port_params.format.video.nFrameWidth = avctx->width;
494  out_port_params.format.video.nFrameHeight = avctx->height;
495  out_port_params.format.video.nStride = 0;
496  out_port_params.format.video.nSliceHeight = 0;
497  out_port_params.format.video.nBitrate = avctx->bit_rate;
498  out_port_params.format.video.xFramerate = in_port_params.format.video.xFramerate;
499  out_port_params.format.video.bFlagErrorConcealment = OMX_FALSE;
500  if (avctx->codec->id == AV_CODEC_ID_MPEG4)
501  out_port_params.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
502  else if (avctx->codec->id == AV_CODEC_ID_H264)
503  out_port_params.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
504 
505  err = OMX_SetParameter(s->handle, OMX_IndexParamPortDefinition, &out_port_params);
506  CHECK(err);
507  err = OMX_GetParameter(s->handle, OMX_IndexParamPortDefinition, &out_port_params);
508  CHECK(err);
509  s->num_out_buffers = out_port_params.nBufferCountActual;
510 
511  INIT_STRUCT(vid_param_bitrate);
512  vid_param_bitrate.nPortIndex = s->out_port;
513  vid_param_bitrate.eControlRate = OMX_Video_ControlRateVariable;
514  vid_param_bitrate.nTargetBitrate = avctx->bit_rate;
515  err = OMX_SetParameter(s->handle, OMX_IndexParamVideoBitrate, &vid_param_bitrate);
516  if (err != OMX_ErrorNone)
517  av_log(avctx, AV_LOG_WARNING, "Unable to set video bitrate parameter\n");
518 
519  if (avctx->codec->id == AV_CODEC_ID_H264) {
520  OMX_VIDEO_PARAM_AVCTYPE avc = { 0 };
521  INIT_STRUCT(avc);
522  avc.nPortIndex = s->out_port;
523  err = OMX_GetParameter(s->handle, OMX_IndexParamVideoAvc, &avc);
524  CHECK(err);
525  avc.nBFrames = 0;
526  avc.nPFrames = avctx->gop_size - 1;
527  switch (s->profile == FF_PROFILE_UNKNOWN ? avctx->profile : s->profile) {
529  avc.eProfile = OMX_VIDEO_AVCProfileBaseline;
530  break;
532  avc.eProfile = OMX_VIDEO_AVCProfileMain;
533  break;
535  avc.eProfile = OMX_VIDEO_AVCProfileHigh;
536  break;
537  default:
538  break;
539  }
540  err = OMX_SetParameter(s->handle, OMX_IndexParamVideoAvc, &avc);
541  CHECK(err);
542  }
543 
544  err = OMX_SendCommand(s->handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
545  CHECK(err);
546 
547  s->in_buffer_headers = av_mallocz(sizeof(OMX_BUFFERHEADERTYPE*) * s->num_in_buffers);
548  s->free_in_buffers = av_mallocz(sizeof(OMX_BUFFERHEADERTYPE*) * s->num_in_buffers);
549  s->out_buffer_headers = av_mallocz(sizeof(OMX_BUFFERHEADERTYPE*) * s->num_out_buffers);
550  s->done_out_buffers = av_mallocz(sizeof(OMX_BUFFERHEADERTYPE*) * s->num_out_buffers);
552  return AVERROR(ENOMEM);
553  for (i = 0; i < s->num_in_buffers && err == OMX_ErrorNone; i++) {
554  if (s->input_zerocopy)
555  err = OMX_UseBuffer(s->handle, &s->in_buffer_headers[i], s->in_port, s, in_port_params.nBufferSize, NULL);
556  else
557  err = OMX_AllocateBuffer(s->handle, &s->in_buffer_headers[i], s->in_port, s, in_port_params.nBufferSize);
558  if (err == OMX_ErrorNone)
559  s->in_buffer_headers[i]->pAppPrivate = s->in_buffer_headers[i]->pOutputPortPrivate = NULL;
560  }
561  CHECK(err);
562  s->num_in_buffers = i;
563  for (i = 0; i < s->num_out_buffers && err == OMX_ErrorNone; i++)
564  err = OMX_AllocateBuffer(s->handle, &s->out_buffer_headers[i], s->out_port, s, out_port_params.nBufferSize);
565  CHECK(err);
566  s->num_out_buffers = i;
567 
568  if (wait_for_state(s, OMX_StateIdle) < 0) {
569  av_log(avctx, AV_LOG_ERROR, "Didn't get OMX_StateIdle\n");
570  return AVERROR_UNKNOWN;
571  }
572  err = OMX_SendCommand(s->handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
573  CHECK(err);
574  if (wait_for_state(s, OMX_StateExecuting) < 0) {
575  av_log(avctx, AV_LOG_ERROR, "Didn't get OMX_StateExecuting\n");
576  return AVERROR_UNKNOWN;
577  }
578 
579  for (i = 0; i < s->num_out_buffers && err == OMX_ErrorNone; i++)
580  err = OMX_FillThisBuffer(s->handle, s->out_buffer_headers[i]);
581  if (err != OMX_ErrorNone) {
582  for (; i < s->num_out_buffers; i++)
584  }
585  for (i = 0; i < s->num_in_buffers; i++)
587  return err != OMX_ErrorNone ? AVERROR_UNKNOWN : 0;
588 }
589 
591 {
592  int i, executing;
593 
595  executing = s->state == OMX_StateExecuting;
597 
598  if (executing) {
599  OMX_SendCommand(s->handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
600  wait_for_state(s, OMX_StateIdle);
601  OMX_SendCommand(s->handle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
602  for (i = 0; i < s->num_in_buffers; i++) {
603  OMX_BUFFERHEADERTYPE *buffer = get_buffer(&s->input_mutex, &s->input_cond,
605  if (s->input_zerocopy)
606  buffer->pBuffer = NULL;
607  OMX_FreeBuffer(s->handle, s->in_port, buffer);
608  }
609  for (i = 0; i < s->num_out_buffers; i++) {
610  OMX_BUFFERHEADERTYPE *buffer = get_buffer(&s->output_mutex, &s->output_cond,
612  OMX_FreeBuffer(s->handle, s->out_port, buffer);
613  }
614  wait_for_state(s, OMX_StateLoaded);
615  }
616  if (s->handle) {
618  s->handle = NULL;
619  }
620 
622  s->omx_context = NULL;
623  if (s->mutex_cond_inited) {
630  s->mutex_cond_inited = 0;
631  }
636  av_freep(&s->output_buf);
637 }
638 
640 {
641  OMXCodecContext *s = avctx->priv_data;
643  const char *role;
644  OMX_BUFFERHEADERTYPE *buffer;
645  OMX_ERRORTYPE err;
646 
647 #if CONFIG_OMX_RPI
648  s->input_zerocopy = 1;
649 #endif
650 
651  s->omx_context = omx_init(avctx, s->libname, s->libprefix);
652  if (!s->omx_context)
654 
661  s->mutex_cond_inited = 1;
662  s->avctx = avctx;
663  s->state = OMX_StateLoaded;
664  s->error = OMX_ErrorNone;
665 
666  switch (avctx->codec->id) {
667  case AV_CODEC_ID_MPEG4:
668  role = "video_encoder.mpeg4";
669  break;
670  case AV_CODEC_ID_H264:
671  role = "video_encoder.avc";
672  break;
673  default:
674  return AVERROR(ENOSYS);
675  }
676 
677  if ((ret = find_component(s->omx_context, avctx, role, s->component_name, sizeof(s->component_name))) < 0)
678  goto fail;
679 
680  av_log(avctx, AV_LOG_INFO, "Using %s\n", s->component_name);
681 
682  if ((ret = omx_component_init(avctx, role)) < 0)
683  goto fail;
684 
685  if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
686  while (1) {
687  buffer = get_buffer(&s->output_mutex, &s->output_cond,
689  if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
690  if ((ret = av_reallocp(&avctx->extradata, avctx->extradata_size + buffer->nFilledLen + AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
691  avctx->extradata_size = 0;
692  goto fail;
693  }
694  memcpy(avctx->extradata + avctx->extradata_size, buffer->pBuffer + buffer->nOffset, buffer->nFilledLen);
695  avctx->extradata_size += buffer->nFilledLen;
696  memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
697  }
698  err = OMX_FillThisBuffer(s->handle, buffer);
699  if (err != OMX_ErrorNone) {
701  &s->num_done_out_buffers, s->done_out_buffers, buffer);
702  av_log(avctx, AV_LOG_ERROR, "OMX_FillThisBuffer failed: %x\n", err);
703  ret = AVERROR_UNKNOWN;
704  goto fail;
705  }
706  if (avctx->codec->id == AV_CODEC_ID_H264) {
707  // For H.264, the extradata can be returned in two separate buffers
708  // (the videocore encoder on raspberry pi does this);
709  // therefore check that we have got both SPS and PPS before continuing.
710  int nals[32] = { 0 };
711  int i;
712  for (i = 0; i + 4 < avctx->extradata_size; i++) {
713  if (!avctx->extradata[i + 0] &&
714  !avctx->extradata[i + 1] &&
715  !avctx->extradata[i + 2] &&
716  avctx->extradata[i + 3] == 1) {
717  nals[avctx->extradata[i + 4] & 0x1f]++;
718  }
719  }
720  if (nals[H264_NAL_SPS] && nals[H264_NAL_PPS])
721  break;
722  } else {
723  if (avctx->extradata_size > 0)
724  break;
725  }
726  }
727  }
728 
729  return 0;
730 fail:
731  return ret;
732 }
733 
734 
736  const AVFrame *frame, int *got_packet)
737 {
738  OMXCodecContext *s = avctx->priv_data;
739  int ret = 0;
740  OMX_BUFFERHEADERTYPE* buffer;
741  OMX_ERRORTYPE err;
742 
743  if (frame) {
744  uint8_t *dst[4];
745  int linesize[4];
746  int need_copy;
747  buffer = get_buffer(&s->input_mutex, &s->input_cond,
749 
750  buffer->nFilledLen = av_image_fill_arrays(dst, linesize, buffer->pBuffer, avctx->pix_fmt, s->stride, s->plane_size, 1);
751 
752  if (s->input_zerocopy) {
753  uint8_t *src[4] = { NULL };
754  int src_linesize[4];
755  av_image_fill_arrays(src, src_linesize, frame->data[0], avctx->pix_fmt, s->stride, s->plane_size, 1);
756  if (frame->linesize[0] == src_linesize[0] &&
757  frame->linesize[1] == src_linesize[1] &&
758  frame->linesize[2] == src_linesize[2] &&
759  frame->data[1] == src[1] &&
760  frame->data[2] == src[2]) {
761  // If the input frame happens to have all planes stored contiguously,
762  // with the right strides, just clone the frame and set the OMX
763  // buffer header to point to it
764  AVFrame *local = av_frame_clone(frame);
765  if (!local) {
766  // Return the buffer to the queue so it's not lost
768  return AVERROR(ENOMEM);
769  } else {
770  buffer->pAppPrivate = local;
771  buffer->pOutputPortPrivate = NULL;
772  buffer->pBuffer = local->data[0];
773  need_copy = 0;
774  }
775  } else {
776  // If not, we need to allocate a new buffer with the right
777  // size and copy the input frame into it.
778  uint8_t *buf = NULL;
779  int image_buffer_size = av_image_get_buffer_size(avctx->pix_fmt, s->stride, s->plane_size, 1);
780  if (image_buffer_size >= 0)
781  buf = av_malloc(image_buffer_size);
782  if (!buf) {
783  // Return the buffer to the queue so it's not lost
785  return AVERROR(ENOMEM);
786  } else {
787  buffer->pAppPrivate = buf;
788  // Mark that pAppPrivate is an av_malloc'ed buffer, not an AVFrame
789  buffer->pOutputPortPrivate = (void*) 1;
790  buffer->pBuffer = buf;
791  need_copy = 1;
792  buffer->nFilledLen = av_image_fill_arrays(dst, linesize, buffer->pBuffer, avctx->pix_fmt, s->stride, s->plane_size, 1);
793  }
794  }
795  } else {
796  need_copy = 1;
797  }
798  if (need_copy)
799  av_image_copy(dst, linesize, (const uint8_t**) frame->data, frame->linesize, avctx->pix_fmt, avctx->width, avctx->height);
800  buffer->nFlags = OMX_BUFFERFLAG_ENDOFFRAME;
801  buffer->nOffset = 0;
802  // Convert the timestamps to microseconds; some encoders can ignore
803  // the framerate and do VFR bit allocation based on timestamps.
804  buffer->nTimeStamp = to_omx_ticks(av_rescale_q(frame->pts, avctx->time_base, AV_TIME_BASE_Q));
805  err = OMX_EmptyThisBuffer(s->handle, buffer);
806  if (err != OMX_ErrorNone) {
808  av_log(avctx, AV_LOG_ERROR, "OMX_EmptyThisBuffer failed: %x\n", err);
809  return AVERROR_UNKNOWN;
810  }
811  } else if (!s->eos_sent) {
812  buffer = get_buffer(&s->input_mutex, &s->input_cond,
814 
815  buffer->nFilledLen = 0;
816  buffer->nFlags = OMX_BUFFERFLAG_EOS;
817  buffer->pAppPrivate = buffer->pOutputPortPrivate = NULL;
818  err = OMX_EmptyThisBuffer(s->handle, buffer);
819  if (err != OMX_ErrorNone) {
821  av_log(avctx, AV_LOG_ERROR, "OMX_EmptyThisBuffer failed: %x\n", err);
822  return AVERROR_UNKNOWN;
823  }
824  s->eos_sent = 1;
825  }
826 
827  while (!*got_packet && ret == 0 && !s->got_eos) {
828  // If not flushing, just poll the queue if there's finished packets.
829  // If flushing, do a blocking wait until we either get a completed
830  // packet, or get EOS.
831  buffer = get_buffer(&s->output_mutex, &s->output_cond,
833  !frame);
834  if (!buffer)
835  break;
836 
837  if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
838  s->got_eos = 1;
839 
840  if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG && avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
841  if ((ret = av_reallocp(&avctx->extradata, avctx->extradata_size + buffer->nFilledLen + AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
842  avctx->extradata_size = 0;
843  goto end;
844  }
845  memcpy(avctx->extradata + avctx->extradata_size, buffer->pBuffer + buffer->nOffset, buffer->nFilledLen);
846  avctx->extradata_size += buffer->nFilledLen;
847  memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
848  } else {
849  if (!(buffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) || !pkt->data) {
850  // If the output packet isn't preallocated, just concatenate everything in our
851  // own buffer
852  int newsize = s->output_buf_size + buffer->nFilledLen + AV_INPUT_BUFFER_PADDING_SIZE;
853  if ((ret = av_reallocp(&s->output_buf, newsize)) < 0) {
854  s->output_buf_size = 0;
855  goto end;
856  }
857  memcpy(s->output_buf + s->output_buf_size, buffer->pBuffer + buffer->nOffset, buffer->nFilledLen);
858  s->output_buf_size += buffer->nFilledLen;
859  if (buffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) {
860  if ((ret = av_packet_from_data(pkt, s->output_buf, s->output_buf_size)) < 0) {
861  av_freep(&s->output_buf);
862  s->output_buf_size = 0;
863  goto end;
864  }
865  s->output_buf = NULL;
866  s->output_buf_size = 0;
867  }
868  } else {
869  // End of frame, and the caller provided a preallocated frame
870  if ((ret = ff_alloc_packet2(avctx, pkt, s->output_buf_size + buffer->nFilledLen, 0)) < 0) {
871  av_log(avctx, AV_LOG_ERROR, "Error getting output packet of size %d.\n",
872  (int)(s->output_buf_size + buffer->nFilledLen));
873  goto end;
874  }
875  memcpy(pkt->data, s->output_buf, s->output_buf_size);
876  memcpy(pkt->data + s->output_buf_size, buffer->pBuffer + buffer->nOffset, buffer->nFilledLen);
877  av_freep(&s->output_buf);
878  s->output_buf_size = 0;
879  }
880  if (buffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) {
881  pkt->pts = av_rescale_q(from_omx_ticks(buffer->nTimeStamp), AV_TIME_BASE_Q, avctx->time_base);
882  // We don't currently enable B-frames for the encoders, so set
883  // pkt->dts = pkt->pts. (The calling code behaves worse if the encoder
884  // doesn't set the dts).
885  pkt->dts = pkt->pts;
886  if (buffer->nFlags & OMX_BUFFERFLAG_SYNCFRAME)
887  pkt->flags |= AV_PKT_FLAG_KEY;
888  *got_packet = 1;
889  }
890  }
891 end:
892  err = OMX_FillThisBuffer(s->handle, buffer);
893  if (err != OMX_ErrorNone) {
895  av_log(avctx, AV_LOG_ERROR, "OMX_FillThisBuffer failed: %x\n", err);
896  ret = AVERROR_UNKNOWN;
897  }
898  }
899  return ret;
900 }
901 
903 {
904  OMXCodecContext *s = avctx->priv_data;
905 
906  cleanup(s);
907  return 0;
908 }
909 
910 #define OFFSET(x) offsetof(OMXCodecContext, x)
911 #define VDE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM
912 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
913 static const AVOption options[] = {
914  { "omx_libname", "OpenMAX library name", OFFSET(libname), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VDE },
915  { "omx_libprefix", "OpenMAX library prefix", OFFSET(libprefix), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VDE },
916  { "zerocopy", "Try to avoid copying input frames if possible", OFFSET(input_zerocopy), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
917  { "profile", "Set the encoding profile", OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = FF_PROFILE_UNKNOWN }, FF_PROFILE_UNKNOWN, FF_PROFILE_H264_HIGH, VE, "profile" },
918  { "baseline", "", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_H264_BASELINE }, 0, 0, VE, "profile" },
919  { "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_H264_MAIN }, 0, 0, VE, "profile" },
920  { "high", "", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_H264_HIGH }, 0, 0, VE, "profile" },
921  { NULL }
922 };
923 
924 static const enum AVPixelFormat omx_encoder_pix_fmts[] = {
926 };
927 
928 static const AVClass omx_mpeg4enc_class = {
929  .class_name = "mpeg4_omx",
930  .item_name = av_default_item_name,
931  .option = options,
932  .version = LIBAVUTIL_VERSION_INT,
933 };
935  .name = "mpeg4_omx",
936  .long_name = NULL_IF_CONFIG_SMALL("OpenMAX IL MPEG-4 video encoder"),
937  .type = AVMEDIA_TYPE_VIDEO,
938  .id = AV_CODEC_ID_MPEG4,
939  .priv_data_size = sizeof(OMXCodecContext),
941  .encode2 = omx_encode_frame,
942  .close = omx_encode_end,
943  .pix_fmts = omx_encoder_pix_fmts,
944  .capabilities = AV_CODEC_CAP_DELAY,
946  .priv_class = &omx_mpeg4enc_class,
947 };
948 
949 static const AVClass omx_h264enc_class = {
950  .class_name = "h264_omx",
951  .item_name = av_default_item_name,
952  .option = options,
953  .version = LIBAVUTIL_VERSION_INT,
954 };
956  .name = "h264_omx",
957  .long_name = NULL_IF_CONFIG_SMALL("OpenMAX IL H.264 video encoder"),
958  .type = AVMEDIA_TYPE_VIDEO,
959  .id = AV_CODEC_ID_H264,
960  .priv_data_size = sizeof(OMXCodecContext),
962  .encode2 = omx_encode_frame,
963  .close = omx_encode_end,
964  .pix_fmts = omx_encoder_pix_fmts,
965  .capabilities = AV_CODEC_CAP_DELAY,
967  .priv_class = &omx_h264enc_class,
968 };
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: internal.h:48
#define FF_PROFILE_H264_MAIN
Definition: avcodec.h:2935
#define AVERROR_ENCODER_NOT_FOUND
Encoder not found.
Definition: error.h:54
#define NULL
Definition: coverity.c:32
const struct AVCodec * codec
Definition: avcodec.h:1574
AVRational framerate
Definition: avcodec.h:3101
#define VE
Definition: omx.c:912
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
Definition: os2threads.h:108
OMX_ERRORTYPE(* ptr_Deinit)(void)
Definition: omx.c:80
static AVMutex mutex
Definition: log.c:44
#define to_omx_ticks(x)
Definition: omx.c:60
This structure describes decoded (raw) audio or video data.
Definition: frame.h:268
#define pthread_mutex_lock(a)
Definition: ffprobe.c:61
static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
Definition: os2threads.h:166
AVOption.
Definition: opt.h:246
static av_cold int find_component(OMXContext *omx_context, void *logctx, const char *role, char *str, int str_size)
Definition: omx.c:338
misc image utilities
OMX_ERRORTYPE(* ptr_FreeHandle)(OMX_HANDLETYPE)
Definition: omx.c:83
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
int64_t bit_rate
the average bitrate
Definition: avcodec.h:1615
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
OMX_BUFFERHEADERTYPE ** in_buffer_headers
Definition: omx.c:205
int num
Numerator.
Definition: rational.h:59
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:411
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1775
Convenience header that includes libavutil&#39;s core.
static OMX_ERRORTYPE fill_buffer_done(OMX_HANDLETYPE component, OMX_PTR app_data, OMX_BUFFERHEADERTYPE *buffer)
Definition: omx.c:323
static av_cold int omx_encode_end(AVCodecContext *avctx)
Definition: omx.c:902
static OMX_BUFFERHEADERTYPE * get_buffer(pthread_mutex_t *mutex, pthread_cond_t *cond, int *array_size, OMX_BUFFERHEADERTYPE **array, int wait)
Definition: omx.c:242
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:236
static AVPacket pkt
#define src
Definition: vp8dsp.c:254
int profile
profile
Definition: avcodec.h:2894
AVCodec.
Definition: avcodec.h:3477
static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond)
Definition: os2threads.h:140
void * lib
Definition: omx.c:77
static OMX_ERRORTYPE empty_buffer_done(OMX_HANDLETYPE component, OMX_PTR app_data, OMX_BUFFERHEADERTYPE *buffer)
Definition: omx.c:305
int num_out_buffers
Definition: omx.c:204
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avcodec.h:1688
void * lib2
Definition: omx.c:78
static enum AVPixelFormat omx_encoder_pix_fmts[]
Definition: omx.c:924
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:72
#define AV_CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
Definition: avcodec.h:1006
int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int64_t min_size)
Check AVPacket size and/or allocate data.
Definition: encode.c:32
#define FF_PROFILE_H264_BASELINE
Definition: avcodec.h:2933
OMX_ERRORTYPE(* ptr_GetHandle)(OMX_HANDLETYPE *, OMX_STRING, OMX_PTR, OMX_CALLBACKTYPE *)
Definition: omx.c:82
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
Definition: internal.h:40
uint8_t
#define av_cold
Definition: attributes.h:82
#define av_malloc(s)
pthread_cond_t input_cond
Definition: omx.c:212
AVOptions.
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
OMX_BUFFERHEADERTYPE ** done_out_buffers
Definition: omx.c:210
GLsizei GLboolean const GLfloat * value
Definition: opengl_enc.c:108
int num_in_buffers
Definition: omx.c:204
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:361
int av_packet_from_data(AVPacket *pkt, uint8_t *data, int size)
Initialize a reference-counted packet from av_malloc()ed data.
Definition: avpacket.c:152
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1666
OMX_ERRORTYPE(* ptr_GetComponentsOfRole)(OMX_STRING, OMX_U32 *, OMX_U8 **)
Definition: omx.c:84
uint8_t * data
Definition: avcodec.h:1477
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:192
#define av_log(a,...)
int got_eos
Definition: omx.c:223
OMX_ERRORTYPE error
Definition: omx.c:219
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1509
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
H.264 common definitions.
int profile
Definition: omx.c:229
enum AVCodecID id
Definition: avcodec.h:3491
int av_image_get_buffer_size(enum AVPixelFormat pix_fmt, int width, int height, int align)
Return the size in bytes of the amount of data required to store an image with the given parameters...
Definition: imgutils.c:431
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:260
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
pthread_cond_t state_cond
Definition: omx.c:217
OMXContext * omx_context
Definition: omx.c:193
int out_port
Definition: omx.c:200
int mutex_cond_inited
Definition: omx.c:221
AVCodecContext * avctx
Definition: omx.c:195
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
static av_cold int wait_for_state(OMXCodecContext *s, OMX_STATETYPE state)
Definition: omx.c:375
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:1645
#define FF_PROFILE_H264_HIGH
Definition: avcodec.h:2937
pthread_mutex_t output_mutex
Definition: omx.c:213
#define VDE
Definition: omx.c:911
const char * name
Name of the codec implementation.
Definition: avcodec.h:3484
OMX_COLOR_FORMATTYPE color_format
Definition: omx.c:201
OMX_HANDLETYPE handle
Definition: omx.c:199
static void append_buffer(pthread_mutex_t *mutex, pthread_cond_t *cond, int *array_size, OMX_BUFFERHEADERTYPE **array, OMX_BUFFERHEADERTYPE *buffer)
Definition: omx.c:232
AVCodec ff_mpeg4_omx_encoder
Definition: omx.c:934
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
Definition: avstring.c:83
#define fail()
Definition: checkasm.h:120
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.
Definition: imgutils.c:387
static int omx_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet)
Definition: omx.c:735
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1483
static av_cold void * dlsym_prefixed(void *handle, const char *symbol, const char *prefix)
Definition: omx.c:89
OMX_BUFFERHEADERTYPE ** out_buffer_headers
Definition: omx.c:206
char * libname
Definition: omx.c:191
OMX_BUFFERHEADERTYPE ** free_in_buffers
Definition: omx.c:208
#define CHECK(x)
Definition: omx.c:68
int num_done_out_buffers
Definition: omx.c:209
int width
picture width / height.
Definition: avcodec.h:1738
typedef void(APIENTRY *FF_PFNGLACTIVETEXTUREPROC)(GLenum texture)
#define FF_PROFILE_UNKNOWN
Definition: avcodec.h:2895
static av_cold int omx_encode_init(AVCodecContext *avctx)
Definition: omx.c:639
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
Definition: os2threads.h:100
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 s(width, name)
Definition: cbs_vp9.c:257
static const AVOption options[]
Definition: omx.c:913
pthread_cond_t output_cond
Definition: omx.c:214
int output_buf_size
Definition: omx.c:226
static av_cold int omx_try_load(OMXContext *s, void *logctx, const char *libname, const char *prefix, const char *libname2)
Definition: omx.c:96
#define pthread_mutex_unlock(a)
Definition: ffprobe.c:65
OMX_ERRORTYPE(* ptr_Init)(void)
Definition: omx.c:79
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition: frame.c:540
static const AVClass omx_mpeg4enc_class
Definition: omx.c:928
OMX_VERSIONTYPE version
Definition: omx.c:198
int input_zerocopy
Definition: omx.c:228
#define AV_LOG_INFO
Standard information.
Definition: log.h:187
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
Definition: mem.c:163
Libavcodec external API header.
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:260
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:299
int eos_sent
Definition: omx.c:223
main external API structure.
Definition: avcodec.h:1565
OMX_ERRORTYPE(* ptr_ComponentNameEnum)(OMX_STRING, OMX_U32, OMX_U32)
Definition: omx.c:81
void * buf
Definition: avisynth_c.h:766
int extradata_size
Definition: avcodec.h:1667
Describe the class of an AVClass context structure.
Definition: log.h:67
#define OFFSET(x)
Definition: omx.c:910
char component_name[OMX_MAX_STRINGNAME_SIZE]
Definition: omx.c:197
static av_cold void omx_deinit(OMXContext *omx_context)
Definition: omx.c:180
#define snprintf
Definition: snprintf.h:34
static av_cold int omx_component_init(AVCodecContext *avctx, const char *role)
Definition: omx.c:387
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:275
mfxU16 profile
Definition: qsvenc.c:44
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:282
#define AV_CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
Definition: avcodec.h:904
static const OMX_CALLBACKTYPE callbacks
Definition: omx.c:332
static OMX_ERRORTYPE event_handler(OMX_HANDLETYPE component, OMX_PTR app_data, OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2, OMX_PTR event_data)
Definition: omx.c:263
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition: avcodec.h:1760
int(* cond)(enum AVPixelFormat pix_fmt)
Definition: pixdesc_query.c:28
int av_strstart(const char *str, const char *pfx, const char **ptr)
Return non-zero if pfx is a prefix of str.
Definition: avstring.c:34
OMX_STATETYPE state
Definition: omx.c:218
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
common internal api header.
_fmutex pthread_mutex_t
Definition: os2threads.h:49
common internal and external API header
int plane_size
Definition: omx.c:202
static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
Definition: os2threads.h:129
void(* host_init)(void)
Definition: omx.c:86
int in_port
Definition: omx.c:200
int den
Denominator.
Definition: rational.h:60
pthread_mutex_t input_mutex
Definition: omx.c:211
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:71
int stride
Definition: omx.c:202
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
Definition: avcodec.h:790
void * priv_data
Definition: avcodec.h:1592
pthread_mutex_t state_mutex
Definition: omx.c:216
#define av_free(p)
#define from_omx_ticks(x)
Definition: omx.c:61
#define INIT_STRUCT(x)
Definition: omx.c:64
static av_always_inline int pthread_cond_broadcast(pthread_cond_t *cond)
Definition: os2threads.h:158
static const AVClass omx_h264enc_class
Definition: omx.c:949
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed...
Definition: avcodec.h:1476
#define av_freep(p)
int num_free_in_buffers
Definition: omx.c:207
static int array[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:106
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
char * libprefix
Definition: omx.c:192
static av_cold void cleanup(OMXCodecContext *s)
Definition: omx.c:590
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
This structure stores compressed data.
Definition: avcodec.h:1454
AVCodec ff_h264_omx_encoder
Definition: omx.c:955
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1470
uint8_t * output_buf
Definition: omx.c:225
Definition: omx.c:76
GLuint buffer
Definition: opengl_enc.c:101
static struct @308 state
static av_cold OMXContext * omx_init(void *logctx, const char *libname, const char *prefix)
Definition: omx.c:140
OMX_ERRORTYPE(* ptr_GetRolesOfComponent)(OMX_STRING, OMX_U32 *, OMX_U8 **)
Definition: omx.c:85
void * av_mallocz_array(size_t nmemb, size_t size)
Definition: mem.c:191