30 #include <OMX_Component.h> 
   53     s.nLowPart  = 
value & 0xffffffff;
 
   62 #define to_omx_ticks(x) (x) 
   63 #define from_omx_ticks(x) (x) 
   66 #define INIT_STRUCT(x) do {                                               \ 
   67         x.nSize = sizeof(x);                                              \ 
   68         x.nVersion = s->version;                                          \ 
   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;                                       \ 
   84     OMX_ERRORTYPE (*
ptr_GetHandle)(OMX_HANDLETYPE*, OMX_STRING, OMX_PTR, OMX_CALLBACKTYPE*);
 
   94     snprintf(buf, 
sizeof(buf), 
"%s%s", prefix ? prefix : 
"", symbol);
 
   95     return dlsym(handle, buf);
 
   99                                 const char *libname, 
const char *prefix,
 
  100                                 const char *libname2)
 
  103         s->lib2 = dlopen(libname2, RTLD_NOW | RTLD_GLOBAL);
 
  108         s->host_init = dlsym(
s->lib2, 
"bcm_host_init");
 
  116     s->lib = dlopen(libname, RTLD_NOW | RTLD_GLOBAL);
 
  123     s->ptr_ComponentNameEnum   = 
dlsym_prefixed(
s->lib, 
"OMX_ComponentNameEnum", 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) {
 
  144     static const char * 
const libnames[] = {
 
  146         "/opt/vc/lib/libopenmaxil.so", 
"/opt/vc/lib/libbcm_host.so",
 
  148         "libOMX_Core.so", 
NULL,
 
  149         "libOmxCore.so", 
NULL,
 
  153     const char* 
const* nameptr;
 
  157     omx_context = 
av_mallocz(
sizeof(*omx_context));
 
  167         for (nameptr = libnames; *nameptr; nameptr += 2)
 
  168             if (!(
ret = 
omx_try_load(omx_context, logctx, nameptr[0], prefix, nameptr[1])))
 
  187     dlclose(omx_context->
lib);
 
  234 #define NB_MUTEX_CONDS 6 
  235 #define OFF(field) offsetof(OMXCodecContext, field) 
  237                     (
OFF(input_mutex), 
OFF(output_mutex), 
OFF(state_mutex)),
 
  238                     (
OFF(input_cond),  
OFF(output_cond),  
OFF(state_cond)));
 
  241                           int* array_size, OMX_BUFFERHEADERTYPE **
array,
 
  242                           OMX_BUFFERHEADERTYPE *
buffer)
 
  251                                         int* array_size, OMX_BUFFERHEADERTYPE **
array,
 
  254     OMX_BUFFERHEADERTYPE *
buffer;
 
  260     if (*array_size > 0) {
 
  263         memmove(&
array[0], &
array[1], (*array_size) * 
sizeof(OMX_BUFFERHEADERTYPE*));
 
  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)
 
  286     case OMX_EventCmdComplete:
 
  287         if (data1 == OMX_CommandStateSet) {
 
  293         } 
else if (data1 == OMX_CommandPortDisable) {
 
  295         } 
else if (data1 == OMX_CommandPortEnable) {
 
  299                                              (uint32_t) data1, (uint32_t) data2);
 
  302     case OMX_EventPortSettingsChanged:
 
  307                                          event, (uint32_t) data1, (uint32_t) data2);
 
  310     return OMX_ErrorNone;
 
  314                                        OMX_BUFFERHEADERTYPE *
buffer)
 
  317     if (
s->input_zerocopy) {
 
  318         if (
buffer->pAppPrivate) {
 
  319             if (
buffer->pOutputPortPrivate)
 
  327                   &
s->num_free_in_buffers, 
s->free_in_buffers, 
buffer);
 
  328     return OMX_ErrorNone;
 
  332                                       OMX_BUFFERHEADERTYPE *
buffer)
 
  336                   &
s->num_done_out_buffers, 
s->done_out_buffers, 
buffer);
 
  337     return OMX_ErrorNone;
 
  347                                   const char *role, 
char *str, 
int str_size)
 
  355         av_strlcpy(str, 
"OMX.broadcom.video_encode", str_size);
 
  364     components = 
av_calloc(num, 
sizeof(*components));
 
  367     for (
i = 0; 
i < num; 
i++) {
 
  368         components[
i] = 
av_mallocz(OMX_MAX_STRINGNAME_SIZE);
 
  369         if (!components[
i]) {
 
  377     for (
i = 0; 
i < num; 
i++)
 
  387     while (
s->state != 
state && 
s->error == OMX_ErrorNone)
 
  389     if (
s->error != OMX_ErrorNone)
 
  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 };
 
  406     s->version.s.nVersionMajor = 1;
 
  407     s->version.s.nVersionMinor = 1;
 
  408     s->version.s.nRevision     = 2;
 
  410     err = 
s->omx_context->ptr_GetHandle(&
s->handle, 
s->component_name, 
s, (OMX_CALLBACKTYPE*) &
callbacks);
 
  411     if (err != OMX_ErrorNone) {
 
  418     av_strlcpy(role_params.cRole, role, 
sizeof(role_params.cRole));
 
  420     OMX_SetParameter(
s->handle, OMX_IndexParamStandardComponentRole, &role_params);
 
  423     err = OMX_GetParameter(
s->handle, OMX_IndexParamVideoInit, &video_port_params);
 
  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 };
 
  431         port_params.nPortIndex = port;
 
  432         err = OMX_GetParameter(
s->handle, OMX_IndexParamPortDefinition, &port_params);
 
  433         if (err != OMX_ErrorNone) {
 
  437         if (port_params.eDir == OMX_DirInput && 
s->in_port < 0) {
 
  438             in_port_params = port_params;
 
  440         } 
else if (port_params.eDir == OMX_DirOutput && 
s->out_port < 0) {
 
  441             out_port_params = port_params;
 
  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);
 
  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)
 
  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;
 
  463     if (
s->color_format == 0) {
 
  468     in_port_params.bEnabled   = OMX_TRUE;
 
  469     in_port_params.bPopulated = OMX_FALSE;
 
  470     in_port_params.eDomain    = OMX_PortDomainVideo;
 
  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;
 
  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;
 
  488     err = OMX_SetParameter(
s->handle, OMX_IndexParamPortDefinition, &in_port_params);
 
  490     err = OMX_GetParameter(
s->handle, OMX_IndexParamPortDefinition, &in_port_params);
 
  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;
 
  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;
 
  509         out_port_params.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4;
 
  511         out_port_params.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
 
  513     err = OMX_SetParameter(
s->handle, OMX_IndexParamPortDefinition, &out_port_params);
 
  515     err = OMX_GetParameter(
s->handle, OMX_IndexParamPortDefinition, &out_port_params);
 
  517     s->num_out_buffers = out_port_params.nBufferCountActual;
 
  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)
 
  528         OMX_VIDEO_PARAM_AVCTYPE avc = { 0 };
 
  530         avc.nPortIndex = 
s->out_port;
 
  531         err = OMX_GetParameter(
s->handle, OMX_IndexParamVideoAvc, &avc);
 
  537             avc.eProfile = OMX_VIDEO_AVCProfileBaseline;
 
  540             avc.eProfile = OMX_VIDEO_AVCProfileMain;
 
  543             avc.eProfile = OMX_VIDEO_AVCProfileHigh;
 
  548         err = OMX_SetParameter(
s->handle, OMX_IndexParamVideoAvc, &avc);
 
  552     err = OMX_SendCommand(
s->handle, OMX_CommandStateSet, OMX_StateIdle, 
NULL);
 
  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)
 
  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);
 
  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;
 
  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);
 
  574     s->num_out_buffers = 
i;
 
  580     err = OMX_SendCommand(
s->handle, OMX_CommandStateSet, OMX_StateExecuting, 
NULL);
 
  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];
 
  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];
 
  606         executing = 
s->state == OMX_StateExecuting;
 
  610             OMX_SendCommand(
s->handle, OMX_CommandStateSet, OMX_StateIdle, 
NULL);
 
  612             OMX_SendCommand(
s->handle, OMX_CommandStateSet, OMX_StateLoaded, 
NULL);
 
  613             for (
int i = 0; 
i < 
s->num_in_buffers; 
i++) {
 
  615                                                         &
s->num_free_in_buffers, 
s->free_in_buffers, 1);
 
  616                 if (
s->input_zerocopy)
 
  618                 OMX_FreeBuffer(
s->handle, 
s->in_port, 
buffer);
 
  620             for (
int i = 0; 
i < 
s->num_out_buffers; 
i++) {
 
  622                                                         &
s->num_done_out_buffers, 
s->done_out_buffers, 1);
 
  623                 OMX_FreeBuffer(
s->handle, 
s->out_port, 
buffer);
 
  628             s->omx_context->ptr_FreeHandle(
s->handle);
 
  633         s->omx_context = 
NULL;
 
  648     OMX_BUFFERHEADERTYPE *
buffer;
 
  655     s->omx_context = 
omx_init(avctx, 
s->libname, 
s->libprefix);
 
  660     s->state = OMX_StateLoaded;
 
  661     s->error = OMX_ErrorNone;
 
  665         role = 
"video_encoder.mpeg4";
 
  668         role = 
"video_encoder.avc";
 
  674     if ((
ret = 
find_component(
s->omx_context, avctx, role, 
s->component_name, 
sizeof(
s->component_name))) < 0)
 
  685                                 &
s->num_done_out_buffers, 
s->done_out_buffers, 1);
 
  686             if (
buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
 
  695             err = OMX_FillThisBuffer(
s->handle, 
buffer);
 
  696             if (err != OMX_ErrorNone) {
 
  698                               &
s->num_done_out_buffers, 
s->done_out_buffers, 
buffer);
 
  707                 int nals[32] = { 0 };
 
  737     OMX_BUFFERHEADERTYPE* 
buffer;
 
  746                             &
s->num_free_in_buffers, 
s->free_in_buffers, 1);
 
  750         if (
s->input_zerocopy) {
 
  754             if (
frame->linesize[0] == src_linesize[0] &&
 
  755                 frame->linesize[1] == src_linesize[1] &&
 
  756                 frame->linesize[2] == src_linesize[2] &&
 
  768                     buffer->pAppPrivate = local;
 
  778                 if (image_buffer_size >= 0)
 
  785                     buffer->pAppPrivate = buf;
 
  787                     buffer->pOutputPortPrivate = (
void*) 1;
 
  799         buffer->nFlags = OMX_BUFFERFLAG_ENDOFFRAME;
 
  806             OMX_CONFIG_BOOLEANTYPE 
config = {0, };
 
  808             config.bEnabled = OMX_TRUE;
 
  809             err = OMX_SetConfig(
s->handle, OMX_IndexConfigBrcmVideoRequestIFrame, &
config);
 
  810             if (err != OMX_ErrorNone) {
 
  814             OMX_CONFIG_INTRAREFRESHVOPTYPE 
config = {0, };
 
  816             config.nPortIndex = 
s->out_port;
 
  817             config.IntraRefreshVOP = OMX_TRUE;
 
  818             err = OMX_SetConfig(
s->handle, OMX_IndexConfigVideoIntraVOPRefresh, &
config);
 
  819             if (err != OMX_ErrorNone) {
 
  824         err = OMX_EmptyThisBuffer(
s->handle, 
buffer);
 
  825         if (err != OMX_ErrorNone) {
 
  830     } 
else if (!
s->eos_sent) {
 
  832                             &
s->num_free_in_buffers, 
s->free_in_buffers, 1);
 
  835         buffer->nFlags = OMX_BUFFERFLAG_EOS;
 
  837         err = OMX_EmptyThisBuffer(
s->handle, 
buffer);
 
  838         if (err != OMX_ErrorNone) {
 
  846     while (!*got_packet && 
ret == 0 && !
s->got_eos) {
 
  851                             &
s->num_done_out_buffers, 
s->done_out_buffers,
 
  852                             !
frame || had_partial);
 
  856         if (
buffer->nFlags & OMX_BUFFERFLAG_EOS)
 
  870                 s->output_buf_size = 0;
 
  873             memcpy(
s->output_buf + 
s->output_buf_size, 
buffer->pBuffer + 
buffer->nOffset, 
buffer->nFilledLen);
 
  874             s->output_buf_size += 
buffer->nFilledLen;
 
  875             if (
buffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) {
 
  879                     s->output_buf_size = 0;
 
  882                 s->output_buf = 
NULL;
 
  883                 s->output_buf_size = 0;
 
  889                 if (
buffer->nFlags & OMX_BUFFERFLAG_SYNCFRAME)
 
  899         err = OMX_FillThisBuffer(
s->handle, 
buffer);
 
  900         if (err != OMX_ErrorNone) {
 
  917 #define OFFSET(x) offsetof(OMXCodecContext, x) 
  918 #define VDE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_ENCODING_PARAM 
  919 #define VE  AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM 
  923     { 
"zerocopy", 
"Try to avoid copying input frames if possible", 
OFFSET(input_zerocopy), 
AV_OPT_TYPE_INT, { .i64 = CONFIG_OMX_RPI }, 0, 1, 
VE },
 
  942     .
p.
name           = 
"mpeg4_omx",
 
  964     .
p.
name           = 
"h264_omx",