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  av_log(avctx, AV_LOG_WARNING,
652  "The %s encoder is deprecated and will be removed in future versions\n",
653  avctx->codec->name);
654 
655  /* cleanup relies on the mutexes/conditions being initialized first. */
656  ret = ff_pthread_init(s, omx_codec_context_offsets);
657  if (ret < 0)
658  return ret;
659  s->omx_context = omx_init(avctx, s->libname, s->libprefix);
660  if (!s->omx_context)
662 
663  s->avctx = avctx;
664  s->state = OMX_StateLoaded;
665  s->error = OMX_ErrorNone;
666 
667  switch (avctx->codec->id) {
668  case AV_CODEC_ID_MPEG4:
669  role = "video_encoder.mpeg4";
670  break;
671  case AV_CODEC_ID_H264:
672  role = "video_encoder.avc";
673  break;
674  default:
675  return AVERROR(ENOSYS);
676  }
677 
678  if ((ret = find_component(s->omx_context, avctx, role, s->component_name, sizeof(s->component_name))) < 0)
679  goto fail;
680 
681  av_log(avctx, AV_LOG_INFO, "Using %s\n", s->component_name);
682 
683  if ((ret = omx_component_init(avctx, role)) < 0)
684  goto fail;
685 
686  if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
687  while (1) {
688  buffer = get_buffer(&s->output_mutex, &s->output_cond,
689  &s->num_done_out_buffers, s->done_out_buffers, 1);
690  if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
691  if ((ret = av_reallocp(&avctx->extradata, avctx->extradata_size + buffer->nFilledLen + AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
692  avctx->extradata_size = 0;
693  goto fail;
694  }
695  memcpy(avctx->extradata + avctx->extradata_size, buffer->pBuffer + buffer->nOffset, buffer->nFilledLen);
696  avctx->extradata_size += buffer->nFilledLen;
697  memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
698  }
699  err = OMX_FillThisBuffer(s->handle, buffer);
700  if (err != OMX_ErrorNone) {
701  append_buffer(&s->output_mutex, &s->output_cond,
702  &s->num_done_out_buffers, s->done_out_buffers, buffer);
703  av_log(avctx, AV_LOG_ERROR, "OMX_FillThisBuffer failed: %x\n", err);
705  goto fail;
706  }
707  if (avctx->codec->id == AV_CODEC_ID_H264) {
708  // For H.264, the extradata can be returned in two separate buffers
709  // (the videocore encoder on raspberry pi does this);
710  // therefore check that we have got both SPS and PPS before continuing.
711  int nals[32] = { 0 };
712  int i;
713  for (i = 0; i + 4 < avctx->extradata_size; i++) {
714  if (!avctx->extradata[i + 0] &&
715  !avctx->extradata[i + 1] &&
716  !avctx->extradata[i + 2] &&
717  avctx->extradata[i + 3] == 1) {
718  nals[avctx->extradata[i + 4] & 0x1f]++;
719  }
720  }
721  if (nals[H264_NAL_SPS] && nals[H264_NAL_PPS])
722  break;
723  } else {
724  if (avctx->extradata_size > 0)
725  break;
726  }
727  }
728  }
729 
730  return 0;
731 fail:
732  return ret;
733 }
734 
735 
737  const AVFrame *frame, int *got_packet)
738 {
739  OMXCodecContext *s = avctx->priv_data;
740  int ret = 0;
741  OMX_BUFFERHEADERTYPE* buffer;
742  OMX_ERRORTYPE err;
743  int had_partial = 0;
744 
745  if (frame) {
746  uint8_t *dst[4];
747  int linesize[4];
748  int need_copy;
749  buffer = get_buffer(&s->input_mutex, &s->input_cond,
750  &s->num_free_in_buffers, s->free_in_buffers, 1);
751 
752  buffer->nFilledLen = av_image_fill_arrays(dst, linesize, buffer->pBuffer, avctx->pix_fmt, s->stride, s->plane_size, 1);
753 
754  if (s->input_zerocopy) {
755  uint8_t *src[4] = { NULL };
756  int src_linesize[4];
757  av_image_fill_arrays(src, src_linesize, frame->data[0], avctx->pix_fmt, s->stride, s->plane_size, 1);
758  if (frame->linesize[0] == src_linesize[0] &&
759  frame->linesize[1] == src_linesize[1] &&
760  frame->linesize[2] == src_linesize[2] &&
761  frame->data[1] == src[1] &&
762  frame->data[2] == src[2]) {
763  // If the input frame happens to have all planes stored contiguously,
764  // with the right strides, just clone the frame and set the OMX
765  // buffer header to point to it
766  AVFrame *local = av_frame_clone(frame);
767  if (!local) {
768  // Return the buffer to the queue so it's not lost
769  append_buffer(&s->input_mutex, &s->input_cond, &s->num_free_in_buffers, s->free_in_buffers, buffer);
770  return AVERROR(ENOMEM);
771  } else {
772  buffer->pAppPrivate = local;
773  buffer->pOutputPortPrivate = NULL;
774  buffer->pBuffer = local->data[0];
775  need_copy = 0;
776  }
777  } else {
778  // If not, we need to allocate a new buffer with the right
779  // size and copy the input frame into it.
780  uint8_t *buf = NULL;
781  int image_buffer_size = av_image_get_buffer_size(avctx->pix_fmt, s->stride, s->plane_size, 1);
782  if (image_buffer_size >= 0)
783  buf = av_malloc(image_buffer_size);
784  if (!buf) {
785  // Return the buffer to the queue so it's not lost
786  append_buffer(&s->input_mutex, &s->input_cond, &s->num_free_in_buffers, s->free_in_buffers, buffer);
787  return AVERROR(ENOMEM);
788  } else {
789  buffer->pAppPrivate = buf;
790  // Mark that pAppPrivate is an av_malloc'ed buffer, not an AVFrame
791  buffer->pOutputPortPrivate = (void*) 1;
792  buffer->pBuffer = buf;
793  need_copy = 1;
794  buffer->nFilledLen = av_image_fill_arrays(dst, linesize, buffer->pBuffer, avctx->pix_fmt, s->stride, s->plane_size, 1);
795  }
796  }
797  } else {
798  need_copy = 1;
799  }
800  if (need_copy)
801  av_image_copy2(dst, linesize, frame->data, frame->linesize,
802  avctx->pix_fmt, avctx->width, avctx->height);
803  buffer->nFlags = OMX_BUFFERFLAG_ENDOFFRAME;
804  buffer->nOffset = 0;
805  // Convert the timestamps to microseconds; some encoders can ignore
806  // the framerate and do VFR bit allocation based on timestamps.
807  buffer->nTimeStamp = to_omx_ticks(av_rescale_q(frame->pts, avctx->time_base, AV_TIME_BASE_Q));
808  if (frame->pict_type == AV_PICTURE_TYPE_I) {
809 #if CONFIG_OMX_RPI
810  OMX_CONFIG_BOOLEANTYPE config = {0, };
812  config.bEnabled = OMX_TRUE;
813  err = OMX_SetConfig(s->handle, OMX_IndexConfigBrcmVideoRequestIFrame, &config);
814  if (err != OMX_ErrorNone) {
815  av_log(avctx, AV_LOG_ERROR, "OMX_SetConfig(RequestIFrame) failed: %x\n", err);
816  }
817 #else
818  OMX_CONFIG_INTRAREFRESHVOPTYPE config = {0, };
820  config.nPortIndex = s->out_port;
821  config.IntraRefreshVOP = OMX_TRUE;
822  err = OMX_SetConfig(s->handle, OMX_IndexConfigVideoIntraVOPRefresh, &config);
823  if (err != OMX_ErrorNone) {
824  av_log(avctx, AV_LOG_ERROR, "OMX_SetConfig(IntraVOPRefresh) failed: %x\n", err);
825  }
826 #endif
827  }
828  err = OMX_EmptyThisBuffer(s->handle, buffer);
829  if (err != OMX_ErrorNone) {
830  append_buffer(&s->input_mutex, &s->input_cond, &s->num_free_in_buffers, s->free_in_buffers, buffer);
831  av_log(avctx, AV_LOG_ERROR, "OMX_EmptyThisBuffer failed: %x\n", err);
832  return AVERROR_UNKNOWN;
833  }
834  } else if (!s->eos_sent) {
835  buffer = get_buffer(&s->input_mutex, &s->input_cond,
836  &s->num_free_in_buffers, s->free_in_buffers, 1);
837 
838  buffer->nFilledLen = 0;
839  buffer->nFlags = OMX_BUFFERFLAG_EOS;
840  buffer->pAppPrivate = buffer->pOutputPortPrivate = NULL;
841  err = OMX_EmptyThisBuffer(s->handle, buffer);
842  if (err != OMX_ErrorNone) {
843  append_buffer(&s->input_mutex, &s->input_cond, &s->num_free_in_buffers, s->free_in_buffers, buffer);
844  av_log(avctx, AV_LOG_ERROR, "OMX_EmptyThisBuffer failed: %x\n", err);
845  return AVERROR_UNKNOWN;
846  }
847  s->eos_sent = 1;
848  }
849 
850  while (!*got_packet && ret == 0 && !s->got_eos) {
851  // If not flushing, just poll the queue if there's finished packets.
852  // If flushing, do a blocking wait until we either get a completed
853  // packet, or get EOS.
854  buffer = get_buffer(&s->output_mutex, &s->output_cond,
855  &s->num_done_out_buffers, s->done_out_buffers,
856  !frame || had_partial);
857  if (!buffer)
858  break;
859 
860  if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
861  s->got_eos = 1;
862 
863  if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG && avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
864  if ((ret = av_reallocp(&avctx->extradata, avctx->extradata_size + buffer->nFilledLen + AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
865  avctx->extradata_size = 0;
866  goto end;
867  }
868  memcpy(avctx->extradata + avctx->extradata_size, buffer->pBuffer + buffer->nOffset, buffer->nFilledLen);
869  avctx->extradata_size += buffer->nFilledLen;
870  memset(avctx->extradata + avctx->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
871  } else {
872  int newsize = s->output_buf_size + buffer->nFilledLen + AV_INPUT_BUFFER_PADDING_SIZE;
873  if ((ret = av_reallocp(&s->output_buf, newsize)) < 0) {
874  s->output_buf_size = 0;
875  goto end;
876  }
877  memcpy(s->output_buf + s->output_buf_size, buffer->pBuffer + buffer->nOffset, buffer->nFilledLen);
878  s->output_buf_size += buffer->nFilledLen;
879  if (buffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) {
880  memset(s->output_buf + s->output_buf_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
881  if ((ret = av_packet_from_data(pkt, s->output_buf, s->output_buf_size)) < 0) {
882  av_freep(&s->output_buf);
883  s->output_buf_size = 0;
884  goto end;
885  }
886  s->output_buf = NULL;
887  s->output_buf_size = 0;
889  // We don't currently enable B-frames for the encoders, so set
890  // pkt->dts = pkt->pts. (The calling code behaves worse if the encoder
891  // doesn't set the dts).
892  pkt->dts = pkt->pts;
893  if (buffer->nFlags & OMX_BUFFERFLAG_SYNCFRAME)
895  *got_packet = 1;
896  } else {
897 #if CONFIG_OMX_RPI
898  had_partial = 1;
899 #endif
900  }
901  }
902 end:
903  err = OMX_FillThisBuffer(s->handle, buffer);
904  if (err != OMX_ErrorNone) {
905  append_buffer(&s->output_mutex, &s->output_cond, &s->num_done_out_buffers, s->done_out_buffers, buffer);
906  av_log(avctx, AV_LOG_ERROR, "OMX_FillThisBuffer failed: %x\n", err);
908  }
909  }
910  return ret;
911 }
912 
914 {
915  OMXCodecContext *s = avctx->priv_data;
916 
917  cleanup(s);
918  return 0;
919 }
920 
921 #define OFFSET(x) offsetof(OMXCodecContext, x)
922 #define VDE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM
923 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
924 static const AVOption options[] = {
925  { "omx_libname", "OpenMAX library name", OFFSET(libname), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VDE },
926  { "omx_libprefix", "OpenMAX library prefix", OFFSET(libprefix), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VDE },
927  { "zerocopy", "Try to avoid copying input frames if possible", OFFSET(input_zerocopy), AV_OPT_TYPE_INT, { .i64 = CONFIG_OMX_RPI }, 0, 1, VE },
928  { "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" },
929  { "baseline", "", 0, AV_OPT_TYPE_CONST, { .i64 = AV_PROFILE_H264_BASELINE }, 0, 0, VE, .unit = "profile" },
930  { "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = AV_PROFILE_H264_MAIN }, 0, 0, VE, .unit = "profile" },
931  { "high", "", 0, AV_OPT_TYPE_CONST, { .i64 = AV_PROFILE_H264_HIGH }, 0, 0, VE, .unit = "profile" },
932  { NULL }
933 };
934 
935 static const enum AVPixelFormat omx_encoder_pix_fmts[] = {
937 };
938 
939 static const AVClass omx_mpeg4enc_class = {
940  .class_name = "mpeg4_omx",
941  .item_name = av_default_item_name,
942  .option = options,
943  .version = LIBAVUTIL_VERSION_INT,
944 };
946  .p.name = "mpeg4_omx",
947  CODEC_LONG_NAME("OpenMAX IL MPEG-4 video encoder"),
948  .p.type = AVMEDIA_TYPE_VIDEO,
949  .p.id = AV_CODEC_ID_MPEG4,
950  .priv_data_size = sizeof(OMXCodecContext),
953  .close = omx_encode_end,
954  .p.pix_fmts = omx_encoder_pix_fmts,
955  .color_ranges = AVCOL_RANGE_MPEG,
956  .p.capabilities = AV_CODEC_CAP_DELAY,
957  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
958  .p.priv_class = &omx_mpeg4enc_class,
959 };
960 
961 static const AVClass omx_h264enc_class = {
962  .class_name = "h264_omx",
963  .item_name = av_default_item_name,
964  .option = options,
965  .version = LIBAVUTIL_VERSION_INT,
966 };
968  .p.name = "h264_omx",
969  CODEC_LONG_NAME("OpenMAX IL H.264 video encoder"),
970  .p.type = AVMEDIA_TYPE_VIDEO,
971  .p.id = AV_CODEC_ID_H264,
972  .priv_data_size = sizeof(OMXCodecContext),
975  .close = omx_encode_end,
976  .p.pix_fmts = omx_encoder_pix_fmts,
977  .color_ranges = AVCOL_RANGE_MPEG, /* FIXME: implement tagging */
978  .p.capabilities = AV_CODEC_CAP_DELAY,
979  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
980  .p.priv_class = &omx_h264enc_class,
981 };
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:215
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:43
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:112
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
int64_t
long long int64_t
Definition: coverity.c:34
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:162
callbacks
static const OMX_CALLBACKTYPE callbacks
Definition: omx.c:340
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:389
OMXCodecContext::out_buffer_headers
OMX_BUFFERHEADERTYPE ** out_buffer_headers
Definition: omx.c:208
OMXCodecContext
Definition: omx.c:191
AVOption
AVOption.
Definition: opt.h:429
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:127
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:225
OMXCodecContext::state
OMX_STATETYPE state
Definition: omx.c:220
OMXCodecContext::input_zerocopy
int input_zerocopy
Definition: omx.c:230
ff_h264_omx_encoder
const FFCodec ff_h264_omx_encoder
Definition: omx.c:967
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:594
ff_pthread_free
av_cold void ff_pthread_free(void *obj, const unsigned offsets[])
Definition: pthread.c:92
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:410
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
H264_NAL_PPS
@ H264_NAL_PPS
Definition: h264.h:42
AVCodecContext::framerate
AVRational framerate
Definition: avcodec.h:566
FFCodec::p
AVCodec p
The public AVCodec.
Definition: codec_internal.h:131
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:460
OMXCodecContext::libname
char * libname
Definition: omx.c:193
fail
#define fail()
Definition: checkasm.h:189
OMXCodecContext::version
OMX_VERSIONTYPE version
Definition: omx.c:200
omx_encoder_pix_fmts
static enum AVPixelFormat omx_encoder_pix_fmts[]
Definition: omx.c:935
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:508
OMXCodecContext::plane_size
int plane_size
Definition: omx.c:204
FF_CODEC_ENCODE_CB
#define FF_CODEC_ENCODE_CB(func)
Definition: codec_internal.h:320
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:209
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:530
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:921
av_frame_clone
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
Definition: frame.c:609
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:296
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:75
NULL
#define NULL
Definition: coverity.c:32
AVCodecContext::bit_rate
int64_t bit_rate
the average bitrate
Definition: avcodec.h:501
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:922
options
Definition: swscale.c:42
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:550
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:368
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:1037
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
dst
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition: dsp.h:83
ff_mpeg4_omx_encoder
const FFCodec ff_mpeg4_omx_encoder
Definition: omx.c:945
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
options
static const AVOption options[]
Definition: omx.c:924
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:538
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:545
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:961
OMXCodecContext::num_out_buffers
int num_out_buffers
Definition: omx.c:206
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:220
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:532
AVCodecContext::extradata
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:529
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:736
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
state
static struct @465 state
pthread_cond_t
Definition: os2threads.h:58
profile
int profile
Definition: mxfenc.c:2233
AVCodecContext::height
int height
Definition: avcodec.h:624
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:663
AVCOL_RANGE_MPEG
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition: pixfmt.h:700
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:116
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:80
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:110
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:451
AV_PROFILE_H264_HIGH
#define AV_PROFILE_H264_HIGH
Definition: defs.h:114
OMXCodecContext::error
OMX_ERRORTYPE error
Definition: omx.c:221
omx_encode_end
static av_cold int omx_encode_end(AVCodecContext *avctx)
Definition: omx.c:913
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
Underlying C type is int.
Definition: opt.h:259
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1650
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:939
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:105
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:516
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:478
OMXCodecContext::profile
int profile
Definition: omx.c:231
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
OMXContext::ptr_Deinit
OMX_ERRORTYPE(* ptr_Deinit)(void)
Definition: omx.c:82
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:624
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
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition: opt.h:276
OMXCodecContext::num_done_out_buffers
int num_done_out_buffers
Definition: omx.c:211
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition: opt.h:299
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
H264_NAL_SPS
@ H264_NAL_SPS
Definition: h264.h:41
src
#define src
Definition: vp8dsp.c:248
VE
#define VE
Definition: omx.c:923
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