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