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 "codec_internal.h" 45#include "h264.h" 46#include "pthread_internal.h" 47 48#ifdef OMX_SKIP64BIT 49static 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} 56static 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 77typedef 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 90static 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 97static 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); 105 return AVERROR_ENCODER_NOT_FOUND; 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; 112 return AVERROR_ENCODER_NOT_FOUND; 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); 118 return AVERROR_ENCODER_NOT_FOUND; 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; 136 return AVERROR_ENCODER_NOT_FOUND; 137 } 138 return 0; 139} 140 141static 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; 153 int ret = AVERROR_ENCODER_NOT_FOUND; 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 181static 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 190typedef struct OMXCodecContext { 191 const AVClass *class; 192 char *libname; 193 char *libprefix; 194 OMXContext *omx_context; 195 196 AVCodecContext *avctx; 197 198 char component_name[OMX_MAX_STRINGNAME_SIZE]; 199 OMX_VERSIONTYPE version; 200 OMX_HANDLETYPE handle; 201 int in_port, out_port; 202 OMX_COLOR_FORMATTYPE color_format; 203 int stride, plane_size; 204 205 int num_in_buffers, num_out_buffers; 206 OMX_BUFFERHEADERTYPE **in_buffer_headers; 207 OMX_BUFFERHEADERTYPE **out_buffer_headers; 208 int num_free_in_buffers; 209 OMX_BUFFERHEADERTYPE **free_in_buffers; 210 int num_done_out_buffers; 211 OMX_BUFFERHEADERTYPE **done_out_buffers; 212 pthread_mutex_t input_mutex; 213 pthread_cond_t input_cond; 214 pthread_mutex_t output_mutex; 215 pthread_cond_t output_cond; 216 217 pthread_mutex_t state_mutex; 218 pthread_cond_t state_cond; 219 OMX_STATETYPE state; 220 OMX_ERRORTYPE error; 221 222 unsigned mutex_cond_inited_cnt; 223 224 int eos_sent, got_eos; 225 226 uint8_t *output_buf; 227 int output_buf_size; 228 229 int input_zerocopy; 230 int profile; 231} OMXCodecContext; 232 233#define NB_MUTEX_CONDS 6 234#define OFF(field) offsetof(OMXCodecContext, field) 235DEFINE_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 239static void append_buffer(pthread_mutex_t *mutex, pthread_cond_t *cond, 240 int* array_size, OMX_BUFFERHEADERTYPE **array, 241 OMX_BUFFERHEADERTYPE *buffer) 242{ 243 pthread_mutex_lock(mutex); 244 array[(*array_size)++] = buffer; 245 pthread_cond_broadcast(cond); 246 pthread_mutex_unlock(mutex); 247} 248 249static 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; 254 pthread_mutex_lock(mutex); 255 if (wait) { 256 while (!*array_size) 257 pthread_cond_wait(cond, mutex); 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 } 266 pthread_mutex_unlock(mutex); 267 return buffer; 268} 269 270static 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 312static 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 330static 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 339static const OMX_CALLBACKTYPE callbacks = { 340 event_handler, 341 empty_buffer_done, 342 fill_buffer_done 343}; 344 345static 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); 361 return AVERROR_ENCODER_NOT_FOUND; 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); 375end: 376 for (i = 0; i < num; i++) 377 av_free(components[i]); 378 av_free(components); 379 return ret; 380} 381 382static 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) 389 ret = AVERROR_ENCODER_NOT_FOUND; 390 pthread_mutex_unlock(&s->state_mutex); 391 return ret; 392} 393 394static 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) { 535 case FF_PROFILE_H264_BASELINE: 536 avc.eProfile = OMX_VIDEO_AVCProfileBaseline; 537 break; 538 case FF_PROFILE_H264_MAIN: 539 avc.eProfile = OMX_VIDEO_AVCProfileMain; 540 break; 541 case FF_PROFILE_H264_HIGH: 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 597static av_cold void cleanup(OMXCodecContext *s) 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 642static av_cold int omx_encode_init(AVCodecContext *avctx) 643{ 644 OMXCodecContext *s = avctx->priv_data; 645 int ret = AVERROR_ENCODER_NOT_FOUND; 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) 656 return AVERROR_ENCODER_NOT_FOUND; 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); 699 ret = AVERROR_UNKNOWN; 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; 726fail: 727 return ret; 728} 729 730 731static int omx_encode_frame(AVCodecContext *avctx, AVPacket *pkt, 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, }; 805 INIT_STRUCT(config); 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, }; 813 INIT_STRUCT(config); 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; 882 pkt->pts = av_rescale_q(from_omx_ticks(buffer->nTimeStamp), AV_TIME_BASE_Q, avctx->time_base); 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) 888 pkt->flags |= AV_PKT_FLAG_KEY; 889 *got_packet = 1; 890 } else { 891#if CONFIG_OMX_RPI 892 had_partial = 1; 893#endif 894 } 895 } 896end: 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); 901 ret = AVERROR_UNKNOWN; 902 } 903 } 904 return ret; 905} 906 907static av_cold int omx_encode_end(AVCodecContext *avctx) 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 918static 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 929static const enum AVPixelFormat omx_encoder_pix_fmts[] = { 930 AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE 931}; 932 933static 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}; 939const FFCodec ff_mpeg4_omx_encoder = { 940 .p.name = "mpeg4_omx", 941 .p.long_name = NULL_IF_CONFIG_SMALL("OpenMAX IL MPEG-4 video encoder"), 942 .p.type = AVMEDIA_TYPE_VIDEO, 943 .p.id = AV_CODEC_ID_MPEG4, 944 .priv_data_size = sizeof(OMXCodecContext), 945 .init = omx_encode_init, 946 FF_CODEC_ENCODE_CB(omx_encode_frame), 947 .close = omx_encode_end, 948 .p.pix_fmts = omx_encoder_pix_fmts, 949 .p.capabilities = AV_CODEC_CAP_DELAY, 950 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, 951 .p.priv_class = &omx_mpeg4enc_class, 952}; 953 954static 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}; 960const FFCodec ff_h264_omx_encoder = { 961 .p.name = "h264_omx", 962 .p.long_name = NULL_IF_CONFIG_SMALL("OpenMAX IL H.264 video encoder"), 963 .p.type = AVMEDIA_TYPE_VIDEO, 964 .p.id = AV_CODEC_ID_H264, 965 .priv_data_size = sizeof(OMXCodecContext), 966 .init = omx_encode_init, 967 FF_CODEC_ENCODE_CB(omx_encode_frame), 968 .close = omx_encode_end, 969 .p.pix_fmts = omx_encoder_pix_fmts, 970 .p.capabilities = AV_CODEC_CAP_DELAY, 971 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, 972 .p.priv_class = &omx_h264enc_class, 973}; 974