示例#1
0
文件: codec.c 项目: Adatan/vlc
static void CloseDecoder(decoder_t *dec)
{
    decoder_sys_t *sys = dec->p_sys;
    MMAL_BUFFER_HEADER_T *buffer;

    if (!sys)
        return;

    if (sys->component && sys->component->control->is_enabled)
        mmal_port_disable(sys->component->control);

    if (sys->input && sys->input->is_enabled)
        mmal_port_disable(sys->input);

    if (sys->output && sys->output->is_enabled)
        mmal_port_disable(sys->output);

    if (sys->component && sys->component->is_enabled)
        mmal_component_disable(sys->component);

    if (sys->input_pool)
        mmal_pool_destroy(sys->input_pool);

    if (sys->output_format)
        mmal_format_free(sys->output_format);

    /* Free pictures which are decoded but have not yet been sent
     * out to the core */
    while ((buffer = mmal_queue_get(sys->decoded_pictures))) {
        picture_t *pic = (picture_t *)buffer->user_data;
        picture_Release(pic);

        if (sys->output_pool) {
            buffer->user_data = NULL;
            buffer->alloc_size = 0;
            buffer->data = NULL;
            mmal_buffer_header_release(buffer);
        }
    }

    if (sys->decoded_pictures)
        mmal_queue_destroy(sys->decoded_pictures);

    if (sys->output_pool)
        mmal_pool_destroy(sys->output_pool);

    if (sys->component)
        mmal_component_release(sys->component);

    vlc_mutex_destroy(&sys->mutex);
    vlc_sem_destroy(&sys->sem);
    free(sys);

    bcm_host_deinit();
}
示例#2
0
CMMALVideo::~CMMALVideo()
{
  if (g_advancedSettings.CanLogComponent(LOGVIDEO))
    CLog::Log(LOGDEBUG, "%s::%s %p", CLASSNAME, __func__, this);
  assert(m_finished);
  Reset();

  pthread_mutex_destroy(&m_output_mutex);

  if (m_deint && m_deint->control && m_deint->control->is_enabled)
    mmal_port_disable(m_deint->control);

  if (m_dec && m_dec->control && m_dec->control->is_enabled)
    mmal_port_disable(m_dec->control);

  if (m_dec_input && m_dec_input->is_enabled)
    mmal_port_disable(m_dec_input);
  m_dec_input = NULL;

  if (m_dec_output && m_dec_output->is_enabled)
    mmal_port_disable(m_dec_output);
  m_dec_output = NULL;

  if (m_deint_connection)
    mmal_connection_destroy(m_deint_connection);
  m_deint_connection = NULL;

  if (m_deint && m_deint->is_enabled)
    mmal_component_disable(m_deint);

  if (m_dec && m_dec->is_enabled)
      mmal_component_disable(m_dec);

  if (m_dec_input_pool)
    mmal_pool_destroy(m_dec_input_pool);
  m_dec_input_pool = NULL;

  if (m_dec_output_pool)
    mmal_pool_destroy(m_dec_output_pool);
  m_dec_output_pool = NULL;

  if (m_deint)
    mmal_component_destroy(m_deint);
  m_deint = NULL;

  if (m_dec)
    mmal_component_destroy(m_dec);
  m_dec = NULL;
  mmal_format_free(m_es_format);
  m_es_format = NULL;
}
示例#3
0
/** Free a port structure */
void mmal_port_free(MMAL_PORT_T *port)
{
   LOG_TRACE("%s at %p", port ? port->name : "<invalid>", port);

   if (!port)
      return;

   vcos_assert(port->format == port->priv->core->format_ptr_copy);
   mmal_format_free(port->priv->core->format_ptr_copy);
   vcos_semaphore_delete(&port->priv->core->transit_sema);
   vcos_mutex_delete(&port->priv->core->transit_lock);
   vcos_mutex_delete(&port->priv->core->send_lock);
   vcos_mutex_delete(&port->priv->core->lock);
   vcos_free(port);
}
示例#4
0
文件: codec.c 项目: Adatan/vlc
static int change_output_format(decoder_t *dec)
{
    MMAL_PARAMETER_VIDEO_INTERLACE_TYPE_T interlace_type;
    decoder_sys_t *sys = dec->p_sys;
    MMAL_STATUS_T status;
    int pool_size;
    int ret = 0;

    if (atomic_load(&sys->started)) {
        mmal_format_full_copy(sys->output->format, sys->output_format);
        status = mmal_port_format_commit(sys->output);
        if (status != MMAL_SUCCESS) {
            msg_Err(dec, "Failed to commit output format (status=%"PRIx32" %s)",
                    status, mmal_status_to_string(status));
            ret = -1;
            goto port_reset;
        }
        goto apply_fmt;
    }

port_reset:
    msg_Dbg(dec, "%s: Do full port reset", __func__);
    status = mmal_port_disable(sys->output);
    if (status != MMAL_SUCCESS) {
        msg_Err(dec, "Failed to disable output port (status=%"PRIx32" %s)",
                status, mmal_status_to_string(status));
        ret = -1;
        goto out;
    }

    mmal_format_full_copy(sys->output->format, sys->output_format);
    status = mmal_port_format_commit(sys->output);
    if (status != MMAL_SUCCESS) {
        msg_Err(dec, "Failed to commit output format (status=%"PRIx32" %s)",
                status, mmal_status_to_string(status));
        ret = -1;
        goto out;
    }

    if (sys->opaque) {
        sys->output->buffer_num = NUM_ACTUAL_OPAQUE_BUFFERS;
        pool_size = NUM_DECODER_BUFFER_HEADERS;
    } else {
        sys->output->buffer_num = __MAX(sys->output->buffer_num_recommended,
                MIN_NUM_BUFFERS_IN_TRANSIT);
        pool_size = sys->output->buffer_num;
    }

    sys->output->buffer_size = sys->output->buffer_size_recommended;

    status = mmal_port_enable(sys->output, output_port_cb);
    if (status != MMAL_SUCCESS) {
        msg_Err(dec, "Failed to enable output port (status=%"PRIx32" %s)",
                status, mmal_status_to_string(status));
        ret = -1;
        goto out;
    }

    if (!atomic_load(&sys->started)) {
        if (!sys->opaque) {
            sys->output_pool = mmal_port_pool_create(sys->output, pool_size, 0);
            msg_Dbg(dec, "Created output pool with %d pictures", sys->output_pool->headers_num);
        }

        atomic_store(&sys->started, true);

        /* we need one picture from vout for each buffer header on the output
         * port */
        dec->i_extra_picture_buffers = pool_size;

        /* remove what VLC core reserves as it is part of the pool_size
         * already */
        if (dec->fmt_in.i_codec == VLC_CODEC_H264)
            dec->i_extra_picture_buffers -= 19;
        else
            dec->i_extra_picture_buffers -= 3;

        msg_Dbg(dec, "Request %d extra pictures", dec->i_extra_picture_buffers);
    }

apply_fmt:
    dec->fmt_out.video.i_width = sys->output->format->es->video.width;
    dec->fmt_out.video.i_height = sys->output->format->es->video.height;
    dec->fmt_out.video.i_x_offset = sys->output->format->es->video.crop.x;
    dec->fmt_out.video.i_y_offset = sys->output->format->es->video.crop.y;
    dec->fmt_out.video.i_visible_width = sys->output->format->es->video.crop.width;
    dec->fmt_out.video.i_visible_height = sys->output->format->es->video.crop.height;
    dec->fmt_out.video.i_sar_num = sys->output->format->es->video.par.num;
    dec->fmt_out.video.i_sar_den = sys->output->format->es->video.par.den;
    dec->fmt_out.video.i_frame_rate = sys->output->format->es->video.frame_rate.num;
    dec->fmt_out.video.i_frame_rate_base = sys->output->format->es->video.frame_rate.den;

    /* Query interlaced type */
    interlace_type.hdr.id = MMAL_PARAMETER_VIDEO_INTERLACE_TYPE;
    interlace_type.hdr.size = sizeof(MMAL_PARAMETER_VIDEO_INTERLACE_TYPE_T);
    status = mmal_port_parameter_get(sys->output, &interlace_type.hdr);
    if (status != MMAL_SUCCESS) {
        msg_Warn(dec, "Failed to query interlace type from decoder output port (status=%"PRIx32" %s)",
                status, mmal_status_to_string(status));
    } else {
        sys->b_progressive = (interlace_type.eMode == MMAL_InterlaceProgressive);
        sys->b_top_field_first = sys->b_progressive ? true :
            (interlace_type.eMode == MMAL_InterlaceFieldsInterleavedUpperFirst);
        msg_Dbg(dec, "Detected %s%s video (%d)",
                sys->b_progressive ? "progressive" : "interlaced",
                sys->b_progressive ? "" : (sys->b_top_field_first ? " tff" : " bff"),
                interlace_type.eMode);
    }

out:
    mmal_format_free(sys->output_format);
    sys->output_format = NULL;

    return ret;
}
示例#5
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;
}
示例#6
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;
}