Пример #1
0
Файл: codec.c Проект: Adatan/vlc
static void output_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
{
    decoder_t *dec = (decoder_t *)port->userdata;
    decoder_sys_t *sys = dec->p_sys;
    picture_t *picture;
    MMAL_EVENT_FORMAT_CHANGED_T *fmt;
    MMAL_ES_FORMAT_T *format;

    if (buffer->cmd == 0) {
        if (buffer->length > 0) {
            mmal_queue_put(sys->decoded_pictures, buffer);
        } else {
            picture = (picture_t *)buffer->user_data;
            picture_Release(picture);
            if (sys->output_pool) {
                buffer->user_data = NULL;
                buffer->alloc_size = 0;
                buffer->data = NULL;
                mmal_buffer_header_release(buffer);
            }
        }
        atomic_fetch_sub(&sys->output_in_transit, 1);
        vlc_sem_post(&sys->sem);
    } else if (buffer->cmd == MMAL_EVENT_FORMAT_CHANGED) {
        fmt = mmal_event_format_changed_get(buffer);

        format = mmal_format_alloc();
        mmal_format_full_copy(format, fmt->format);

        if (sys->opaque)
            format->encoding = MMAL_ENCODING_OPAQUE;

        sys->output_format = format;

        mmal_buffer_header_release(buffer);
    } else {
        mmal_buffer_header_release(buffer);
    }
}
Пример #2
0
CMMALVideo::CMMALVideo()
{
  if (g_advancedSettings.CanLogComponent(LOGVIDEO))
    CLog::Log(LOGDEBUG, "%s::%s %p", CLASSNAME, __func__, this);
  pthread_mutex_init(&m_output_mutex, NULL);

  m_drop_state = false;
  m_decoded_width = 0;
  m_decoded_height = 0;

  m_finished = false;
  m_pFormatName = "mmal-xxxx";

  m_interlace_mode = MMAL_InterlaceProgressive;
  m_interlace_method = VS_INTERLACEMETHOD_NONE;
  m_startframe = false;
  m_decoderPts = DVD_NOPTS_VALUE;
  m_droppedPics = 0;
  m_decode_frame_number = 1;

  m_dec = NULL;
  m_dec_input = NULL;
  m_dec_output = NULL;
  m_dec_input_pool = NULL;
  m_dec_output_pool = NULL;

  m_deint = NULL;
  m_deint_connection = NULL;

  m_codingType = 0;

  m_changed_count = 0;
  m_changed_count_dec = 0;
  m_output_busy = 0;
  m_demux_queue_length = 0;
  m_es_format = mmal_format_alloc();
  m_preroll = true;
  m_speed = DVD_PLAYSPEED_NORMAL;
}
Пример #3
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;
}
Пример #4
0
/** Allocate a port structure */
MMAL_PORT_T *mmal_port_alloc(MMAL_COMPONENT_T *component, MMAL_PORT_TYPE_T type, unsigned int extra_size)
{
   MMAL_PORT_T *port;
   MMAL_PORT_PRIVATE_CORE_T *core;
   unsigned int name_size = strlen(component->name) + sizeof(PORT_NAME_FORMAT);
   unsigned int size = sizeof(*port) + sizeof(MMAL_PORT_PRIVATE_T) +
      sizeof(MMAL_PORT_PRIVATE_CORE_T) + name_size + extra_size;
   MMAL_BOOL_T lock = 0, lock_send = 0, lock_transit = 0, sema_transit = 0;
   MMAL_BOOL_T lock_stats = 0, lock_connection = 0;

   LOG_TRACE("component:%s type:%u extra:%u", component->name, type, extra_size);

   port = vcos_calloc(1, size, "mmal port");
   if (!port)
   {
      LOG_ERROR("failed to allocate port, size %u", size);
      return 0;
   }
   port->type = type;

   port->priv = (MMAL_PORT_PRIVATE_T *)(port+1);
   port->priv->core = core = (MMAL_PORT_PRIVATE_CORE_T *)(port->priv+1);
   if (extra_size)
      port->priv->module = (struct MMAL_PORT_MODULE_T *)(port->priv->core+1);
   port->component = component;
   port->name = core->name = ((char *)(port->priv->core+1)) + extra_size;
   core->name_size = name_size;
   mmal_port_name_update(port);
   core->queue_last = &core->queue_first;

   port->priv->pf_connect = mmal_port_connect_default;

   lock = vcos_mutex_create(&port->priv->core->lock, "mmal port lock") == VCOS_SUCCESS;
   lock_send = vcos_mutex_create(&port->priv->core->send_lock, "mmal port send lock") == VCOS_SUCCESS;
   lock_transit = vcos_mutex_create(&port->priv->core->transit_lock, "mmal port transit lock") == VCOS_SUCCESS;
   sema_transit = vcos_semaphore_create(&port->priv->core->transit_sema, "mmal port transit sema", 1) == VCOS_SUCCESS;
   lock_stats = vcos_mutex_create(&port->priv->core->stats_lock, "mmal stats lock") == VCOS_SUCCESS;
   lock_connection = vcos_mutex_create(&port->priv->core->connection_lock, "mmal connection lock") == VCOS_SUCCESS;

   if (!lock || !lock_send || !lock_transit || !sema_transit || !lock_stats || !lock_connection)
   {
      LOG_ERROR("%s: failed to create sync objects (%u,%u,%u,%u,%u,%u)",
            port->name, lock, lock_send, lock_transit, sema_transit, lock_stats, lock_connection);
      goto error;
   }

   port->format = mmal_format_alloc();
   if (!port->format)
   {
      LOG_ERROR("%s: failed to allocate format object", port->name);
      goto error;
   }
   port->priv->core->format_ptr_copy = port->format;

   LOG_TRACE("%s: created at %p", port->name, port);
   return port;

 error:
   if (lock) vcos_mutex_delete(&port->priv->core->lock);
   if (lock_send) vcos_mutex_delete(&port->priv->core->send_lock);
   if (lock_transit) vcos_mutex_delete(&port->priv->core->transit_lock);
   if (sema_transit) vcos_semaphore_delete(&port->priv->core->transit_sema);
   if (lock_stats) vcos_mutex_delete(&port->priv->core->stats_lock);
   if (lock_connection) vcos_mutex_delete(&port->priv->core->connection_lock);
   if (port->format) mmal_format_free(port->format);
   vcos_free(port);
   return 0;
}