RPi2,OpenMAX,死锁

时间:2015-12-31 11:15:14

标签: c++ linux multithreading raspberry-pi openmax

环境

  • Raspberry Pi 2 B +
  • Debian Linux
  • OpenMAX IL

用例

  • OpenMAX Camera Video捕获
    • 禁用相机端口
    • 设置了渲染器/摄像机隧道
    • 所有组件状态都设置为空闲
    • 已启用端口

问题描述

启用摄像机输入端口(端口#73)的第一个端口,使用“OMX_CommandPortEnable”命令启用端口,与“OMX_CommandPortDisable”命令一样,相机组件需要启动它“ OMX_CALLBACKTYPE :: EventHandler“事件处理程序具有”eEvent == OMX_EventCmdComplete“和”nData1 == OMX_CommandPortEnable“,但是,这种情况从未发生过,应用程序无限等待端口启用。

问题分析

我正在使用std :: condition_variable与std :: mutex一起等待状态更改完成,因此,OMX_CALLBACKTYPE :: EventHandler更新条件变量并在调用者线程锁定std时调用“notify_one()”: :mutex并等待设置条件变量,使用这种方法永远不会调用“OMX_CALLBACKTYPE :: EventHandler”(带任何参数),程序永远锁定。
注意:在等待条件变量时,验证互斥锁不被拥有,这是通过验证(0 == std :: mutex :: __ owner)来完成的。
HOWEVER ,通过迭代调用usleep和OMX_GetParameter(OMX_IndexParamPortDefinition)来轮询端口状态时,一切正常。

手头的问题

为什么在轮询它的值时会触发“OMX_CALLBACKTYPE :: EventHandler”而在使用conditional_variable时不会触发?有窗户就有APC& amp;警报线程,在linux中有任何等价物吗?可以解释上面提到的一个吗?

1 个答案:

答案 0 :(得分:1)

我的经验是,在端口填充缓冲区之前,启用端口不会发出事件回调。也就是说,序列是:

  • 将端口设置为已启用(OMX_SendCommand()OMX_CommandPortEnable)。
  • 填充端口缓冲区(OMX_AllocateBuffer()OMX_UseBuffer())。
  • 接收OMX_CommandPortEnable事件回调。

如果在分配缓冲区之前等待事件回调,那么就会出现死锁。

当您通过测试OMX_PARAM_PORTDEFINITIONTYPE.bEnabled进行投票时,会立即返回OMX_TRUE,因为the spec表示此成员已同步设置:

  

端口应立即在其端口定义中设置bEnabled   端口收到OMX_CommandPortEnable时的结构。

以下是我认为当事情发生在你身上时所发生的事情":

  • 将端口设置为启用。
  • 轮询直到bEnabledOMX_TRUE(会立即发生)。
  • 填充端口缓冲区。
  • 接收OMX_CommandPortEnable事件回调。

你可能会错误地认为它是按照这个顺序发生的:

  • 将端口设置为启用。
  • 轮询直到bEnabledOMX_TRUE(会立即发生)。
  • 接收OMX_CommandPortEnable事件回调。
  • 填充端口缓冲区。

这似乎使用条件变量以某种方式改变了OpenMAX的行为。实际上bEnabledOMX_CommandPortEnable回调并没有真正报告相同的事情。我不相信在启用端口和分配缓冲区之间任何同步都是必要的(或者是可取的)。