示例#1
0
bool CMMALRenderer::init_vout(ERenderFormat format)
{
  CSingleLock lock(m_sharedSection);
  bool formatChanged = m_format != format;
  MMAL_STATUS_T status;

  CLog::Log(LOGDEBUG, "%s::%s configured:%d format:%d->%d", CLASSNAME, __func__, m_bConfigured, m_format, format);

  if (m_bMMALConfigured && formatChanged)
    UnInitMMAL();

  if (m_bMMALConfigured)
    return true;

  m_format = format;
  if (m_format != RENDER_FMT_MMAL && m_format != RENDER_FMT_YUV420P)
    return true;

  /* Create video renderer */
  status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER, &m_vout);
  if(status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to create vout component (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }

  m_vout->control->userdata = (struct MMAL_PORT_USERDATA_T *)this;
  status = mmal_port_enable(m_vout->control, vout_control_port_cb);
  if(status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to enable vout control port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }
  m_vout_input = m_vout->input[0];
  m_vout_input->userdata = (struct MMAL_PORT_USERDATA_T *)this;
  MMAL_ES_FORMAT_T *es_format = m_vout_input->format;

  es_format->type = MMAL_ES_TYPE_VIDEO;
  es_format->es->video.crop.width = m_sourceWidth;
  es_format->es->video.crop.height = m_sourceHeight;

  if (m_format == RENDER_FMT_MMAL)
  {
    es_format->encoding = MMAL_ENCODING_OPAQUE;
    es_format->es->video.width = m_sourceWidth;
    es_format->es->video.height = m_sourceHeight;
  }
  else if (m_format == RENDER_FMT_YUV420P)
  {
    const int pitch = ALIGN_UP(m_sourceWidth, 32);
    const int aligned_height = ALIGN_UP(m_sourceHeight, 16);

    es_format->encoding = MMAL_ENCODING_I420;
    es_format->es->video.width = pitch;
    es_format->es->video.height = aligned_height;

    if (CONF_FLAGS_YUVCOEF_MASK(m_iFlags) == CONF_FLAGS_YUVCOEF_BT709)
      es_format->es->video.color_space = MMAL_COLOR_SPACE_ITUR_BT709;
    else if (CONF_FLAGS_YUVCOEF_MASK(m_iFlags) == CONF_FLAGS_YUVCOEF_BT601)
      es_format->es->video.color_space = MMAL_COLOR_SPACE_ITUR_BT601;
    else if (CONF_FLAGS_YUVCOEF_MASK(m_iFlags) == CONF_FLAGS_YUVCOEF_240M)
      es_format->es->video.color_space = MMAL_COLOR_SPACE_SMPTE240M;
  }

  if (m_format == RENDER_FMT_MMAL)
  {
    status = mmal_port_parameter_set_boolean(m_vout_input, MMAL_PARAMETER_ZERO_COPY,  MMAL_TRUE);
    if (status != MMAL_SUCCESS)
       CLog::Log(LOGERROR, "%s::%s Failed to enable zero copy mode on %s (status=%x %s)", CLASSNAME, __func__, m_vout_input->name, status, mmal_status_to_string(status));
  }
  status = mmal_port_format_commit(m_vout_input);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to commit vout input format (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }

  m_vout_input->buffer_num = std::max(m_vout_input->buffer_num_recommended, (uint32_t)m_NumYV12Buffers);
  m_vout_input->buffer_size = m_vout_input->buffer_size_recommended;

  status = mmal_port_enable(m_vout_input, vout_input_port_cb_static);
  if(status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to vout enable input port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }

  status = mmal_component_enable(m_vout);
  if(status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to enable vout component (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }

  m_vout_input_pool = mmal_port_pool_create(m_vout_input , m_vout_input->buffer_num, m_vout_input->buffer_size);
  if (!m_vout_input_pool)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to create pool for decoder input port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }
  return true;
}
示例#2
0
bool CMMALRenderer::Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_format, unsigned int orientation)
{
    ReleaseBuffers();

    m_sourceWidth  = width;
    m_sourceHeight = height;
    m_renderOrientation = orientation;

    m_fps = fps;
    m_iFlags = flags;
    m_format = format;

    CLog::Log(LOGDEBUG, "%s::%s - %dx%d->%dx%d@%.2f flags:%x format:%d ext:%x orient:%d", CLASSNAME, __func__, width, height, d_width, d_height, fps, flags, format, extended_format, orientation);

    m_RenderUpdateCallBackFn = NULL;
    m_RenderUpdateCallBackCtx = NULL;

    // calculate the input frame aspect ratio
    CalculateFrameAspectRatio(d_width, d_height);
    ChooseBestResolution(fps);
    m_destWidth = g_graphicsContext.GetResInfo(m_resolution).iWidth;
    m_destHeight = g_graphicsContext.GetResInfo(m_resolution).iHeight;
    SetViewMode(CMediaSettings::Get().GetCurrentVideoSettings().m_ViewMode);
    ManageDisplay();

    if (m_format == RENDER_FMT_MMAL|| m_format == RENDER_FMT_YUV420P)
    {
        MMAL_ES_FORMAT_T *es_format = mmal_format_alloc();
        es_format->type = MMAL_ES_TYPE_VIDEO;
        es_format->es->video.crop.width = m_sourceWidth;
        es_format->es->video.crop.height = m_sourceHeight;

        if (m_format == RENDER_FMT_MMAL)
        {
            es_format->encoding = MMAL_ENCODING_OPAQUE;
            es_format->es->video.width = m_sourceWidth;
            es_format->es->video.height = m_sourceHeight;
        }
        else if (m_format == RENDER_FMT_YUV420P)
        {
            const int pitch = ALIGN_UP(m_sourceWidth, 32);
            const int aligned_height = ALIGN_UP(m_sourceHeight, 16);

            es_format->encoding = MMAL_ENCODING_I420;
            es_format->es->video.width = pitch;
            es_format->es->video.height = aligned_height;

            if (CONF_FLAGS_YUVCOEF_MASK(m_iFlags) == CONF_FLAGS_YUVCOEF_BT709)
                es_format->es->video.color_space = MMAL_COLOR_SPACE_ITUR_BT709;
            else if (CONF_FLAGS_YUVCOEF_MASK(m_iFlags) == CONF_FLAGS_YUVCOEF_BT601)
                es_format->es->video.color_space = MMAL_COLOR_SPACE_ITUR_BT601;
            else if (CONF_FLAGS_YUVCOEF_MASK(m_iFlags) == CONF_FLAGS_YUVCOEF_240M)
                es_format->es->video.color_space = MMAL_COLOR_SPACE_SMPTE240M;
        }
        if (m_bConfigured)
            UnInitMMAL();
        m_bConfigured = init_vout(es_format);
        mmal_format_free(es_format);
    }
    else
        m_bConfigured = true;

    return m_bConfigured;
}
示例#3
0
bool CMMALRenderer::init_vout(ERenderFormat format, bool opaque)
{
  CSingleLock lock(m_sharedSection);
  bool formatChanged = m_format != format || m_opaque != opaque;
  MMAL_STATUS_T status;

  CLog::Log(LOGDEBUG, "%s::%s configured:%d format %d->%d opaque %d->%d", CLASSNAME, __func__, m_bConfigured, m_format, format, m_opaque, opaque);

  if (m_bMMALConfigured && formatChanged)
    UnInitMMAL();

  if (m_bMMALConfigured || format != RENDER_FMT_MMAL)
    return true;

  m_format = format;
  m_opaque = opaque;

  /* Create video renderer */
  status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER, &m_vout);
  if(status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to create vout component (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }

  m_vout_input = m_vout->input[0];
  m_vout_input->userdata = (struct MMAL_PORT_USERDATA_T *)this;
  MMAL_ES_FORMAT_T *es_format = m_vout_input->format;

  es_format->type = MMAL_ES_TYPE_VIDEO;
  if (CONF_FLAGS_YUVCOEF_MASK(m_iFlags) == CONF_FLAGS_YUVCOEF_BT709)
    es_format->es->video.color_space = MMAL_COLOR_SPACE_ITUR_BT709;
  else if (CONF_FLAGS_YUVCOEF_MASK(m_iFlags) == CONF_FLAGS_YUVCOEF_BT601)
    es_format->es->video.color_space = MMAL_COLOR_SPACE_ITUR_BT601;
  else if (CONF_FLAGS_YUVCOEF_MASK(m_iFlags) == CONF_FLAGS_YUVCOEF_240M)
    es_format->es->video.color_space = MMAL_COLOR_SPACE_SMPTE240M;

  es_format->es->video.crop.width = m_sourceWidth;
  es_format->es->video.crop.height = m_sourceHeight;
  es_format->es->video.width = m_sourceWidth;
  es_format->es->video.height = m_sourceHeight;

  es_format->encoding = m_opaque ? MMAL_ENCODING_OPAQUE : MMAL_ENCODING_I420;

  status = mmal_port_parameter_set_boolean(m_vout_input, MMAL_PARAMETER_ZERO_COPY,  MMAL_TRUE);
  if (status != MMAL_SUCCESS)
     CLog::Log(LOGERROR, "%s::%s Failed to enable zero copy mode on %s (status=%x %s)", CLASSNAME, __func__, m_vout_input->name, status, mmal_status_to_string(status));

  status = mmal_port_format_commit(m_vout_input);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to commit vout input format (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }

  m_vout_input->buffer_num = std::max(m_vout_input->buffer_num_recommended, (uint32_t)m_NumYV12Buffers+(m_opaque?0:32));
  m_vout_input->buffer_size = m_vout_input->buffer_size_recommended;

  status = mmal_port_enable(m_vout_input, vout_input_port_cb_static);
  if(status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to vout enable input port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }

  status = mmal_component_enable(m_vout);
  if(status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to enable vout component (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }

  CLog::Log(LOGDEBUG, "%s::%s Created pool of size %d x %d", CLASSNAME, __func__, m_vout_input->buffer_num, m_vout_input->buffer_size);
  m_vout_input_pool = mmal_port_pool_create(m_vout_input , m_vout_input->buffer_num, m_opaque ? m_vout_input->buffer_size:0);
  if (!m_vout_input_pool)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to create pool for decoder input port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }
  if (!CSettings::GetInstance().GetBool("videoplayer.usedisplayasclock"))
  {
    m_queue = mmal_queue_create();
    Create();
  }
  return true;
}