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/mem.h"
42 #include "libavutil/opt.h"
43 
44 #include "avcodec.h"
45 #include "codec_internal.h"
46 #include "h264.h"
47 #include "pthread_internal.h"
48 
49 #ifdef OMX_SKIP64BIT
50 static OMX_TICKS to_omx_ticks(int64_t value)
51 {
52  OMX_TICKS s;
53  s.nLowPart = value & 0xffffffff;
54  s.nHighPart = value >> 32;
55  return s;
56 }
57 static int64_t from_omx_ticks(OMX_TICKS value)
58 {
59  return (((int64_t)value.nHighPart) << 32) | value.nLowPart;
60 }
61 #else
62 #define to_omx_ticks(x) (x)
63 #define from_omx_ticks(x) (x)
64 #endif
65 
66 #define INIT_STRUCT(x) do { \
67  x.nSize = sizeof(x); \
68  x.nVersion = s->version; \
69  } while (0)
70 #define CHECK(x) do { \
71  if (x != OMX_ErrorNone) { \
72  av_log(avctx, AV_LOG_ERROR, \
73  "err %x (%d) on line %d\n", x, x, __LINE__); \
74  return AVERROR_UNKNOWN; \
75  } \
76  } while (0)
77 
78 typedef struct OMXContext {
79  void *lib;
80  void *lib2;
81  OMX_ERRORTYPE (*ptr_Init)(void);
82  OMX_ERRORTYPE (*ptr_Deinit)(void);
83  OMX_ERRORTYPE (*ptr_ComponentNameEnum)(OMX_STRING, OMX_U32, OMX_U32);
84  OMX_ERRORTYPE (*ptr_GetHandle)(OMX_HANDLETYPE*, OMX_STRING, OMX_PTR, OMX_CALLBACKTYPE*);
85  OMX_ERRORTYPE (*ptr_FreeHandle)(OMX_HANDLETYPE);
86  OMX_ERRORTYPE (*ptr_GetComponentsOfRole)(OMX_STRING, OMX_U32*, OMX_U8**);
87  OMX_ERRORTYPE (*ptr_GetRolesOfComponent)(OMX_STRING, OMX_U32*, OMX_U8**);
88  void (*host_init)(void);
89 } OMXContext;
90 
91 static av_cold void *dlsym_prefixed(void *handle, const char *symbol, const char *prefix)
92 {
93  char buf[50];
94  snprintf(buf, sizeof(buf), "%s%s", prefix ? prefix : "", symbol);
95  return dlsym(handle, buf);
96 }
97 
98 static av_cold int omx_try_load(OMXContext *s, void *logctx,
99  const char *libname, const char *prefix,
100  const char *libname2)
101 {
102  if (libname2) {
103  s->lib2 = dlopen(libname2, RTLD_NOW | RTLD_GLOBAL);
104  if (!s->lib2) {
105  av_log(logctx, AV_LOG_WARNING, "%s not found\n", libname2);
107  }
108  s->host_init = dlsym(s->lib2, "bcm_host_init");
109  if (!s->host_init) {
110  av_log(logctx, AV_LOG_WARNING, "bcm_host_init not found\n");
111  dlclose(s->lib2);
112  s->lib2 = NULL;
114  }
115  }
116  s->lib = dlopen(libname, RTLD_NOW | RTLD_GLOBAL);
117  if (!s->lib) {
118  av_log(logctx, AV_LOG_WARNING, "%s not found\n", libname);
120  }
121  s->ptr_Init = dlsym_prefixed(s->lib, "OMX_Init", prefix);
122  s->ptr_Deinit = dlsym_prefixed(s->lib, "OMX_Deinit", prefix);
123  s->ptr_ComponentNameEnum = dlsym_prefixed(s->lib, "OMX_ComponentNameEnum", prefix);
124  s->ptr_GetHandle = dlsym_prefixed(s->lib, "OMX_GetHandle", prefix);
125  s->ptr_FreeHandle = dlsym_prefixed(s->lib, "OMX_FreeHandle", prefix);
126  s->ptr_GetComponentsOfRole = dlsym_prefixed(s->lib, "OMX_GetComponentsOfRole", prefix);
127  s->ptr_GetRolesOfComponent = dlsym_prefixed(s->lib, "OMX_GetRolesOfComponent", prefix);
128  if (!s->ptr_Init || !s->ptr_Deinit || !s->ptr_ComponentNameEnum ||
129  !s->ptr_GetHandle || !s->ptr_FreeHandle ||
130  !s->ptr_GetComponentsOfRole || !s->ptr_GetRolesOfComponent) {
131  av_log(logctx, AV_LOG_WARNING, "Not all functions found in %s\n", libname);
132  dlclose(s->lib);
133  s->lib = NULL;
134  if (s->lib2)
135  dlclose(s->lib2);
136  s->lib2 = NULL;
138  }
139  return 0;
140 }
141 
142 static av_cold OMXContext *omx_init(void *logctx, const char *libname, const char *prefix)
143 {
144  static const char * const libnames[] = {
145 #if CONFIG_OMX_RPI
146  "/opt/vc/lib/libopenmaxil.so", "/opt/vc/lib/libbcm_host.so",
147 #else
148  "libOMX_Core.so", NULL,
149  "libOmxCore.so", NULL,
150 #endif
151  NULL
152  };
153  const char* const* nameptr;
155  OMXContext *omx_context;
156 
157  omx_context = av_mallocz(sizeof(*omx_context));
158  if (!omx_context)
159  return NULL;
160  if (libname) {
161  ret = omx_try_load(omx_context, logctx, libname, prefix, NULL);
162  if (ret < 0) {
163  av_free(omx_context);
164  return NULL;
165  }
166  } else {
167  for (nameptr = libnames; *nameptr; nameptr += 2)
168  if (!(ret = omx_try_load(omx_context, logctx, nameptr[0], prefix, nameptr[1])))
169  break;
170  if (!*nameptr) {
171  av_free(omx_context);
172  return NULL;
173  }
174  }
175 
176  if (omx_context->host_init)
177  omx_context->host_init();
178  omx_context->ptr_Init();
179  return omx_context;
180 }
181 
182 static av_cold void omx_deinit(OMXContext *omx_context)
183 {
184  if (!omx_context)
185  return;
186  omx_context->ptr_Deinit();
187  dlclose(omx_context->lib);
188  av_free(omx_context);
189 }
190 
191 typedef struct OMXCodecContext {
192  const AVClass *class;
193  char *libname;
194  char *libprefix;
196 
198 
199  char component_name[OMX_MAX_STRINGNAME_SIZE];
200  OMX_VERSIONTYPE version;
201  OMX_HANDLETYPE handle;
203  OMX_COLOR_FORMATTYPE color_format;
205 
207  OMX_BUFFERHEADERTYPE **in_buffer_headers;
208  OMX_BUFFERHEADERTYPE **out_buffer_headers;
210  OMX_BUFFERHEADERTYPE **free_in_buffers;
212  OMX_BUFFERHEADERTYPE **done_out_buffers;
217 
220  OMX_STATETYPE state;
221  OMX_ERRORTYPE error;
222 
224 
226 
227  uint8_t *output_buf;
229 
231  int profile;
233 
234 #define NB_MUTEX_CONDS 6
235 #define OFF(field) offsetof(OMXCodecContext, field)
236 DEFINE_OFFSET_ARRAY(OMXCodecContext, omx_codec_context, mutex_cond_inited_cnt,
237  (OFF(input_mutex), OFF(output_mutex), OFF(state_mutex)),
238  (OFF(input_cond), OFF(output_cond), OFF(state_cond)));
239 
241  int* array_size, OMX_BUFFERHEADERTYPE **array,
242  OMX_BUFFERHEADERTYPE *buffer)
243 {
245  array[(*array_size)++] = buffer;
248 }
249 
250 static OMX_BUFFERHEADERTYPE *get_buffer(pthread_mutex_t *mutex, pthread_cond_t *cond,
251  int* array_size, OMX_BUFFERHEADERTYPE **array,
252  int wait)
253 {
254  OMX_BUFFERHEADERTYPE *buffer;
256  if (wait) {
257  while (!*array_size)
259  }
260  if (*array_size > 0) {
261  buffer = array[0];
262  (*array_size)--;
263  memmove(&array[0], &array[1], (*array_size) * sizeof(OMX_BUFFERHEADERTYPE*));
264  } else {
265  buffer = NULL;
266  }
268  return buffer;
269 }
270 
271 static OMX_ERRORTYPE event_handler(OMX_HANDLETYPE component, OMX_PTR app_data, OMX_EVENTTYPE event,
272  OMX_U32 data1, OMX_U32 data2, OMX_PTR event_data)
273 {
274  OMXCodecContext *s = app_data;
275  // This uses casts in the printfs, since OMX_U32 actually is a typedef for
276  // unsigned long in official header versions (but there are also modified
277  // versions where it is something else).
278  switch (event) {
279  case OMX_EventError:
280  pthread_mutex_lock(&s->state_mutex);
281  av_log(s->avctx, AV_LOG_ERROR, "OMX error %"PRIx32"\n", (uint32_t) data1);
282  s->error = data1;
283  pthread_cond_broadcast(&s->state_cond);
284  pthread_mutex_unlock(&s->state_mutex);
285  break;
286  case OMX_EventCmdComplete:
287  if (data1 == OMX_CommandStateSet) {
288  pthread_mutex_lock(&s->state_mutex);
289  s->state = data2;
290  av_log(s->avctx, AV_LOG_VERBOSE, "OMX state changed to %"PRIu32"\n", (uint32_t) data2);
291  pthread_cond_broadcast(&s->state_cond);
292  pthread_mutex_unlock(&s->state_mutex);
293  } else if (data1 == OMX_CommandPortDisable) {
294  av_log(s->avctx, AV_LOG_VERBOSE, "OMX port %"PRIu32" disabled\n", (uint32_t) data2);
295  } else if (data1 == OMX_CommandPortEnable) {
296  av_log(s->avctx, AV_LOG_VERBOSE, "OMX port %"PRIu32" enabled\n", (uint32_t) data2);
297  } else {
298  av_log(s->avctx, AV_LOG_VERBOSE, "OMX command complete, command %"PRIu32", value %"PRIu32"\n",
299  (uint32_t) data1, (uint32_t) data2);
300  }
301  break;
302  case OMX_EventPortSettingsChanged:
303  av_log(s->avctx, AV_LOG_VERBOSE, "OMX port %"PRIu32" settings changed\n", (uint32_t) data1);
304  break;
305  default:
306  av_log(s->avctx, AV_LOG_VERBOSE, "OMX event %d %"PRIx32" %"PRIx32"\n",
307  event, (uint32_t) data1, (uint32_t) data2);
308  break;
309  }
310  return OMX_ErrorNone;
311 }
312 
313 static OMX_ERRORTYPE empty_buffer_done(OMX_HANDLETYPE component, OMX_PTR app_data,
314  OMX_BUFFERHEADERTYPE *buffer)
315 {
316  OMXCodecContext *s = app_data;
317  if (s->input_zerocopy) {
318  if (buffer->pAppPrivate) {
319  if (buffer->pOutputPortPrivate)
320  av_free(buffer->pAppPrivate);
321  else
322  av_frame_free((AVFrame**)&buffer->pAppPrivate);
323  buffer->pAppPrivate = NULL;
324  }
325  }
326  append_buffer(&s->input_mutex, &s->input_cond,
327  &s->num_free_in_buffers, s->free_in_buffers, buffer);
328  return OMX_ErrorNone;
329 }
330 
331 static OMX_ERRORTYPE fill_buffer_done(OMX_HANDLETYPE component, OMX_PTR app_data,
332  OMX_BUFFERHEADERTYPE *buffer)
333 {
334  OMXCodecContext *s = app_data;
335  append_buffer(&s->output_mutex, &s->output_cond,
336  &s->num_done_out_buffers, s->done_out_buffers, buffer);
337  return OMX_ErrorNone;
338 }
339 
340 static const OMX_CALLBACKTYPE callbacks = {
344 };
345 
346 static av_cold int find_component(OMXContext *omx_context, void *logctx,
347  const char *role, char *str, int str_size)
348 {
349  OMX_U32 i, num = 0;
350  char **components;
351  int ret = 0;
352 
353 #if CONFIG_OMX_RPI
354  if (av_strstart(role, "video_encoder.", NULL)) {
355  av_strlcpy(str, "OMX.broadcom.video_encode", str_size);
356  return 0;
357  }
358 #endif
359  omx_context->ptr_GetComponentsOfRole((OMX_STRING) role, &num, NULL);
360  if (!num) {
361  av_log(logctx, AV_LOG_WARNING, "No component for role %s found\n", role);
363  }
364  components = av_calloc(num, sizeof(*components));
365  if (!components)
366  return AVERROR(ENOMEM);
367  for (i = 0; i < num; i++) {
368  components[i] = av_mallocz(OMX_MAX_STRINGNAME_SIZE);
369  if (!components[i]) {
370  ret = AVERROR(ENOMEM);
371  goto end;
372  }
373  }
374  omx_context->ptr_GetComponentsOfRole((OMX_STRING) role, &num, (OMX_U8**) components);
375  av_strlcpy(str, components[0], str_size);
376 end:
377  for (i = 0; i < num; i++)
378  av_free(components[i]);
379  av_free(components);
380  return ret;
381 }
382 
383 static av_cold int wait_for_state(OMXCodecContext *s, OMX_STATETYPE state)
384 {
385  int ret = 0;
386  pthread_mutex_lock(&s->state_mutex);
387  while (s->state != state && s->error == OMX_ErrorNone)
388  pthread_cond_wait(&s->state_cond, &s->state_mutex);
389  if (s->error != OMX_ErrorNone)
391  pthread_mutex_unlock(&s->state_mutex);
392  return ret;
393 }
394 
395 static av_cold int omx_component_init(AVCodecContext *avctx, const char *role)
396 {
397  OMXCodecContext *s = avctx->priv_data;
398  OMX_PARAM_COMPONENTROLETYPE role_params = { 0 };
399  OMX_PORT_PARAM_TYPE video_port_params = { 0 };
400  OMX_PARAM_PORTDEFINITIONTYPE in_port_params = { 0 }, out_port_params = { 0 };
401  OMX_VIDEO_PARAM_PORTFORMATTYPE video_port_format = { 0 };
402  OMX_VIDEO_PARAM_BITRATETYPE vid_param_bitrate = { 0 };
403  OMX_ERRORTYPE err;
404  int i;
405 
406  s->version.s.nVersionMajor = 1;
407  s->version.s.nVersionMinor = 1;
408  s->version.s.nRevision = 2;
409 
410  err = s->omx_context->ptr_GetHandle(&s->handle, s->component_name, s, (OMX_CALLBACKTYPE*) &callbacks);
411  if (err != OMX_ErrorNone) {
412  av_log(avctx, AV_LOG_ERROR, "OMX_GetHandle(%s) failed: %x\n", s->component_name, err);
413  return AVERROR_UNKNOWN;
414  }
415 
416  // This one crashes the mediaserver on qcom, if used over IOMX
417  INIT_STRUCT(role_params);
418  av_strlcpy(role_params.cRole, role, sizeof(role_params.cRole));
419  // Intentionally ignore errors on this one
420  OMX_SetParameter(s->handle, OMX_IndexParamStandardComponentRole, &role_params);
421 
422  INIT_STRUCT(video_port_params);
423  err = OMX_GetParameter(s->handle, OMX_IndexParamVideoInit, &video_port_params);
424  CHECK(err);
425 
426  s->in_port = s->out_port = -1;
427  for (i = 0; i < video_port_params.nPorts; i++) {
428  int port = video_port_params.nStartPortNumber + i;
429  OMX_PARAM_PORTDEFINITIONTYPE port_params = { 0 };
430  INIT_STRUCT(port_params);
431  port_params.nPortIndex = port;
432  err = OMX_GetParameter(s->handle, OMX_IndexParamPortDefinition, &port_params);
433  if (err != OMX_ErrorNone) {
434  av_log(avctx, AV_LOG_WARNING, "port %d error %x\n", port, err);
435  break;
436  }
437  if (port_params.eDir == OMX_DirInput && s->in_port < 0) {
438  in_port_params = port_params;
439  s->in_port = port;
440  } else if (port_params.eDir == OMX_DirOutput && s->out_port < 0) {
441  out_port_params = port_params;
442  s->out_port = port;
443  }
444  }
445  if (s->in_port < 0 || s->out_port < 0) {
446  av_log(avctx, AV_LOG_ERROR, "No in or out port found (in %d out %d)\n", s->in_port, s->out_port);
447  return AVERROR_UNKNOWN;
448  }
449 
450  s->color_format = 0;
451  for (i = 0; ; i++) {
452  INIT_STRUCT(video_port_format);
453  video_port_format.nIndex = i;
454  video_port_format.nPortIndex = s->in_port;
455  if (OMX_GetParameter(s->handle, OMX_IndexParamVideoPortFormat, &video_port_format) != OMX_ErrorNone)
456  break;
457  if (video_port_format.eColorFormat == OMX_COLOR_FormatYUV420Planar ||
458  video_port_format.eColorFormat == OMX_COLOR_FormatYUV420PackedPlanar) {
459  s->color_format = video_port_format.eColorFormat;
460  break;
461  }
462  }
463  if (s->color_format == 0) {
464  av_log(avctx, AV_LOG_ERROR, "No supported pixel formats (%d formats available)\n", i);
465  return AVERROR_UNKNOWN;
466  }
467 
468  in_port_params.bEnabled = OMX_TRUE;
469  in_port_params.bPopulated = OMX_FALSE;
470  in_port_params.eDomain = OMX_PortDomainVideo;
471 
472  in_port_params.format.video.pNativeRender = NULL;
473  in_port_params.format.video.bFlagErrorConcealment = OMX_FALSE;
474  in_port_params.format.video.eColorFormat = s->color_format;
475  s->stride = avctx->width;
476  s->plane_size = avctx->height;
477  // If specific codecs need to manually override the stride/plane_size,
478  // that can be done here.
479  in_port_params.format.video.nStride = s->stride;
480  in_port_params.format.video.nSliceHeight = s->plane_size;
481  in_port_params.format.video.nFrameWidth = avctx->width;
482  in_port_params.format.video.nFrameHeight = avctx->height;
483  if (avctx->framerate.den > 0 && avctx->framerate.num > 0)
484  in_port_params.format.video.xFramerate = (1LL << 16) * avctx->framerate.num / avctx->framerate.den;
485  else
486  in_port_params.format.video.xFramerate = (1LL << 16) * avctx->time_base.den / avctx->time_base.num;
487 
488  err = OMX_SetParameter(s->handle, OMX_IndexParamPortDefinition, &in_port_params);
489  CHECK(err);
490  err = OMX_GetParameter(s->handle, OMX_IndexParamPortDefinition, &in_port_params);
491  CHECK(err);
492  s->stride = in_port_params.format.video.nStride;
493  s->plane_size = in_port_params.format.video.nSliceHeight;
494  s->num_in_buffers = in_port_params.nBufferCountActual;
495 
496  err = OMX_GetParameter(s->handle, OMX_IndexParamPortDefinition, &out_port_params);
497  out_port_params.bEnabled = OMX_TRUE;
498  out_port_params.bPopulated = OMX_FALSE;
499  out_port_params.eDomain = OMX_PortDomainVideo;
500  out_port_params.format.video.pNativeRender = NULL;
501  out_port_params.format.video.nFrameWidth = avctx->width;
502  out_port_params.format.video.nFrameHeight = avctx->height;
503  out_port_params.format.video.nStride = 0;
504  out_port_params.format.video.nSliceHeight = 0;
505  out_port_params.format.video.nBitrate = avctx->bit_rate;
506  out_port_params.format.video.xFramerate = in_port_params.format.video.xFramerate;
507  out_port_params.format.video.bFlagErrorConcealment = OMX_FALSE;
508  if (avctx->codec->id == AV_CODEC_ID_MPEG4)
509  out_port_params.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
510  else if (avctx->codec->id == AV_CODEC_ID_H264)
511  out_port_params.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
512 
513  err = OMX_SetParameter(s->handle, OMX_IndexParamPortDefinition, &out_port_params);
514  CHECK(err);
515  err = OMX_GetParameter(s->handle, OMX_IndexParamPortDefinition, &out_port_params);
516  CHECK(err);
517  s->num_out_buffers = out_port_params.nBufferCountActual;
518 
519  INIT_STRUCT(vid_param_bitrate);
520  vid_param_bitrate.nPortIndex = s->out_port;
521  vid_param_bitrate.eControlRate = OMX_Video_ControlRateVariable;
522  vid_param_bitrate.nTargetBitrate = avctx->bit_rate;
523  err = OMX_SetParameter(s->handle, OMX_IndexParamVideoBitrate, &vid_param_bitrate);
524  if (err != OMX_ErrorNone)
525  av_log(avctx, AV_LOG_WARNING, "Unable to set video bitrate parameter\n");
526 
527  if (avctx->codec->id == AV_CODEC_ID_H264) {
528  OMX_VIDEO_PARAM_AVCTYPE avc = { 0 };
529  INIT_STRUCT(avc);
530  avc.nPortIndex = s->out_port;
531  err = OMX_GetParameter(s->handle, OMX_IndexParamVideoAvc, &avc);
532  CHECK(err);
533  avc.nBFrames = 0;
534  avc.nPFrames = avctx->gop_size - 1;
535  switch (s->profile == AV_PROFILE_UNKNOWN ? avctx->profile : s->profile) {
537  avc.eProfile = OMX_VIDEO_AVCProfileBaseline;
538  break;
540  avc.eProfile = OMX_VIDEO_AVCProfileMain;
541  break;
543  avc.eProfile = OMX_VIDEO_AVCProfileHigh;
544  break;
545  default:
546  break;
547  }
548  err = OMX_SetParameter(s->handle, OMX_IndexParamVideoAvc, &avc);
549  CHECK(err);
550  }
551 
552  err = OMX_SendCommand(s->handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
553  CHECK(err);
554 
555  s->in_buffer_headers = av_mallocz(sizeof(OMX_BUFFERHEADERTYPE*) * s->num_in_buffers);
556  s->free_in_buffers = av_mallocz(sizeof(OMX_BUFFERHEADERTYPE*) * s->num_in_buffers);
557  s->out_buffer_headers = av_mallocz(sizeof(OMX_BUFFERHEADERTYPE*) * s->num_out_buffers);
558  s->done_out_buffers = av_mallocz(sizeof(OMX_BUFFERHEADERTYPE*) * s->num_out_buffers);
559  if (!s->in_buffer_headers || !s->free_in_buffers || !s->out_buffer_headers || !s->done_out_buffers)
560  return AVERROR(ENOMEM);
561  for (i = 0; i < s->num_in_buffers && err == OMX_ErrorNone; i++) {
562  if (s->input_zerocopy)
563  err = OMX_UseBuffer(s->handle, &s->in_buffer_headers[i], s->in_port, s, in_port_params.nBufferSize, NULL);
564  else
565  err = OMX_AllocateBuffer(s->handle, &s->in_buffer_headers[i], s->in_port, s, in_port_params.nBufferSize);
566  if (err == OMX_ErrorNone)
567  s->in_buffer_headers[i]->pAppPrivate = s->in_buffer_headers[i]->pOutputPortPrivate = NULL;
568  }
569  CHECK(err);
570  s->num_in_buffers = i;
571  for (i = 0; i < s->num_out_buffers && err == OMX_ErrorNone; i++)
572  err = OMX_AllocateBuffer(s->handle, &s->out_buffer_headers[i], s->out_port, s, out_port_params.nBufferSize);
573  CHECK(err);
574  s->num_out_buffers = i;
575 
576  if (wait_for_state(s, OMX_StateIdle) < 0) {
577  av_log(avctx, AV_LOG_ERROR, "Didn't get OMX_StateIdle\n");
578  return AVERROR_UNKNOWN;
579  }
580  err = OMX_SendCommand(s->handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
581  CHECK(err);
582  if (wait_for_state(s, OMX_StateExecuting) < 0) {
583  av_log(avctx, AV_LOG_ERROR, "Didn't get OMX_StateExecuting\n");
584  return AVERROR_UNKNOWN;
585  }
586 
587  for (i = 0; i < s->num_out_buffers && err == OMX_ErrorNone; i++)
588  err = OMX_FillThisBuffer(s->handle, s->out_buffer_headers[i]);
589  if (err != OMX_ErrorNone) {
590  for (; i < s->num_out_buffers; i++)
591  s->done_out_buffers[s->num_done_out_buffers++] = s->out_buffer_headers[i];
592  }
593  for (i = 0; i < s->num_in_buffers; i++)
594  s->free_in_buffers[s->num_free_in_buffers++] = s->in_buffer_headers[i];
595  return err != OMX_ErrorNone ? AVERROR_UNKNOWN : 0;
596 }
597 
599 {
600  int executing;
601 
602  /* If the mutexes/condition variables have not been properly initialized,
603  * nothing has been initialized and locking the mutex might be unsafe. */
604  if (s->mutex_cond_inited_cnt == NB_MUTEX_CONDS) {
605  pthread_mutex_lock(&s->state_mutex);
606  executing = s->state == OMX_StateExecuting;
607  pthread_mutex_unlock(&s->state_mutex);
608 
609  if (executing) {
610  OMX_SendCommand(s->handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
611  wait_for_state(s, OMX_StateIdle);
612  OMX_SendCommand(s->handle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
613  for (int i = 0; i < s->num_in_buffers; i++) {
614  OMX_BUFFERHEADERTYPE *buffer = get_buffer(&s->input_mutex, &s->input_cond,
615  &s->num_free_in_buffers, s->free_in_buffers, 1);
616  if (s->input_zerocopy)
617  buffer->pBuffer = NULL;
618  OMX_FreeBuffer(s->handle, s->in_port, buffer);
619  }
620  for (int i = 0; i < s->num_out_buffers; i++) {
621  OMX_BUFFERHEADERTYPE *buffer = get_buffer(&s->output_mutex, &s->output_cond,
622  &s->num_done_out_buffers, s->done_out_buffers, 1);
623  OMX_FreeBuffer(s->handle, s->out_port, buffer);
624  }
625  wait_for_state(s, OMX_StateLoaded);
626  }
627  if (s->handle) {
628  s->omx_context->ptr_FreeHandle(s->handle);
629  s->handle = NULL;
630  }
631 
632  omx_deinit(s->omx_context);
633  s->omx_context = NULL;
634  av_freep(&s->in_buffer_headers);
635  av_freep(&s->out_buffer_headers);
636  av_freep(&s->free_in_buffers);
637  av_freep(&s->done_out_buffers);
638  av_freep(&s->output_buf);
639  }
640  ff_pthread_free(s, omx_codec_context_offsets);
641 }
642 
644 {
645  OMXCodecContext *s = avctx->priv_data;
647  const char *role;
648  OMX_BUFFERHEADERTYPE *buffer;
649  OMX_ERRORTYPE err;
650 
651  /* cleanup relies on the mutexes/conditions being initialized first. */
652  ret = ff_pthread_init(s, omx_codec_context_offsets);
653  if (ret < 0)
654  return ret;
655  s->omx_context = omx_init(avctx, s->libname, s->libprefix);
656  if (!s->omx_context)
658 
659  s->avctx = avctx;
660  s->state = OMX_StateLoaded;
661  s->error = OMX_ErrorNone;
662 
663  switch (avctx->codec->id) {
664  case AV_CODEC_ID_MPEG4:
665  role = "video_encoder.mpeg4";
666  break;
667  case AV_CODEC_ID_H264:
668  role = "video_encoder.avc";
669  break;
670  default:
671  return AVERROR(ENOSYS);
672  }
673 
674  if ((ret = find_component(s->omx_context, avctx, role, s->component_name, sizeof(s->component_name))) < 0)
675  goto fail;
676 
677  av_log(avctx, AV_LOG_INFO, "Using %s\n", s->component_name);
678 
679  if ((ret = omx_component_init(avctx, role)) < 0)
680  goto fail;
681 
682  if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
683  while (1) {
684  buffer = get_buffer(&s->output_mutex, &s->output_cond,
685  &s->num_done_out_buffers, s->done_out_buffers, 1);
686  if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
687  if ((ret = av_reallocp(&avctx->extradata, avctx->extradata_size + buffer->nFilledLen + AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
688  avctx->extradata_size = 0;
689  goto fail;
690  }
691  memcpy(avctx->extradata + avctx->extradata_size, buffer->pBuffer + buffer->nOffset, buffer->nFilledLen);
692  avctx->extradata_size += buffer->nFilledLen;
693  memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
694  }
695  err = OMX_FillThisBuffer(s->handle, buffer);
696  if (err != OMX_ErrorNone) {
697  append_buffer(&s->output_mutex, &s->output_cond,
698  &s->num_done_out_buffers, s->done_out_buffers, buffer);
699  av_log(avctx, AV_LOG_ERROR, "OMX_FillThisBuffer failed: %x\n", err);
701  goto fail;
702  }
703  if (avctx->codec->id == AV_CODEC_ID_H264) {
704  // For H.264, the extradata can be returned in two separate buffers
705  // (the videocore encoder on raspberry pi does this);
706  // therefore check that we have got both SPS and PPS before continuing.
707  int nals[32] = { 0 };
708  int i;
709  for (i = 0; i + 4 < avctx->extradata_size; i++) {
710  if (!avctx->extradata[i + 0] &&
711  !avctx->extradata[i + 1] &&
712  !avctx->extradata[i + 2] &&
713  avctx->extradata[i + 3] == 1) {
714  nals[avctx->extradata[i + 4] & 0x1f]++;
715  }
716  }
717  if (nals[H264_NAL_SPS] && nals[H264_NAL_PPS])
718  break;
719  } else {
720  if (avctx->extradata_size > 0)
721  break;
722  }
723  }
724  }
725 
726  return 0;
727 fail:
728  return ret;
729 }
730 
731 
733  const AVFrame *frame, int *got_packet)
734 {
735  OMXCodecContext *s = avctx->priv_data;
736  int ret = 0;
737  OMX_BUFFERHEADERTYPE* buffer;
738  OMX_ERRORTYPE err;
739  int had_partial = 0;
740 
741  if (frame) {
742  uint8_t *dst[4];
743  int linesize[4];
744  int need_copy;
745  buffer = get_buffer(&s->input_mutex, &s->input_cond,
746  &s->num_free_in_buffers, s->free_in_buffers, 1);
747 
748  buffer->nFilledLen = av_image_fill_arrays(dst, linesize, buffer->pBuffer, avctx->pix_fmt, s->stride, s->plane_size, 1);
749 
750  if (s->input_zerocopy) {
751  uint8_t *src[4] = { NULL };
752  int src_linesize[4];
753  av_image_fill_arrays(src, src_linesize, frame->data[0], avctx->pix_fmt, s->stride, s->plane_size, 1);
754  if (frame->linesize[0] == src_linesize[0] &&
755  frame->linesize[1] == src_linesize[1] &&
756  frame->linesize[2] == src_linesize[2] &&
757  frame->data[1] == src[1] &&
758  frame->data[2] == src[2]) {
759  // If the input frame happens to have all planes stored contiguously,
760  // with the right strides, just clone the frame and set the OMX
761  // buffer header to point to it
762  AVFrame *local = av_frame_clone(frame);
763  if (!local) {
764  // Return the buffer to the queue so it's not lost
765  append_buffer(&s->input_mutex, &s->input_cond, &s->num_free_in_buffers, s->free_in_buffers, buffer);
766  return AVERROR(ENOMEM);
767  } else {
768  buffer->pAppPrivate = local;
769  buffer->pOutputPortPrivate = NULL;
770  buffer->pBuffer = local->data[0];
771  need_copy = 0;
772  }
773  } else {
774  // If not, we need to allocate a new buffer with the right
775  // size and copy the input frame into it.
776  uint8_t *buf = NULL;
777  int image_buffer_size = av_image_get_buffer_size(avctx->pix_fmt, s->stride, s->plane_size, 1);
778  if (image_buffer_size >= 0)
779  buf = av_malloc(image_buffer_size);
780  if (!buf) {
781  // Return the buffer to the queue so it's not lost
782  append_buffer(&s->input_mutex, &s->input_cond, &s->num_free_in_buffers, s->free_in_buffers, buffer);
783  return AVERROR(ENOMEM);
784  } else {
785  buffer->pAppPrivate = buf;
786  // Mark that pAppPrivate is an av_malloc'ed buffer, not an AVFrame
787  buffer->pOutputPortPrivate = (void*) 1;
788  buffer->pBuffer = buf;
789  need_copy = 1;
790  buffer->nFilledLen = av_image_fill_arrays(dst, linesize, buffer->pBuffer, avctx->pix_fmt, s->stride, s->plane_size, 1);
791  }
792  }
793  } else {
794  need_copy = 1;
795  }
796  if (need_copy)
797  av_image_copy2(dst, linesize, frame->data, frame->linesize,
798  avctx->pix_fmt, avctx->width, avctx->height);
799  buffer->nFlags = OMX_BUFFERFLAG_ENDOFFRAME;
800  buffer->nOffset = 0;
801  // Convert the timestamps to microseconds; some encoders can ignore
802  // the framerate and do VFR bit allocation based on timestamps.
803  buffer->nTimeStamp = to_omx_ticks(av_rescale_q(frame->pts, avctx->time_base, AV_TIME_BASE_Q));
804  if (frame->pict_type == AV_PICTURE_TYPE_I) {
805 #if CONFIG_OMX_RPI
806  OMX_CONFIG_BOOLEANTYPE config = {0, };
808  config.bEnabled = OMX_TRUE;
809  err = OMX_SetConfig(s->handle, OMX_IndexConfigBrcmVideoRequestIFrame, &config);
810  if (err != OMX_ErrorNone) {
811  av_log(avctx, AV_LOG_ERROR, "OMX_SetConfig(RequestIFrame) failed: %x\n", err);
812  }
813 #else
814  OMX_CONFIG_INTRAREFRESHVOPTYPE config = {0, };
816  config.nPortIndex = s->out_port;
817  config.IntraRefreshVOP = OMX_TRUE;
818  err = OMX_SetConfig(s->handle, OMX_IndexConfigVideoIntraVOPRefresh, &config);
819  if (err != OMX_ErrorNone) {
820  av_log(avctx, AV_LOG_ERROR, "OMX_SetConfig(IntraVOPRefresh) failed: %x\n", err);
821  }
822 #endif
823  }
824  err = OMX_EmptyThisBuffer(s->handle, buffer);
825  if (err != OMX_ErrorNone) {
826  append_buffer(&s->input_mutex, &s->input_cond, &s->num_free_in_buffers, s->free_in_buffers, buffer);
827  av_log(avctx, AV_LOG_ERROR, "OMX_EmptyThisBuffer failed: %x\n", err);
828  return AVERROR_UNKNOWN;
829  }
830  } else if (!s->eos_sent) {
831  buffer = get_buffer(&s->input_mutex, &s->input_cond,
832  &s->num_free_in_buffers, s->free_in_buffers, 1);
833 
834  buffer->nFilledLen = 0;
835  buffer->nFlags = OMX_BUFFERFLAG_EOS;
836  buffer->pAppPrivate = buffer->pOutputPortPrivate = NULL;
837  err = OMX_EmptyThisBuffer(s->handle, buffer);
838  if (err != OMX_ErrorNone) {
839  append_buffer(&s->input_mutex, &s->input_cond, &s->num_free_in_buffers, s->free_in_buffers, buffer);
840  av_log(avctx, AV_LOG_ERROR, "OMX_EmptyThisBuffer failed: %x\n", err);
841  return AVERROR_UNKNOWN;
842  }
843  s->eos_sent = 1;
844  }
845 
846  while (!*got_packet && ret == 0 && !s->got_eos) {
847  // If not flushing, just poll the queue if there's finished packets.
848  // If flushing, do a blocking wait until we either get a completed
849  // packet, or get EOS.
850  buffer = get_buffer(&s->output_mutex, &s->output_cond,
851  &s->num_done_out_buffers, s->done_out_buffers,
852  !frame || had_partial);
853  if (!buffer)
854  break;
855 
856  if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
857  s->got_eos = 1;
858 
859  if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG && avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
860  if ((ret = av_reallocp(&avctx->extradata, avctx->extradata_size + buffer->nFilledLen + AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
861  avctx->extradata_size = 0;
862  goto end;
863  }
864  memcpy(avctx->extradata + avctx->extradata_size, buffer->pBuffer + buffer->nOffset, buffer->nFilledLen);
865  avctx->extradata_size += buffer->nFilledLen;
866  memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
867  } else {
868  int newsize = s->output_buf_size + buffer->nFilledLen + AV_INPUT_BUFFER_PADDING_SIZE;
869  if ((ret = av_reallocp(&s->output_buf, newsize)) < 0) {
870  s->output_buf_size = 0;
871  goto end;
872  }
873  memcpy(s->output_buf + s->output_buf_size, buffer->pBuffer + buffer->nOffset, buffer->nFilledLen);
874  s->output_buf_size += buffer->nFilledLen;
875  if (buffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) {
876  memset(s->output_buf + s->output_buf_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
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;
885  // We don't currently enable B-frames for the encoders, so set
886  // pkt->dts = pkt->pts. (The calling code behaves worse if the encoder
887  // doesn't set the dts).
888  pkt->dts = pkt->pts;
889  if (buffer->nFlags & OMX_BUFFERFLAG_SYNCFRAME)
891  *got_packet = 1;
892  } else {
893 #if CONFIG_OMX_RPI
894  had_partial = 1;
895 #endif
896  }
897  }
898 end:
899  err = OMX_FillThisBuffer(s->handle, buffer);
900  if (err != OMX_ErrorNone) {
901  append_buffer(&s->output_mutex, &s->output_cond, &s->num_done_out_buffers, s->done_out_buffers, buffer);
902  av_log(avctx, AV_LOG_ERROR, "OMX_FillThisBuffer failed: %x\n", err);
904  }
905  }
906  return ret;
907 }
908 
910 {
911  OMXCodecContext *s = avctx->priv_data;
912 
913  cleanup(s);
914  return 0;
915 }
916 
917 #define OFFSET(x) offsetof(OMXCodecContext, x)
918 #define VDE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM
919 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
920 static const AVOption options[] = {
921  { "omx_libname", "OpenMAX library name", OFFSET(libname), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VDE },
922  { "omx_libprefix", "OpenMAX library prefix", OFFSET(libprefix), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VDE },
923  { "zerocopy", "Try to avoid copying input frames if possible", OFFSET(input_zerocopy), AV_OPT_TYPE_INT, { .i64 = CONFIG_OMX_RPI }, 0, 1, VE },
924  { "profile", "Set the encoding profile", OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = AV_PROFILE_UNKNOWN }, AV_PROFILE_UNKNOWN, AV_PROFILE_H264_HIGH, VE, .unit = "profile" },
925  { "baseline", "", 0, AV_OPT_TYPE_CONST, { .i64 = AV_PROFILE_H264_BASELINE }, 0, 0, VE, .unit = "profile" },
926  { "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = AV_PROFILE_H264_MAIN }, 0, 0, VE, .unit = "profile" },
927  { "high", "", 0, AV_OPT_TYPE_CONST, { .i64 = AV_PROFILE_H264_HIGH }, 0, 0, VE, .unit = "profile" },
928  { NULL }
929 };
930 
931 static const enum AVPixelFormat omx_encoder_pix_fmts[] = {
933 };
934 
935 static const AVClass omx_mpeg4enc_class = {
936  .class_name = "mpeg4_omx",
937  .item_name = av_default_item_name,
938  .option = options,
939  .version = LIBAVUTIL_VERSION_INT,
940 };
942  .p.name = "mpeg4_omx",
943  CODEC_LONG_NAME("OpenMAX IL MPEG-4 video encoder"),
944  .p.type = AVMEDIA_TYPE_VIDEO,
945  .p.id = AV_CODEC_ID_MPEG4,
946  .priv_data_size = sizeof(OMXCodecContext),
949  .close = omx_encode_end,
950  .p.pix_fmts = omx_encoder_pix_fmts,
951  .p.capabilities = AV_CODEC_CAP_DELAY,
952  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
953  .p.priv_class = &omx_mpeg4enc_class,
954 };
955 
956 static const AVClass omx_h264enc_class = {
957  .class_name = "h264_omx",
958  .item_name = av_default_item_name,
959  .option = options,
960  .version = LIBAVUTIL_VERSION_INT,
961 };
963  .p.name = "h264_omx",
964  CODEC_LONG_NAME("OpenMAX IL H.264 video encoder"),
965  .p.type = AVMEDIA_TYPE_VIDEO,
966  .p.id = AV_CODEC_ID_H264,
967  .priv_data_size = sizeof(OMXCodecContext),
970  .close = omx_encode_end,
971  .p.pix_fmts = omx_encoder_pix_fmts,
972  .p.capabilities = AV_CODEC_CAP_DELAY,
973  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
974  .p.priv_class = &omx_h264enc_class,
975 };
pthread_mutex_t
_fmutex pthread_mutex_t
Definition: os2threads.h:53
OMXCodecContext::done_out_buffers
OMX_BUFFERHEADERTYPE ** done_out_buffers
Definition: omx.c:212
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
cleanup
static av_cold void cleanup(OMXCodecContext *s)
Definition: omx.c:598
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
OMXCodecContext::output_buf_size
int output_buf_size
Definition: omx.c:228
INIT_STRUCT
#define INIT_STRUCT(x)
Definition: omx.c:66
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: codec_internal.h:42
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:87
AV_PROFILE_H264_MAIN
#define AV_PROFILE_H264_MAIN
Definition: defs.h:111
omx_component_init
static av_cold int omx_component_init(AVCodecContext *avctx, const char *role)
Definition: omx.c:395
AV_TIME_BASE_Q
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
Definition: avutil.h:264
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:250
OMXCodecContext::eos_sent
int eos_sent
Definition: omx.c:225
AV_CODEC_ID_MPEG4
@ AV_CODEC_ID_MPEG4
Definition: codec_id.h:64
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:160
callbacks
static const OMX_CALLBACKTYPE callbacks
Definition: omx.c:340
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:374
OMXCodecContext::out_buffer_headers
OMX_BUFFERHEADERTYPE ** out_buffer_headers
Definition: omx.c:208
OMXCodecContext
Definition: omx.c:191
AVOption
AVOption.
Definition: opt.h:346
empty_buffer_done
static OMX_ERRORTYPE empty_buffer_done(OMX_HANDLETYPE component, OMX_PTR app_data, OMX_BUFFERHEADERTYPE *buffer)
Definition: omx.c:313
OMXCodecContext::omx_context
OMXContext * omx_context
Definition: omx.c:195
OMXContext
Definition: omx.c:78
FFCodec
Definition: codec_internal.h:126
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
OMXCodecContext::state
OMX_STATETYPE state
Definition: omx.c:220
OMXCodecContext::input_zerocopy
int input_zerocopy
Definition: omx.c:230
H264_NAL_PPS
@ H264_NAL_PPS
Definition: h264.h:42
ff_h264_omx_encoder
const FFCodec ff_h264_omx_encoder
Definition: omx.c:962
AVERROR_UNKNOWN
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:73
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:579
ff_pthread_free
av_cold void ff_pthread_free(void *obj, const unsigned offsets[])
Definition: pthread.c:91
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:395
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
AV_CODEC_FLAG_GLOBAL_HEADER
#define AV_CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
Definition: avcodec.h:338
AVCodecContext::framerate
AVRational framerate
Definition: avcodec.h:560
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:130
OMXCodecContext::out_port
int out_port
Definition: omx.c:202
OMXCodecContext::state_mutex
pthread_mutex_t state_mutex
Definition: omx.c:218
dlsym_prefixed
static av_cold void * dlsym_prefixed(void *handle, const char *symbol, const char *prefix)
Definition: omx.c:91
AVCodecContext::codec
const struct AVCodec * codec
Definition: avcodec.h:454
OMXCodecContext::libname
char * libname
Definition: omx.c:193
fail
#define fail()
Definition: checkasm.h:179
OMXCodecContext::version
OMX_VERSIONTYPE version
Definition: omx.c:200
omx_encoder_pix_fmts
static enum AVPixelFormat omx_encoder_pix_fmts[]
Definition: omx.c:931
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:502
OMXCodecContext::plane_size
int plane_size
Definition: omx.c:204
FF_CODEC_ENCODE_CB
#define FF_CODEC_ENCODE_CB(func)
Definition: codec_internal.h:295
OMXCodecContext::input_mutex
pthread_mutex_t input_mutex
Definition: omx.c:213
AVRational::num
int num
Numerator.
Definition: rational.h:59
OMXCodecContext::stride
int stride
Definition: omx.c:204
OMXContext::ptr_GetHandle
OMX_ERRORTYPE(* ptr_GetHandle)(OMX_HANDLETYPE *, OMX_STRING, OMX_PTR, OMX_CALLBACKTYPE *)
Definition: omx.c:84
OMXContext::lib
void * lib
Definition: omx.c:79
pkt
AVPacket * pkt
Definition: movenc.c:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
AV_PROFILE_UNKNOWN
#define AV_PROFILE_UNKNOWN
Definition: defs.h:65
OMXContext::lib2
void * lib2
Definition: omx.c:80
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:524
s
#define s(width, name)
Definition: cbs_vp9.c:198
OMXCodecContext::free_in_buffers
OMX_BUFFERHEADERTYPE ** free_in_buffers
Definition: omx.c:210
NB_MUTEX_CONDS
#define NB_MUTEX_CONDS
Definition: omx.c:234
OMXContext::ptr_GetComponentsOfRole
OMX_ERRORTYPE(* ptr_GetComponentsOfRole)(OMX_STRING, OMX_U32 *, OMX_U8 **)
Definition: omx.c:86
OFFSET
#define OFFSET(x)
Definition: omx.c:917
av_frame_clone
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition: frame.c:593
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:73
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:214
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
CODEC_LONG_NAME
#define CODEC_LONG_NAME(str)
Definition: codec_internal.h:271
OMXCodecContext::num_in_buffers
int num_in_buffers
Definition: omx.c:206
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
state
static struct @414 state
AVCodecContext::bit_rate
int64_t bit_rate
the average bitrate
Definition: avcodec.h:495
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:279
VDE
#define VDE
Definition: omx.c:918
pthread_internal.h
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:240
OMXContext::ptr_Init
OMX_ERRORTYPE(* ptr_Init)(void)
Definition: omx.c:81
pthread_mutex_unlock
#define pthread_mutex_unlock(a)
Definition: ffprobe.c:82
OMXCodecContext::output_buf
uint8_t * output_buf
Definition: omx.c:227
OMXCodecContext::mutex_cond_inited_cnt
unsigned mutex_cond_inited_cnt
Definition: omx.c:223
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:544
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:271
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: packet.c:172
init
int(* init)(AVBSFContext *ctx)
Definition: dts2pts.c:366
OMXCodecContext::num_free_in_buffers
int num_free_in_buffers
Definition: omx.c:209
OMXCodecContext::in_buffer_headers
OMX_BUFFERHEADERTYPE ** in_buffer_headers
Definition: omx.c:207
AVCodecContext::gop_size
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition: avcodec.h:1031
av_image_fill_arrays
int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4], const uint8_t *src, enum AVPixelFormat pix_fmt, int width, int height, int align)
Setup the data pointers and linesizes based on the specified image parameters and the provided array.
Definition: imgutils.c:446
codec_internal.h
ff_mpeg4_omx_encoder
const FFCodec ff_mpeg4_omx_encoder
Definition: omx.c:941
OMXCodecContext::in_port
int in_port
Definition: omx.c:202
OMXContext::ptr_ComponentNameEnum
OMX_ERRORTYPE(* ptr_ComponentNameEnum)(OMX_STRING, OMX_U32, OMX_U32)
Definition: omx.c:83
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:188
H264_NAL_SPS
@ H264_NAL_SPS
Definition: h264.h:41
options
static const AVOption options[]
Definition: omx.c:920
OFF
#define OFF(field)
Definition: omx.c:235
AVPacket::dts
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Definition: packet.h:523
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:466
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:98
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:530
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:36
omx_h264enc_class
static const AVClass omx_h264enc_class
Definition: omx.c:956
OMXCodecContext::num_out_buffers
int num_out_buffers
Definition: omx.c:206
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
OMXCodecContext::avctx
AVCodecContext * avctx
Definition: omx.c:197
AVCodec::id
enum AVCodecID id
Definition: codec.h:201
CHECK
#define CHECK(x)
Definition: omx.c:70
log.h
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:517
AVCodecContext::extradata
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:523
OMXCodecContext::libprefix
char * libprefix
Definition: omx.c:194
omx_encode_frame
static int omx_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet)
Definition: omx.c:732
OMXCodecContext::output_mutex
pthread_mutex_t output_mutex
Definition: omx.c:215
DEFINE_OFFSET_ARRAY
DEFINE_OFFSET_ARRAY(OMXCodecContext, omx_codec_context, mutex_cond_inited_cnt,(OFF(input_mutex), OFF(output_mutex), OFF(state_mutex)),(OFF(input_cond), OFF(output_cond), OFF(state_cond)))
to_omx_ticks
#define to_omx_ticks(x)
Definition: omx.c:62
common.h
OMXContext::host_init
void(* host_init)(void)
Definition: omx.c:88
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:346
from_omx_ticks
#define from_omx_ticks(x)
Definition: omx.c:63
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:256
OMXCodecContext::output_cond
pthread_cond_t output_cond
Definition: omx.c:216
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:194
pthread_cond_t
Definition: os2threads.h:58
profile
int profile
Definition: mxfenc.c:2227
AVCodecContext::height
int height
Definition: avcodec.h:618
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:657
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
avcodec.h
wait_for_state
static av_cold int wait_for_state(OMXCodecContext *s, OMX_STATETYPE state)
Definition: omx.c:383
array
static int array[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:111
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:71
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
AV_PROFILE_H264_BASELINE
#define AV_PROFILE_H264_BASELINE
Definition: defs.h:109
omx_encode_init
static av_cold int omx_encode_init(AVCodecContext *avctx)
Definition: omx.c:643
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
omx_deinit
static av_cold void omx_deinit(OMXContext *omx_context)
Definition: omx.c:182
OMXCodecContext::color_format
OMX_COLOR_FORMATTYPE color_format
Definition: omx.c:203
OMXCodecContext::got_eos
int got_eos
Definition: omx.c:225
AVCodecContext
main external API structure.
Definition: avcodec.h:445
AV_PROFILE_H264_HIGH
#define AV_PROFILE_H264_HIGH
Definition: defs.h:113
OMXCodecContext::error
OMX_ERRORTYPE error
Definition: omx.c:221
omx_encode_end
static av_cold int omx_encode_end(AVCodecContext *avctx)
Definition: omx.c:909
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
av_image_copy2
static void av_image_copy2(uint8_t *const dst_data[4], const int dst_linesizes[4], uint8_t *const src_data[4], const int src_linesizes[4], enum AVPixelFormat pix_fmt, int width, int height)
Wrapper around av_image_copy() to workaround the limitation that the conversion from uint8_t * const ...
Definition: imgutils.h:184
AVRational::den
int den
Denominator.
Definition: rational.h:60
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:235
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1639
omx_init
static av_cold OMXContext * omx_init(void *logctx, const char *libname, const char *prefix)
Definition: omx.c:142
omx_mpeg4enc_class
static const AVClass omx_mpeg4enc_class
Definition: omx.c:935
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:76
ff_pthread_init
av_cold int ff_pthread_init(void *obj, const unsigned offsets[])
Initialize/destroy a list of mutexes/conditions contained in a structure.
Definition: pthread.c:104
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:56
avutil.h
mem.h
OMXCodecContext::handle
OMX_HANDLETYPE handle
Definition: omx.c:201
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
AVPacket
This structure stores compressed data.
Definition: packet.h:501
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:472
OMXCodecContext::profile
int profile
Definition: omx.c:231
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
OMXContext::ptr_Deinit
OMX_ERRORTYPE(* ptr_Deinit)(void)
Definition: omx.c:82
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:618
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:85
OMXCodecContext::state_cond
pthread_cond_t state_cond
Definition: omx.c:219
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
avstring.h
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:239
OMXCodecContext::num_done_out_buffers
int num_done_out_buffers
Definition: omx.c:211
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:244
snprintf
#define snprintf
Definition: snprintf.h:34
OMXCodecContext::component_name
char component_name[OMX_MAX_STRINGNAME_SIZE]
Definition: omx.c:199
cond
int(* cond)(enum AVPixelFormat pix_fmt)
Definition: pixdesc_query.c:28
VE
#define VE
Definition: omx.c:919
mutex
static AVMutex mutex
Definition: log.c:46
fill_buffer_done
static OMX_ERRORTYPE fill_buffer_done(OMX_HANDLETYPE component, OMX_PTR app_data, OMX_BUFFERHEADERTYPE *buffer)
Definition: omx.c:331
pthread_mutex_lock
#define pthread_mutex_lock(a)
Definition: ffprobe.c:78
OMXContext::ptr_FreeHandle
OMX_ERRORTYPE(* ptr_FreeHandle)(OMX_HANDLETYPE)
Definition: omx.c:85