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**);
86  void (*host_init)(void);
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 ||
128  !s->ptr_GetComponentsOfRole || !s->ptr_GetRolesOfComponent) {
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;
201  OMX_COLOR_FORMATTYPE color_format;
203 
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 
224 
225  uint8_t *output_buf;
227 
229  int profile;
231 
233  int* array_size, OMX_BUFFERHEADERTYPE **array,
234  OMX_BUFFERHEADERTYPE *buffer)
235 {
237  array[(*array_size)++] = buffer;
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;
248  if (wait) {
249  while (!*array_size)
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  }
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:
272  pthread_mutex_lock(&s->state_mutex);
273  av_log(s->avctx, AV_LOG_ERROR, "OMX error %"PRIx32"\n", (uint32_t) data1);
274  s->error = data1;
275  pthread_cond_broadcast(&s->state_cond);
276  pthread_mutex_unlock(&s->state_mutex);
277  break;
278  case OMX_EventCmdComplete:
279  if (data1 == OMX_CommandStateSet) {
280  pthread_mutex_lock(&s->state_mutex);
281  s->state = data2;
282  av_log(s->avctx, AV_LOG_VERBOSE, "OMX state changed to %"PRIu32"\n", (uint32_t) data2);
283  pthread_cond_broadcast(&s->state_cond);
284  pthread_mutex_unlock(&s->state_mutex);
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  }
318  append_buffer(&s->input_mutex, &s->input_cond,
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;
327  append_buffer(&s->output_mutex, &s->output_cond,
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;
378  pthread_mutex_lock(&s->state_mutex);
379  while (s->state != state && s->error == OMX_ErrorNone)
380  pthread_cond_wait(&s->state_cond, &s->state_mutex);
381  if (s->error != OMX_ErrorNone)
383  pthread_mutex_unlock(&s->state_mutex);
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 = (1LL << 16) * avctx->framerate.num / avctx->framerate.den;
477  else
478  in_port_params.format.video.xFramerate = (1LL << 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);
551  if (!s->in_buffer_headers || !s->free_in_buffers || !s->out_buffer_headers || !s->done_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++)
583  s->done_out_buffers[s->num_done_out_buffers++] = s->out_buffer_headers[i];
584  }
585  for (i = 0; i < s->num_in_buffers; i++)
586  s->free_in_buffers[s->num_free_in_buffers++] = s->in_buffer_headers[i];
587  return err != OMX_ErrorNone ? AVERROR_UNKNOWN : 0;
588 }
589 
591 {
592  int i, executing;
593 
594  pthread_mutex_lock(&s->state_mutex);
595  executing = s->state == OMX_StateExecuting;
596  pthread_mutex_unlock(&s->state_mutex);
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,
604  &s->num_free_in_buffers, s->free_in_buffers, 1);
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,
611  &s->num_done_out_buffers, s->done_out_buffers, 1);
612  OMX_FreeBuffer(s->handle, s->out_port, buffer);
613  }
614  wait_for_state(s, OMX_StateLoaded);
615  }
616  if (s->handle) {
617  s->omx_context->ptr_FreeHandle(s->handle);
618  s->handle = NULL;
619  }
620 
621  omx_deinit(s->omx_context);
622  s->omx_context = NULL;
623  if (s->mutex_cond_inited) {
624  pthread_cond_destroy(&s->state_cond);
625  pthread_mutex_destroy(&s->state_mutex);
626  pthread_cond_destroy(&s->input_cond);
627  pthread_mutex_destroy(&s->input_mutex);
628  pthread_cond_destroy(&s->output_cond);
629  pthread_mutex_destroy(&s->output_mutex);
630  s->mutex_cond_inited = 0;
631  }
632  av_freep(&s->in_buffer_headers);
633  av_freep(&s->out_buffer_headers);
634  av_freep(&s->free_in_buffers);
635  av_freep(&s->done_out_buffers);
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  s->omx_context = omx_init(avctx, s->libname, s->libprefix);
648  if (!s->omx_context)
650 
651  pthread_mutex_init(&s->state_mutex, NULL);
652  pthread_cond_init(&s->state_cond, NULL);
653  pthread_mutex_init(&s->input_mutex, NULL);
654  pthread_cond_init(&s->input_cond, NULL);
655  pthread_mutex_init(&s->output_mutex, NULL);
656  pthread_cond_init(&s->output_cond, NULL);
657  s->mutex_cond_inited = 1;
658  s->avctx = avctx;
659  s->state = OMX_StateLoaded;
660  s->error = OMX_ErrorNone;
661 
662  switch (avctx->codec->id) {
663  case AV_CODEC_ID_MPEG4:
664  role = "video_encoder.mpeg4";
665  break;
666  case AV_CODEC_ID_H264:
667  role = "video_encoder.avc";
668  break;
669  default:
670  return AVERROR(ENOSYS);
671  }
672 
673  if ((ret = find_component(s->omx_context, avctx, role, s->component_name, sizeof(s->component_name))) < 0)
674  goto fail;
675 
676  av_log(avctx, AV_LOG_INFO, "Using %s\n", s->component_name);
677 
678  if ((ret = omx_component_init(avctx, role)) < 0)
679  goto fail;
680 
681  if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
682  while (1) {
683  buffer = get_buffer(&s->output_mutex, &s->output_cond,
684  &s->num_done_out_buffers, s->done_out_buffers, 1);
685  if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
686  if ((ret = av_reallocp(&avctx->extradata, avctx->extradata_size + buffer->nFilledLen + AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
687  avctx->extradata_size = 0;
688  goto fail;
689  }
690  memcpy(avctx->extradata + avctx->extradata_size, buffer->pBuffer + buffer->nOffset, buffer->nFilledLen);
691  avctx->extradata_size += buffer->nFilledLen;
692  memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
693  }
694  err = OMX_FillThisBuffer(s->handle, buffer);
695  if (err != OMX_ErrorNone) {
696  append_buffer(&s->output_mutex, &s->output_cond,
697  &s->num_done_out_buffers, s->done_out_buffers, buffer);
698  av_log(avctx, AV_LOG_ERROR, "OMX_FillThisBuffer failed: %x\n", err);
700  goto fail;
701  }
702  if (avctx->codec->id == AV_CODEC_ID_H264) {
703  // For H.264, the extradata can be returned in two separate buffers
704  // (the videocore encoder on raspberry pi does this);
705  // therefore check that we have got both SPS and PPS before continuing.
706  int nals[32] = { 0 };
707  int i;
708  for (i = 0; i + 4 < avctx->extradata_size; i++) {
709  if (!avctx->extradata[i + 0] &&
710  !avctx->extradata[i + 1] &&
711  !avctx->extradata[i + 2] &&
712  avctx->extradata[i + 3] == 1) {
713  nals[avctx->extradata[i + 4] & 0x1f]++;
714  }
715  }
716  if (nals[H264_NAL_SPS] && nals[H264_NAL_PPS])
717  break;
718  } else {
719  if (avctx->extradata_size > 0)
720  break;
721  }
722  }
723  }
724 
725  return 0;
726 fail:
727  return ret;
728 }
729 
730 
732  const AVFrame *frame, int *got_packet)
733 {
734  OMXCodecContext *s = avctx->priv_data;
735  int ret = 0;
736  OMX_BUFFERHEADERTYPE* buffer;
737  OMX_ERRORTYPE err;
738  int had_partial = 0;
739 
740  if (frame) {
741  uint8_t *dst[4];
742  int linesize[4];
743  int need_copy;
744  buffer = get_buffer(&s->input_mutex, &s->input_cond,
745  &s->num_free_in_buffers, s->free_in_buffers, 1);
746 
747  buffer->nFilledLen = av_image_fill_arrays(dst, linesize, buffer->pBuffer, avctx->pix_fmt, s->stride, s->plane_size, 1);
748 
749  if (s->input_zerocopy) {
750  uint8_t *src[4] = { NULL };
751  int src_linesize[4];
752  av_image_fill_arrays(src, src_linesize, frame->data[0], avctx->pix_fmt, s->stride, s->plane_size, 1);
753  if (frame->linesize[0] == src_linesize[0] &&
754  frame->linesize[1] == src_linesize[1] &&
755  frame->linesize[2] == src_linesize[2] &&
756  frame->data[1] == src[1] &&
757  frame->data[2] == src[2]) {
758  // If the input frame happens to have all planes stored contiguously,
759  // with the right strides, just clone the frame and set the OMX
760  // buffer header to point to it
761  AVFrame *local = av_frame_clone(frame);
762  if (!local) {
763  // Return the buffer to the queue so it's not lost
764  append_buffer(&s->input_mutex, &s->input_cond, &s->num_free_in_buffers, s->free_in_buffers, buffer);
765  return AVERROR(ENOMEM);
766  } else {
767  buffer->pAppPrivate = local;
768  buffer->pOutputPortPrivate = NULL;
769  buffer->pBuffer = local->data[0];
770  need_copy = 0;
771  }
772  } else {
773  // If not, we need to allocate a new buffer with the right
774  // size and copy the input frame into it.
775  uint8_t *buf = NULL;
776  int image_buffer_size = av_image_get_buffer_size(avctx->pix_fmt, s->stride, s->plane_size, 1);
777  if (image_buffer_size >= 0)
778  buf = av_malloc(image_buffer_size);
779  if (!buf) {
780  // Return the buffer to the queue so it's not lost
781  append_buffer(&s->input_mutex, &s->input_cond, &s->num_free_in_buffers, s->free_in_buffers, buffer);
782  return AVERROR(ENOMEM);
783  } else {
784  buffer->pAppPrivate = buf;
785  // Mark that pAppPrivate is an av_malloc'ed buffer, not an AVFrame
786  buffer->pOutputPortPrivate = (void*) 1;
787  buffer->pBuffer = buf;
788  need_copy = 1;
789  buffer->nFilledLen = av_image_fill_arrays(dst, linesize, buffer->pBuffer, avctx->pix_fmt, s->stride, s->plane_size, 1);
790  }
791  }
792  } else {
793  need_copy = 1;
794  }
795  if (need_copy)
796  av_image_copy(dst, linesize, (const uint8_t**) frame->data, frame->linesize, avctx->pix_fmt, avctx->width, avctx->height);
797  buffer->nFlags = OMX_BUFFERFLAG_ENDOFFRAME;
798  buffer->nOffset = 0;
799  // Convert the timestamps to microseconds; some encoders can ignore
800  // the framerate and do VFR bit allocation based on timestamps.
801  buffer->nTimeStamp = to_omx_ticks(av_rescale_q(frame->pts, avctx->time_base, AV_TIME_BASE_Q));
802  if (frame->pict_type == AV_PICTURE_TYPE_I) {
803 #if CONFIG_OMX_RPI
804  OMX_CONFIG_BOOLEANTYPE config = {0, };
806  config.bEnabled = OMX_TRUE;
807  err = OMX_SetConfig(s->handle, OMX_IndexConfigBrcmVideoRequestIFrame, &config);
808  if (err != OMX_ErrorNone) {
809  av_log(avctx, AV_LOG_ERROR, "OMX_SetConfig(RequestIFrame) failed: %x\n", err);
810  }
811 #else
812  OMX_CONFIG_INTRAREFRESHVOPTYPE config = {0, };
814  config.nPortIndex = s->out_port;
815  config.IntraRefreshVOP = OMX_TRUE;
816  err = OMX_SetConfig(s->handle, OMX_IndexConfigVideoIntraVOPRefresh, &config);
817  if (err != OMX_ErrorNone) {
818  av_log(avctx, AV_LOG_ERROR, "OMX_SetConfig(IntraVOPRefresh) failed: %x\n", err);
819  }
820 #endif
821  }
822  err = OMX_EmptyThisBuffer(s->handle, buffer);
823  if (err != OMX_ErrorNone) {
824  append_buffer(&s->input_mutex, &s->input_cond, &s->num_free_in_buffers, s->free_in_buffers, buffer);
825  av_log(avctx, AV_LOG_ERROR, "OMX_EmptyThisBuffer failed: %x\n", err);
826  return AVERROR_UNKNOWN;
827  }
828  } else if (!s->eos_sent) {
829  buffer = get_buffer(&s->input_mutex, &s->input_cond,
830  &s->num_free_in_buffers, s->free_in_buffers, 1);
831 
832  buffer->nFilledLen = 0;
833  buffer->nFlags = OMX_BUFFERFLAG_EOS;
834  buffer->pAppPrivate = buffer->pOutputPortPrivate = NULL;
835  err = OMX_EmptyThisBuffer(s->handle, buffer);
836  if (err != OMX_ErrorNone) {
837  append_buffer(&s->input_mutex, &s->input_cond, &s->num_free_in_buffers, s->free_in_buffers, buffer);
838  av_log(avctx, AV_LOG_ERROR, "OMX_EmptyThisBuffer failed: %x\n", err);
839  return AVERROR_UNKNOWN;
840  }
841  s->eos_sent = 1;
842  }
843 
844  while (!*got_packet && ret == 0 && !s->got_eos) {
845  // If not flushing, just poll the queue if there's finished packets.
846  // If flushing, do a blocking wait until we either get a completed
847  // packet, or get EOS.
848  buffer = get_buffer(&s->output_mutex, &s->output_cond,
849  &s->num_done_out_buffers, s->done_out_buffers,
850  !frame || had_partial);
851  if (!buffer)
852  break;
853 
854  if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
855  s->got_eos = 1;
856 
857  if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG && avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
858  if ((ret = av_reallocp(&avctx->extradata, avctx->extradata_size + buffer->nFilledLen + AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
859  avctx->extradata_size = 0;
860  goto end;
861  }
862  memcpy(avctx->extradata + avctx->extradata_size, buffer->pBuffer + buffer->nOffset, buffer->nFilledLen);
863  avctx->extradata_size += buffer->nFilledLen;
864  memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
865  } else {
866  if (!(buffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) || !pkt->data) {
867  // If the output packet isn't preallocated, just concatenate everything in our
868  // own buffer
869  int newsize = s->output_buf_size + buffer->nFilledLen + AV_INPUT_BUFFER_PADDING_SIZE;
870  if ((ret = av_reallocp(&s->output_buf, newsize)) < 0) {
871  s->output_buf_size = 0;
872  goto end;
873  }
874  memcpy(s->output_buf + s->output_buf_size, buffer->pBuffer + buffer->nOffset, buffer->nFilledLen);
875  s->output_buf_size += buffer->nFilledLen;
876  if (buffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) {
877  if ((ret = av_packet_from_data(pkt, s->output_buf, s->output_buf_size)) < 0) {
878  av_freep(&s->output_buf);
879  s->output_buf_size = 0;
880  goto end;
881  }
882  s->output_buf = NULL;
883  s->output_buf_size = 0;
884  }
885 #if CONFIG_OMX_RPI
886  had_partial = 1;
887 #endif
888  } else {
889  // End of frame, and the caller provided a preallocated frame
890  if ((ret = ff_alloc_packet2(avctx, pkt, s->output_buf_size + buffer->nFilledLen, 0)) < 0) {
891  av_log(avctx, AV_LOG_ERROR, "Error getting output packet of size %d.\n",
892  (int)(s->output_buf_size + buffer->nFilledLen));
893  goto end;
894  }
895  memcpy(pkt->data, s->output_buf, s->output_buf_size);
896  memcpy(pkt->data + s->output_buf_size, buffer->pBuffer + buffer->nOffset, buffer->nFilledLen);
897  av_freep(&s->output_buf);
898  s->output_buf_size = 0;
899  }
900  if (buffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) {
902  // We don't currently enable B-frames for the encoders, so set
903  // pkt->dts = pkt->pts. (The calling code behaves worse if the encoder
904  // doesn't set the dts).
905  pkt->dts = pkt->pts;
906  if (buffer->nFlags & OMX_BUFFERFLAG_SYNCFRAME)
908  *got_packet = 1;
909  }
910  }
911 end:
912  err = OMX_FillThisBuffer(s->handle, buffer);
913  if (err != OMX_ErrorNone) {
914  append_buffer(&s->output_mutex, &s->output_cond, &s->num_done_out_buffers, s->done_out_buffers, buffer);
915  av_log(avctx, AV_LOG_ERROR, "OMX_FillThisBuffer failed: %x\n", err);
917  }
918  }
919  return ret;
920 }
921 
923 {
924  OMXCodecContext *s = avctx->priv_data;
925 
926  cleanup(s);
927  return 0;
928 }
929 
930 #define OFFSET(x) offsetof(OMXCodecContext, x)
931 #define VDE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM
932 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
933 static const AVOption options[] = {
934  { "omx_libname", "OpenMAX library name", OFFSET(libname), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VDE },
935  { "omx_libprefix", "OpenMAX library prefix", OFFSET(libprefix), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VDE },
936  { "zerocopy", "Try to avoid copying input frames if possible", OFFSET(input_zerocopy), AV_OPT_TYPE_INT, { .i64 = CONFIG_OMX_RPI }, 0, 1, VE },
937  { "profile", "Set the encoding profile", OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = FF_PROFILE_UNKNOWN }, FF_PROFILE_UNKNOWN, FF_PROFILE_H264_HIGH, VE, "profile" },
938  { "baseline", "", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_H264_BASELINE }, 0, 0, VE, "profile" },
939  { "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_H264_MAIN }, 0, 0, VE, "profile" },
940  { "high", "", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_H264_HIGH }, 0, 0, VE, "profile" },
941  { NULL }
942 };
943 
944 static const enum AVPixelFormat omx_encoder_pix_fmts[] = {
946 };
947 
948 static const AVClass omx_mpeg4enc_class = {
949  .class_name = "mpeg4_omx",
950  .item_name = av_default_item_name,
951  .option = options,
952  .version = LIBAVUTIL_VERSION_INT,
953 };
955  .name = "mpeg4_omx",
956  .long_name = NULL_IF_CONFIG_SMALL("OpenMAX IL MPEG-4 video encoder"),
957  .type = AVMEDIA_TYPE_VIDEO,
958  .id = AV_CODEC_ID_MPEG4,
959  .priv_data_size = sizeof(OMXCodecContext),
961  .encode2 = omx_encode_frame,
962  .close = omx_encode_end,
964  .capabilities = AV_CODEC_CAP_DELAY,
966  .priv_class = &omx_mpeg4enc_class,
967 };
968 
969 static const AVClass omx_h264enc_class = {
970  .class_name = "h264_omx",
971  .item_name = av_default_item_name,
972  .option = options,
973  .version = LIBAVUTIL_VERSION_INT,
974 };
976  .name = "h264_omx",
977  .long_name = NULL_IF_CONFIG_SMALL("OpenMAX IL H.264 video encoder"),
978  .type = AVMEDIA_TYPE_VIDEO,
979  .id = AV_CODEC_ID_H264,
980  .priv_data_size = sizeof(OMXCodecContext),
982  .encode2 = omx_encode_frame,
983  .close = omx_encode_end,
985  .capabilities = AV_CODEC_CAP_DELAY,
987  .priv_class = &omx_h264enc_class,
988 };
pthread_mutex_t
_fmutex pthread_mutex_t
Definition: os2threads.h:53
OMXCodecContext::done_out_buffers
OMX_BUFFERHEADERTYPE ** done_out_buffers
Definition: omx.c:210
AVCodec
AVCodec.
Definition: codec.h:197
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:187
FF_CODEC_CAP_INIT_THREADSAFE
#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:41
cleanup
static av_cold void cleanup(OMXCodecContext *s)
Definition: omx.c:590
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
OMXCodecContext::output_buf_size
int output_buf_size
Definition: omx.c:226
INIT_STRUCT
#define INIT_STRUCT(x)
Definition: omx.c:64
init
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:31
ff_h264_omx_encoder
const AVCodec ff_h264_omx_encoder
Definition: omx.c:975
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
OMXContext::ptr_GetRolesOfComponent
OMX_ERRORTYPE(* ptr_GetRolesOfComponent)(OMX_STRING, OMX_U32 *, OMX_U8 **)
Definition: omx.c:85
FF_PROFILE_H264_BASELINE
#define FF_PROFILE_H264_BASELINE
Definition: avcodec.h:1670
pthread_mutex_init
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
Definition: os2threads.h:104
omx_component_init
static av_cold int omx_component_init(AVCodecContext *avctx, const char *role)
Definition: omx.c:387
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:260
get_buffer
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
OMXCodecContext::eos_sent
int eos_sent
Definition: omx.c:223
state
static struct @321 state
AV_CODEC_ID_MPEG4
@ AV_CODEC_ID_MPEG4
Definition: codec_id.h:61
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:111
profile
mfxU16 profile
Definition: qsvenc.c:45
callbacks
static const OMX_CALLBACKTYPE callbacks
Definition: omx.c:332
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:303
OMXCodecContext::out_buffer_headers
OMX_BUFFERHEADERTYPE ** out_buffer_headers
Definition: omx.c:206
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:365
OMXCodecContext
Definition: omx.c:189
AVOption
AVOption.
Definition: opt.h:248
empty_buffer_done
static OMX_ERRORTYPE empty_buffer_done(OMX_HANDLETYPE component, OMX_PTR app_data, OMX_BUFFERHEADERTYPE *buffer)
Definition: omx.c:305
OMXCodecContext::omx_context
OMXContext * omx_context
Definition: omx.c:193
OMXContext
Definition: omx.c:76
av_mallocz_array
void * av_mallocz_array(size_t nmemb, size_t size)
Definition: mem.c:196
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:197
OMXCodecContext::state
OMX_STATETYPE state
Definition: omx.c:218
OMXCodecContext::input_zerocopy
int input_zerocopy
Definition: omx.c:228
AVERROR_UNKNOWN
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:71
tf_sess_config.config
config
Definition: tf_sess_config.py:33
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:396
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:317
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
AV_CODEC_FLAG_GLOBAL_HEADER
#define AV_CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
Definition: avcodec.h:306
OMXCodecContext::mutex_cond_inited
int mutex_cond_inited
Definition: omx.c:221
AVCodecContext::framerate
AVRational framerate
Definition: avcodec.h:1816
OMXCodecContext::out_port
int out_port
Definition: omx.c:200
OMXCodecContext::state_mutex
pthread_mutex_t state_mutex
Definition: omx.c:216
dlsym_prefixed
static av_cold void * dlsym_prefixed(void *handle, const char *symbol, const char *prefix)
Definition: omx.c:89
AVCodecContext::codec
const struct AVCodec * codec
Definition: avcodec.h:510
OMXCodecContext::libname
char * libname
Definition: omx.c:191
fail
#define fail()
Definition: checkasm.h:134
OMXCodecContext::version
OMX_VERSIONTYPE version
Definition: omx.c:198
omx_encoder_pix_fmts
static enum AVPixelFormat omx_encoder_pix_fmts[]
Definition: omx.c:944
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:581
FF_PROFILE_H264_HIGH
#define FF_PROFILE_H264_HIGH
Definition: avcodec.h:1674
OMXCodecContext::plane_size
int plane_size
Definition: omx.c:202
OMXCodecContext::input_mutex
pthread_mutex_t input_mutex
Definition: omx.c:211
AVRational::num
int num
Numerator.
Definition: rational.h:59
OMXCodecContext::stride
int stride
Definition: omx.c:202
OMXContext::ptr_GetHandle
OMX_ERRORTYPE(* ptr_GetHandle)(OMX_HANDLETYPE *, OMX_STRING, OMX_PTR, OMX_CALLBACKTYPE *)
Definition: omx.c:82
OMXContext::lib
void * lib
Definition: omx.c:77
pkt
AVPacket * pkt
Definition: movenc.c:59
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:181
av_cold
#define av_cold
Definition: attributes.h:90
OMXContext::lib2
void * lib2
Definition: omx.c:78
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:603
s
#define s(width, name)
Definition: cbs_vp9.c:257
OMXCodecContext::free_in_buffers
OMX_BUFFERHEADERTYPE ** free_in_buffers
Definition: omx.c:208
OMXContext::ptr_GetComponentsOfRole
OMX_ERRORTYPE(* ptr_GetComponentsOfRole)(OMX_STRING, OMX_U32 *, OMX_U8 **)
Definition: omx.c:84
FF_PROFILE_UNKNOWN
#define FF_PROFILE_UNKNOWN
Definition: avcodec.h:1632
OFFSET
#define OFFSET(x)
Definition: omx.c:930
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:289
av_frame_clone
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition: frame.c:423
av_rescale_q
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
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
pthread_cond_broadcast
static av_always_inline int pthread_cond_broadcast(pthread_cond_t *cond)
Definition: os2threads.h:162
OMXCodecContext::input_cond
pthread_cond_t input_cond
Definition: omx.c:212
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:76
OMXCodecContext::num_in_buffers
int num_in_buffers
Definition: omx.c:204
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
NULL
#define NULL
Definition: coverity.c:32
AVCodecContext::bit_rate
int64_t bit_rate
the average bitrate
Definition: avcodec.h:551
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:274
src
#define src
Definition: vp8dsp.c:255
VDE
#define VDE
Definition: omx.c:931
append_buffer
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
OMXContext::ptr_Init
OMX_ERRORTYPE(* ptr_Init)(void)
Definition: omx.c:79
pthread_mutex_unlock
#define pthread_mutex_unlock(a)
Definition: ffprobe.c:67
OMXCodecContext::output_buf
uint8_t * output_buf
Definition: omx.c:225
H264_NAL_SPS
@ H264_NAL_SPS
Definition: h264.h:41
AVCodecContext::time_base
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition: avcodec.h:624
event_handler
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
av_packet_from_data
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:161
OMXCodecContext::num_free_in_buffers
int num_free_in_buffers
Definition: omx.c:207
OMXCodecContext::in_buffer_headers
OMX_BUFFERHEADERTYPE ** in_buffer_headers
Definition: omx.c:205
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
AVCodecContext::gop_size
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition: avcodec.h:696
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:443
ff_mpeg4_omx_encoder
const AVCodec ff_mpeg4_omx_encoder
Definition: omx.c:954
OMXCodecContext::in_port
int in_port
Definition: omx.c:200
OMXContext::ptr_ComponentNameEnum
OMX_ERRORTYPE(* ptr_ComponentNameEnum)(OMX_STRING, OMX_U32, OMX_U32)
Definition: omx.c:81
av_reallocp
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:167
options
static const AVOption options[]
Definition: omx.c:933
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:364
av_image_get_buffer_size
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:463
omx_try_load
static av_cold int omx_try_load(OMXContext *s, void *logctx, const char *libname, const char *prefix, const char *libname2)
Definition: omx.c:96
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:371
av_strstart
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_h264enc_class
static const AVClass omx_h264enc_class
Definition: omx.c:969
pthread_cond_destroy
static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond)
Definition: os2threads.h:144
OMXCodecContext::num_out_buffers
int num_out_buffers
Definition: omx.c:204
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:192
OMXCodecContext::avctx
AVCodecContext * avctx
Definition: omx.c:195
AVCodec::id
enum AVCodecID id
Definition: codec.h:211
pthread_mutex_destroy
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
Definition: os2threads.h:112
CHECK
#define CHECK(x)
Definition: omx.c:68
i
int i
Definition: input.c:407
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:358
AVCodecContext::extradata
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:602
FF_CODEC_CAP_INIT_CLEANUP
#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:49
OMXCodecContext::libprefix
char * libprefix
Definition: omx.c:192
omx_encode_frame
static int omx_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet)
Definition: omx.c:731
OMXCodecContext::output_mutex
pthread_mutex_t output_mutex
Definition: omx.c:213
to_omx_ticks
#define to_omx_ticks(x)
Definition: omx.c:60
common.h
OMXContext::host_init
void(* host_init)(void)
Definition: omx.c:86
value
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf default value
Definition: writing_filters.txt:86
find_component
static av_cold int find_component(OMXContext *omx_context, void *logctx, const char *role, char *str, int str_size)
Definition: omx.c:338
from_omx_ticks
#define from_omx_ticks(x)
Definition: omx.c:61
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:243
OMXCodecContext::output_cond
pthread_cond_t output_cond
Definition: omx.c:214
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:204
pthread_cond_t
Definition: os2threads.h:58
AVCodecContext::height
int height
Definition: avcodec.h:674
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:711
avcodec.h
wait_for_state
static av_cold int wait_for_state(OMXCodecContext *s, OMX_STATETYPE state)
Definition: omx.c:375
array
static int array[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:106
ret
ret
Definition: filter_design.txt:187
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:72
frame
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
Definition: filter_design.txt:264
omx_encode_init
static av_cold int omx_encode_init(AVCodecContext *avctx)
Definition: omx.c:639
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: avcodec.h:192
omx_deinit
static av_cold void omx_deinit(OMXContext *omx_context)
Definition: omx.c:180
OMXCodecContext::color_format
OMX_COLOR_FORMATTYPE color_format
Definition: omx.c:201
OMXCodecContext::got_eos
int got_eos
Definition: omx.c:223
AVCodecContext
main external API structure.
Definition: avcodec.h:501
av_image_copy
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:419
OMXCodecContext::error
OMX_ERRORTYPE error
Definition: omx.c:219
omx_encode_end
static av_cold int omx_encode_end(AVCodecContext *avctx)
Definition: omx.c:922
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
AVRational::den
int den
Denominator.
Definition: rational.h:60
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1631
omx_init
static av_cold OMXContext * omx_init(void *logctx, const char *libname, const char *prefix)
Definition: omx.c:140
omx_mpeg4enc_class
static const AVClass omx_mpeg4enc_class
Definition: omx.c:948
AV_CODEC_CAP_DELAY
#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: codec.h:77
FF_PROFILE_H264_MAIN
#define FF_PROFILE_H264_MAIN
Definition: avcodec.h:1672
pthread_cond_wait
static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
Definition: os2threads.h:192
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AVERROR_ENCODER_NOT_FOUND
#define AVERROR_ENCODER_NOT_FOUND
Encoder not found.
Definition: error.h:54
avutil.h
H264_NAL_PPS
@ H264_NAL_PPS
Definition: h264.h:42
OMXCodecContext::handle
OMX_HANDLETYPE handle
Definition: omx.c:199
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AVPacket
This structure stores compressed data.
Definition: packet.h:342
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:528
OMXCodecContext::profile
int profile
Definition: omx.c:229
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
OMXContext::ptr_Deinit
OMX_ERRORTYPE(* ptr_Deinit)(void)
Definition: omx.c:80
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:674
convert_header.str
string str
Definition: convert_header.py:20
h264.h
imgutils.h
av_strlcpy
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
OMXCodecContext::state_cond
pthread_cond_t state_cond
Definition: omx.c:217
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
pthread_cond_init
static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
Definition: os2threads.h:133
avstring.h
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:229
ff_alloc_packet2
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:33
OMXCodecContext::num_done_out_buffers
int num_done_out_buffers
Definition: omx.c:209
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:234
snprintf
#define snprintf
Definition: snprintf.h:34
OMXCodecContext::component_name
char component_name[OMX_MAX_STRINGNAME_SIZE]
Definition: omx.c:197
cond
int(* cond)(enum AVPixelFormat pix_fmt)
Definition: pixdesc_query.c:28
VE
#define VE
Definition: omx.c:932
mutex
static AVMutex mutex
Definition: log.c:44
fill_buffer_done
static OMX_ERRORTYPE fill_buffer_done(OMX_HANDLETYPE component, OMX_PTR app_data, OMX_BUFFERHEADERTYPE *buffer)
Definition: omx.c:323
pthread_mutex_lock
#define pthread_mutex_lock(a)
Definition: ffprobe.c:63
OMXContext::ptr_FreeHandle
OMX_ERRORTYPE(* ptr_FreeHandle)(OMX_HANDLETYPE)
Definition: omx.c:83