Exemple #1
0
static int flush_decoder(decoder_t *dec)
{
    decoder_sys_t *sys = dec->p_sys;
    MMAL_BUFFER_HEADER_T *buffer;
    MMAL_STATUS_T status;
    int ret = 0;

    msg_Dbg(dec, "Flushing decoder ports...");
    mmal_port_disable(sys->output);
    mmal_port_disable(sys->input);
    mmal_port_flush(sys->output);
    mmal_port_flush(sys->input);

    /* Reload extradata if available */
    if (dec->fmt_in.i_codec == VLC_CODEC_H264) {
        if (dec->fmt_in.i_extra > 0) {
            status = mmal_format_extradata_alloc(sys->input->format,
                    dec->fmt_in.i_extra);
            if (status == MMAL_SUCCESS) {
                memcpy(sys->input->format->extradata, dec->fmt_in.p_extra,
                        dec->fmt_in.i_extra);
                sys->input->format->extradata_size = dec->fmt_in.i_extra;
            } else {
                msg_Err(dec, "Failed to allocate extra format data on input port %s (status=%"PRIx32" %s)",
                        sys->input->name, status, mmal_status_to_string(status));
            }
        }
    }

    status = mmal_port_format_commit(sys->input);
    if (status != MMAL_SUCCESS) {
        msg_Err(dec, "Failed to commit format for input port %s (status=%"PRIx32" %s)",
                sys->input->name, status, mmal_status_to_string(status));
    }

    mmal_port_enable(sys->output, output_port_cb);
    mmal_port_enable(sys->input, input_port_cb);

    while (atomic_load(&sys->output_in_transit))
        vlc_sem_wait(&sys->sem);

    /* 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);
        }
    }
    msg_Dbg(dec, "Ports flushed, returning to normal operation");

    return ret;
}
Exemple #2
0
static int set_latency_target(vout_display_t *vd, bool enable)
{
    vout_display_sys_t *sys = vd->sys;
    MMAL_STATUS_T status;

    MMAL_PARAMETER_AUDIO_LATENCY_TARGET_T latency_target = {
        .hdr = { MMAL_PARAMETER_AUDIO_LATENCY_TARGET, sizeof(latency_target) },
        .enable = enable ? MMAL_TRUE : MMAL_FALSE,
        .filter = 2,
        .target = 4000,
        .shift = 3,
        .speed_factor = -135,
        .inter_factor = 500,
        .adj_cap = 20
    };

    status = mmal_port_parameter_set(sys->input, &latency_target.hdr);
    if (status != MMAL_SUCCESS) {
        msg_Err(vd, "Failed to configure latency target on input port %s (status=%"PRIx32" %s)",
                        sys->input->name, status, mmal_status_to_string(status));
        return VLC_EGENERIC;
    }

    return VLC_SUCCESS;
}
Exemple #3
0
/* Send a payload buffer to a connected port/client */
static MMAL_STATUS_T mmal_port_clock_forward_payload(MMAL_PORT_T *port, const MMAL_CLOCK_PAYLOAD_T *payload)
{
   MMAL_STATUS_T status;
   MMAL_BUFFER_HEADER_T *buffer;

   buffer = mmal_queue_get(port->priv->module->queue);
   if (!buffer)
   {
      LOG_ERROR("no free buffers available");
      return MMAL_ENOSPC;
   }

   status = mmal_buffer_header_mem_lock(buffer);
   if (status != MMAL_SUCCESS)
   {
      LOG_ERROR("failed to lock buffer %s", mmal_status_to_string(status));
      mmal_queue_put_back(port->priv->module->queue, buffer);
      goto end;
   }
   buffer->length = sizeof(MMAL_CLOCK_PAYLOAD_T);
   memcpy(buffer->data, payload, buffer->length);
   mmal_buffer_header_mem_unlock(buffer);

   mmal_port_buffer_header_callback(port, buffer);

end:
   return status;
}
Exemple #4
0
/** Callback from a control port. */
static void svp_bh_control_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buf)
{
   SVP_T *svp = (SVP_T *)port->userdata;

   switch (buf->cmd)
   {
   case MMAL_EVENT_EOS:
      LOG_TRACE("%s: EOS", port->name);
      svp_set_stop(svp, SVP_STOP_EOS);
      break;

   case MMAL_EVENT_ERROR:
      LOG_ERROR("%s: MMAL error: %s", port->name,
                mmal_status_to_string(*(MMAL_STATUS_T *)buf->data));
      svp_set_stop(svp, SVP_STOP_ERROR);
      break;

   default:
      LOG_TRACE("%s: buf %p, event %4.4s", port->name, buf, (char *)&buf->cmd);
      break;
   }

   mmal_buffer_header_release(buf);

   vcos_semaphore_post(&svp->sema);
}
Exemple #5
0
/** Connected output port buffer callback */
static void mmal_port_connected_output_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
{
   MMAL_PORT_T* connected_port = port->priv->core->connected_port;
   MMAL_STATUS_T status;

   LOG_TRACE("buffer %p from connected output port %p: data %p, alloc_size %u, length %u",
             buffer, port, buffer->data, buffer->alloc_size, buffer->length);

   if (buffer->cmd)
   {
      MMAL_EVENT_FORMAT_CHANGED_T *event = mmal_event_format_changed_get(buffer);

      /* Handle format changed events */
      if (event)
      {
         /* Apply the change */
         status = mmal_format_full_copy(port->format, event->format);
         if (status == MMAL_SUCCESS)
            status = mmal_port_format_commit(port);
         if (status != MMAL_SUCCESS)
            LOG_ERROR("format commit failed on port %s (%i)", port->name, status);

         /* Forward to the connected port */
         if (status == MMAL_SUCCESS)
            status = mmal_port_send_buffer(connected_port, buffer);

         if (status != MMAL_SUCCESS)
         {
            mmal_event_error_send(port->component, status);
            mmal_buffer_header_release(buffer);
         }
         return; /* Event handled */
      }

      /* FIXME Release other event buffers for now, until we can deal with shared memory issues */
      mmal_buffer_header_release(buffer);
   }
   else
   {
      if (port->is_enabled)
      {
         /* Forward data buffers to the connected input port */
         status = mmal_port_send_buffer(connected_port, buffer);
         if (status != MMAL_SUCCESS)
         {
            LOG_ERROR("%s could not send buffer on port %s (%s)",
                      port->name, connected_port->name, mmal_status_to_string(status));
            mmal_buffer_header_release(buffer);
         }
      }
      else
      {
         /* This port is disabled. Buffer will be a flushed buffer, so
          * return to the pool rather than delivering it.
          */
         mmal_buffer_header_release(buffer);
      }
   }
}
Exemple #6
0
static picture_t *deinterlace(filter_t *filter, picture_t *picture)
{
    filter_sys_t *sys = filter->p_sys;
    MMAL_BUFFER_HEADER_T *buffer;
    picture_t *out_picture = NULL;
    picture_t *ret = NULL;
    MMAL_STATUS_T status;
    unsigned i = 0;

    fill_output_port(filter);

    buffer = picture->p_sys->buffer;
    buffer->user_data = picture;
    buffer->pts = picture->date;
    buffer->cmd = 0;

    if (!picture->p_sys->displayed) {
        vlc_mutex_lock(&sys->buffer_cond_mutex);
        status = mmal_port_send_buffer(sys->input, buffer);
        if (status != MMAL_SUCCESS) {
            msg_Err(filter, "Failed to send buffer to input port (status=%"PRIx32" %s)",
                    status, mmal_status_to_string(status));
            picture_Release(picture);
        } else {
            picture->p_sys->displayed = true;
            atomic_fetch_add(&sys->input_in_transit, 1);
            vlc_cond_signal(&sys->buffer_cond);
        }
        vlc_mutex_unlock(&sys->buffer_cond_mutex);
    } else {
        picture_Release(picture);
    }

    /*
     * Send output buffers
     */
    while(atomic_load(&sys->started) && i < 2) {
        if (buffer = mmal_queue_timedwait(sys->filtered_pictures, 2000)) {
            i++;
            if (!out_picture) {
                out_picture = (picture_t *)buffer->user_data;
                ret = out_picture;
            } else {
                out_picture->p_next = (picture_t *)buffer->user_data;
                out_picture = out_picture->p_next;
            }
            out_picture->date = buffer->pts;
        } else {
            msg_Dbg(filter, "Failed waiting for filtered picture");
            break;
        }
    }
    if (out_picture)
        out_picture->p_next = NULL;

    return ret;
}
Exemple #7
0
/** Send a buffer header to a port */
MMAL_STATUS_T mmal_port_send_buffer(MMAL_PORT_T *port,
   MMAL_BUFFER_HEADER_T *buffer)
{
   MMAL_STATUS_T status;

   if (!port || !port->priv)
   {
      LOG_ERROR("invalid port");
      return MMAL_EINVAL;
   }

#ifdef ENABLE_MMAL_EXTRA_LOGGING
   LOG_TRACE("%s(%i:%i) port %p, buffer %p (%p,%i,%i)",
             port->component->name, (int)port->type, (int)port->index, port, buffer,
             buffer ? buffer->data: 0, buffer ? (int)buffer->offset : 0,
             buffer ? (int)buffer->length : 0);
#endif

   if (!buffer->data && !(port->capabilities & MMAL_PORT_CAPABILITY_PASSTHROUGH))
   {
      LOG_ERROR("%s(%p) received invalid buffer header", port->name, port);
      return MMAL_EINVAL;
   }

   if (!port->priv->pf_send)
      return MMAL_ENOSYS;

   LOCK_SENDING(port);

   if (!port->is_enabled)
   {
      UNLOCK_SENDING(port);
      return MMAL_EINVAL;
   }

   if (port->type == MMAL_PORT_TYPE_OUTPUT && buffer->length)
   {
      LOG_DEBUG("given an output buffer with length != 0");
      buffer->length = 0;
   }

   IN_TRANSIT_INCREMENT(port);
   status = port->priv->pf_send(port, buffer);

   if (status != MMAL_SUCCESS)
   {
      IN_TRANSIT_DECREMENT(port);
      LOG_ERROR("%s: send failed: %s", port->name, mmal_status_to_string(status));
   }
   else
   {
      mmal_port_update_port_stats(port, MMAL_CORE_STATS_RX);
   }

   UNLOCK_SENDING(port);
   return status;
}
Exemple #8
0
static MMAL_STATUS_T mmal_port_disable_internal(MMAL_PORT_T *port)
{
   MMAL_PORT_PRIVATE_CORE_T* core = port->priv->core;
   MMAL_STATUS_T status = MMAL_SUCCESS;
   MMAL_BUFFER_HEADER_T *buffer;

   LOCK_PORT(port);

   if (!port->is_enabled)
      goto end;

   LOCK_SENDING(port);
   port->is_enabled = 0;
   UNLOCK_SENDING(port);

   mmal_component_action_lock(port->component);

   if (core->pool_for_connection)
      mmal_pool_callback_set(core->pool_for_connection, NULL, NULL);

   status = port->priv->pf_disable(port);

   mmal_component_action_unlock(port->component);

   if (status != MMAL_SUCCESS)
   {
      LOG_ERROR("port %p could not be disabled (%s)", port->name, mmal_status_to_string(status));
      LOCK_SENDING(port);
      port->is_enabled = 1;
      UNLOCK_SENDING(port);
      goto end;
   }

   /* Flush our internal queue */
   buffer = port->priv->core->queue_first;
   while (buffer)
   {
      MMAL_BUFFER_HEADER_T *next = buffer->next;
      mmal_port_buffer_header_callback(port, buffer);
      buffer = next;
   }
   port->priv->core->queue_first = 0;
   port->priv->core->queue_last = &port->priv->core->queue_first;

   /* Wait for all the buffers to have come back from the component */
   LOG_DEBUG("%s waiting for %i buffers left in transit", port->name, (int)IN_TRANSIT_COUNT(port));
   IN_TRANSIT_WAIT(port);
   LOG_DEBUG("%s has no buffers left in transit", port->name);

   port->priv->core->buffer_header_callback = NULL;

 end:
   UNLOCK_PORT(port);
   return status;
}
Exemple #9
0
static void do_connect(void)
{
   /* this command needs a vchiq connection */
   MMAL_STATUS_T st;
   if ((st = mmal_vc_init()) != MMAL_SUCCESS)
   {
      fprintf(stderr, "failed to initialize mmal vc library (%i:%s)\n",
            st, mmal_status_to_string(st));
      exit(1);
   }
}
Exemple #10
0
static void control_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
{
    vout_display_t *vd = (vout_display_t *)port->userdata;
    MMAL_STATUS_T status;

    if (buffer->cmd == MMAL_EVENT_ERROR) {
        status = *(uint32_t *)buffer->data;
        msg_Err(vd, "MMAL error %"PRIx32" \"%s\"", status, mmal_status_to_string(status));
    }

    mmal_buffer_header_release(buffer);
}
Exemple #11
0
static int do_components(int argc, const char **argv)
{
   VC_MEM_ACCESS_HANDLE_T vc;
   VC_MEM_ADDR_T addr, statsaddr;
   size_t size;
   MMAL_VC_STATS_T stats;
   int rc;


   if (argc > 2 && (strcasecmp(argv[2], "update") == 0))
   {
      MMAL_STATUS_T status;
      do_connect();
      status = mmal_vc_get_stats(&stats, 0);
      if (status != MMAL_SUCCESS)
      {
         fprintf(stderr, "Failed to update MMAL stats. error %s",
              mmal_status_to_string(status));
         return -1;
      }
   }
   else
   {
      if ((rc = OpenVideoCoreMemory(&vc)) < 0)
      {
         fprintf(stderr,"Unable to open videocore memory: %d\n", rc);
         return -1;
      }
      if (!LookupVideoCoreSymbol(vc, "mmal_vc_stats", &addr, &size))
      {
         fprintf(stderr,"Could not get MMAL stats address\n");
         goto fail;
      }
      if (!ReadVideoCoreUInt32(vc, &statsaddr, addr))
      {
         fprintf(stderr,"Could not read MMAL stats pointer at address 0x%x\n",
               addr);
         goto fail;
      }
      if (!ReadVideoCoreMemory(vc, &stats, statsaddr, sizeof(stats)))
      {
         fprintf(stderr,"Could not read MMAL stats at address 0x%x\n", addr);
         goto fail;
      }
      CloseVideoCoreMemory(vc);
   }
   rc = print_component_stats(&stats);
   return rc;

fail:
   CloseVideoCoreMemory(vc);
   return -1;
}
Exemple #12
0
static int do_version(int argc, const char **argv)
{
   uint32_t maj = UINT_MAX, min = UINT_MAX, minimum;
   MMAL_STATUS_T st = mmal_vc_get_version(&maj, &min, &minimum);
   (void)argc; (void)argv;
   if (st == MMAL_SUCCESS)
   {
      printf("version %d.%02d (min %d)\n", maj, min, minimum);
      return 0;
   }
   else
   {
      fprintf(stderr, "error getting version (%i:%s)\n", st, mmal_status_to_string(st));
      return -1;
   }
}
Exemple #13
0
static MMAL_STATUS_T mmal_port_disable_locked(MMAL_PORT_T *port)
{
   MMAL_PORT_PRIVATE_CORE_T* core = port->priv->core;
   MMAL_STATUS_T status;

   if (!port->is_enabled)
   {
      LOG_ERROR("port %p is not enabled", port);
      return MMAL_EINVAL;
   }

   LOCK_SENDING(port);
   port->is_enabled = 0;
   UNLOCK_SENDING(port);

   mmal_component_action_lock(port->component);

   if (core->pool_for_connection)
      mmal_pool_callback_set(core->pool_for_connection, NULL, NULL);

   status = port->priv->pf_disable(port);

   mmal_component_action_unlock(port->component);

   if (status != MMAL_SUCCESS)
   {
      LOG_ERROR("port %p could not be disabled (%s)", port->name, mmal_status_to_string(status));
      LOCK_SENDING(port);
      port->is_enabled = 1;
      UNLOCK_SENDING(port);
      return status;
   }

   /* Wait for all the buffers to have come back from the component */
   LOG_DEBUG("%s waiting for %i buffers left in transit", port->name, (int)IN_TRANSIT_COUNT(port));
   IN_TRANSIT_WAIT(port);
   LOG_DEBUG("%s has no buffers left in transit", port->name);

   port->priv->core->buffer_header_callback = NULL;

   if (core->connected_port && port->type == MMAL_PORT_TYPE_OUTPUT)
      mmal_port_disable(core->connected_port);

   return status;
}
Exemple #14
0
static int send_output_buffer(filter_t *filter)
{
    filter_sys_t *sys = filter->p_sys;
    MMAL_BUFFER_HEADER_T *buffer;
    MMAL_STATUS_T status;
    picture_t *picture;
    int ret = 0;

    if (!sys->output->is_enabled) {
        ret = VLC_EGENERIC;
        goto out;
    }

    picture = filter_NewPicture(filter);
    if (!picture) {
        msg_Warn(filter, "Failed to get new picture");
        ret = -1;
        goto out;
    }
    picture->format.i_frame_rate = filter->fmt_out.video.i_frame_rate;
    picture->format.i_frame_rate_base = filter->fmt_out.video.i_frame_rate_base;

    buffer = picture->p_sys->buffer;
    buffer->user_data = picture;
    buffer->cmd = 0;

    mmal_picture_lock(picture);

    vlc_mutex_lock(&sys->buffer_cond_mutex);
    status = mmal_port_send_buffer(sys->output, buffer);
    if (status != MMAL_SUCCESS) {
        msg_Err(filter, "Failed to send buffer to output port (status=%"PRIx32" %s)",
                status, mmal_status_to_string(status));
        mmal_buffer_header_release(buffer);
        picture_Release(picture);
        ret = -1;
    } else {
        atomic_fetch_add(&sys->output_in_transit, 1);
        vlc_cond_signal(&sys->buffer_cond);
    }
    vlc_mutex_unlock(&sys->buffer_cond_mutex);

out:
    return ret;
}
Exemple #15
0
void CMMALVideo::dec_control_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
{
  MMAL_STATUS_T status;

  if (buffer->cmd == MMAL_EVENT_ERROR)
  {
    status = (MMAL_STATUS_T)*(uint32_t *)buffer->data;
    CLog::Log(LOGERROR, "%s::%s Error (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
  }
  else if (buffer->cmd == MMAL_EVENT_FORMAT_CHANGED)
  {
    if (g_advancedSettings.CanLogComponent(LOGVIDEO))
      CLog::Log(LOGDEBUG, "%s::%s format changed", CLASSNAME, __func__);
    PortSettingsChanged(port, buffer);
  }
  else
    CLog::Log(LOGERROR, "%s::%s other (cmd:%x data:%x)", CLASSNAME, __func__, buffer->cmd, *(uint32_t *)buffer->data);

  mmal_buffer_header_release(buffer);
}
Exemple #16
0
/** Callback from a control port. Error and EOS events stop playback. */
static void mmalplay_bh_control_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
{
   MMALPLAY_T *ctx = (MMALPLAY_T *)port->userdata;
   LOG_TRACE("%s(%p),%p,%4.4s", port->name, port, buffer, (char *)&buffer->cmd);

   if (buffer->cmd == MMAL_EVENT_ERROR || buffer->cmd == MMAL_EVENT_EOS)
   {
      if (buffer->cmd == MMAL_EVENT_ERROR)
      {
         LOG_INFO("error event from %s: %s", port->name,
                  mmal_status_to_string(*(MMAL_STATUS_T*)buffer->data));
         ctx->status = *(MMAL_STATUS_T *)buffer->data;
      }
      else if (buffer->cmd == MMAL_EVENT_EOS)
         LOG_INFO("%s: EOS received", port->name);
      mmalplay_stop(ctx);
   }

   mmal_buffer_header_release(buffer);
}
Exemple #17
0
/* Initialise all callbacks and setup internal resources */
static MMAL_STATUS_T mmal_port_clock_setup(MMAL_PORT_T *port, MMAL_PORT_CLOCK_EVENT_CB event_cb)
{
   MMAL_STATUS_T status;

   status = mmal_clock_create(&port->priv->module->clock);
   if (status != MMAL_SUCCESS)
   {
      LOG_ERROR("failed to create clock module on port %s (%s)", port->name, mmal_status_to_string(status));
      return status;
   }
   port->priv->module->clock->user_data = port;

   port->buffer_size = sizeof(MMAL_CLOCK_PAYLOAD_T);
   port->buffer_size_min = sizeof(MMAL_CLOCK_PAYLOAD_T);
   port->buffer_num_min = MMAL_PORT_CLOCK_BUFFERS_MIN;
   port->buffer_num_recommended = MMAL_PORT_CLOCK_BUFFERS_MIN;

   port->priv->module->event_cb = event_cb;
   port->priv->module->queue = mmal_queue_create();
   if (!port->priv->module->queue)
   {
      mmal_clock_destroy(port->priv->module->clock);
      return MMAL_ENOMEM;
   }

   port->priv->pf_set_format = mmal_port_clock_set_format;
   port->priv->pf_enable = mmal_port_clock_enable;
   port->priv->pf_disable = mmal_port_clock_disable;
   port->priv->pf_send = mmal_port_clock_send;
   port->priv->pf_flush = mmal_port_clock_flush;
   port->priv->pf_parameter_set = mmal_port_clock_parameter_set;
   port->priv->pf_parameter_get = mmal_port_clock_parameter_get;
   port->priv->pf_connect = mmal_port_clock_connect;
#ifdef __VIDEOCORE__
   port->priv->pf_payload_alloc = mmal_port_clock_payload_alloc;
   port->priv->pf_payload_free = mmal_port_clock_payload_free;
   port->capabilities = MMAL_PORT_CAPABILITY_ALLOCATION;
#endif

   return status;
}
Exemple #18
0
static int do_stats(int argc, const char **argv)
{
   MMAL_VC_STATS_T stats;
   int reset_stats = strcasecmp(argv[1], "reset") == 0;
   MMAL_STATUS_T st = mmal_vc_get_stats(&stats, reset_stats);
   int ret;
   (void)argc; (void)argv;
   if (st != MMAL_SUCCESS)
   {
      fprintf(stderr, "error getting status (%i,%s)\n", st, mmal_status_to_string(st));
      ret = -1;
   }
   else
   {
      unsigned i;
      uint32_t *ptr = (uint32_t*)&stats;
      for (i=0; i<vcos_countof(stats_fields); i++)
      {
         printf("%-32s: %u\n", stats_fields[i].name, ptr[stats_fields[i].offset/sizeof(uint32_t)]);
      }
      ret = 0;
   }
   return ret;
}
Exemple #19
0
static int Open(filter_t *filter)
{
    int32_t frame_duration = filter->fmt_in.video.i_frame_rate != 0 ?
            (int64_t)1000000 * filter->fmt_in.video.i_frame_rate_base /
            filter->fmt_in.video.i_frame_rate : 0;

    MMAL_PARAMETER_IMAGEFX_PARAMETERS_T imfx_param = {
            { MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS, sizeof(imfx_param) },
            MMAL_PARAM_IMAGEFX_DEINTERLACE_ADV,
            2,
            { 3, frame_duration }
    };

    int ret = VLC_SUCCESS;
    MMAL_STATUS_T status;
    filter_sys_t *sys;

    msg_Dbg(filter, "Try to open mmal_deinterlace filter. frame_duration: %d!", frame_duration);

    if (filter->fmt_in.video.i_chroma != VLC_CODEC_MMAL_OPAQUE)
        return VLC_EGENERIC;

    if (filter->fmt_out.video.i_chroma != VLC_CODEC_MMAL_OPAQUE)
        return VLC_EGENERIC;

    sys = calloc(1, sizeof(filter_sys_t));
    if (!sys)
        return VLC_ENOMEM;
    filter->p_sys = sys;

    bcm_host_init();

    status = mmal_component_create(MMAL_COMPONENT_DEFAULT_DEINTERLACE, &sys->component);
    if (status != MMAL_SUCCESS) {
        msg_Err(filter, "Failed to create MMAL component %s (status=%"PRIx32" %s)",
                MMAL_COMPONENT_DEFAULT_DEINTERLACE, status, mmal_status_to_string(status));
        ret = VLC_EGENERIC;
        goto out;
    }

    status = mmal_port_parameter_set(sys->component->output[0], &imfx_param.hdr);
    if (status != MMAL_SUCCESS) {
        msg_Err(filter, "Failed to configure MMAL component %s (status=%"PRIx32" %s)",
                MMAL_COMPONENT_DEFAULT_DEINTERLACE, status, mmal_status_to_string(status));
        ret = VLC_EGENERIC;
        goto out;
    }

    sys->component->control->userdata = (struct MMAL_PORT_USERDATA_T *)filter;
    status = mmal_port_enable(sys->component->control, control_port_cb);
    if (status != MMAL_SUCCESS) {
        msg_Err(filter, "Failed to enable control port %s (status=%"PRIx32" %s)",
                sys->component->control->name, status, mmal_status_to_string(status));
        ret = VLC_EGENERIC;
        goto out;
    }

    sys->input = sys->component->input[0];
    sys->input->userdata = (struct MMAL_PORT_USERDATA_T *)filter;
    if (filter->fmt_in.i_codec == VLC_CODEC_MMAL_OPAQUE)
        sys->input->format->encoding = MMAL_ENCODING_OPAQUE;
    sys->input->format->es->video.width = filter->fmt_in.video.i_width;
    sys->input->format->es->video.height = filter->fmt_in.video.i_height;
    sys->input->format->es->video.crop.x = 0;
    sys->input->format->es->video.crop.y = 0;
    sys->input->format->es->video.crop.width = filter->fmt_in.video.i_width;
    sys->input->format->es->video.crop.height = filter->fmt_in.video.i_height;
    sys->input->format->es->video.par.num = filter->fmt_in.video.i_sar_num;
    sys->input->format->es->video.par.den = filter->fmt_in.video.i_sar_den;

    es_format_Copy(&filter->fmt_out, &filter->fmt_in);
    filter->fmt_out.video.i_frame_rate *= 2;

    status = mmal_port_format_commit(sys->input);
    if (status != MMAL_SUCCESS) {
        msg_Err(filter, "Failed to commit format for input port %s (status=%"PRIx32" %s)",
                        sys->input->name, status, mmal_status_to_string(status));
        ret = VLC_EGENERIC;
        goto out;
    }
    sys->input->buffer_size = sys->input->buffer_size_recommended;
    sys->input->buffer_num = sys->input->buffer_num_recommended;

    if (filter->fmt_in.i_codec == VLC_CODEC_MMAL_OPAQUE) {
        MMAL_PARAMETER_BOOLEAN_T zero_copy = {
            { MMAL_PARAMETER_ZERO_COPY, sizeof(MMAL_PARAMETER_BOOLEAN_T) },
            1
        };

        status = mmal_port_parameter_set(sys->input, &zero_copy.hdr);
        if (status != MMAL_SUCCESS) {
           msg_Err(filter, "Failed to set zero copy on port %s (status=%"PRIx32" %s)",
                    sys->input->name, status, mmal_status_to_string(status));
           goto out;
        }
    }

    status = mmal_port_enable(sys->input, input_port_cb);
    if (status != MMAL_SUCCESS) {
        msg_Err(filter, "Failed to enable input port %s (status=%"PRIx32" %s)",
                sys->input->name, status, mmal_status_to_string(status));
        ret = VLC_EGENERIC;
        goto out;
    }

    sys->output = sys->component->output[0];
    sys->output->userdata = (struct MMAL_PORT_USERDATA_T *)filter;
    mmal_format_full_copy(sys->output->format, sys->input->format);

    status = mmal_port_format_commit(sys->output);
    if (status != MMAL_SUCCESS) {
        msg_Err(filter, "Failed to commit format for output port %s (status=%"PRIx32" %s)",
                        sys->input->name, status, mmal_status_to_string(status));
        ret = VLC_EGENERIC;
        goto out;
    }

    sys->output->buffer_num = 3;

    if (filter->fmt_in.i_codec == VLC_CODEC_MMAL_OPAQUE) {
        MMAL_PARAMETER_BOOLEAN_T zero_copy = {
            { MMAL_PARAMETER_ZERO_COPY, sizeof(MMAL_PARAMETER_BOOLEAN_T) },
            1
        };

        status = mmal_port_parameter_set(sys->output, &zero_copy.hdr);
        if (status != MMAL_SUCCESS) {
           msg_Err(filter, "Failed to set zero copy on port %s (status=%"PRIx32" %s)",
                    sys->output->name, status, mmal_status_to_string(status));
           goto out;
        }
    }

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

    status = mmal_component_enable(sys->component);
    if (status != MMAL_SUCCESS) {
        msg_Err(filter, "Failed to enable component %s (status=%"PRIx32" %s)",
                sys->component->name, status, mmal_status_to_string(status));
        ret = VLC_EGENERIC;
        goto out;
    }

    sys->filtered_pictures = mmal_queue_create();

    filter->pf_video_filter = deinterlace;
    filter->pf_video_flush = flush;
    vlc_mutex_init_recursive(&sys->mutex);
    vlc_mutex_init(&sys->buffer_cond_mutex);
    vlc_cond_init(&sys->buffer_cond);

out:
    if (ret != VLC_SUCCESS)
        Close(filter);

    return ret;
}
Exemple #20
0
static int OpenDecoder(decoder_t *dec)
{
    int ret = VLC_SUCCESS;
    decoder_sys_t *sys;
    MMAL_PARAMETER_UINT32_T extra_buffers;
    MMAL_STATUS_T status;

    if (dec->fmt_in.i_cat != VIDEO_ES)
        return VLC_EGENERIC;

    if (dec->fmt_in.i_codec != VLC_CODEC_MPGV &&
            dec->fmt_in.i_codec != VLC_CODEC_H264)
        return VLC_EGENERIC;

    sys = calloc(1, sizeof(decoder_sys_t));
    if (!sys) {
        ret = VLC_ENOMEM;
        goto out;
    }
    dec->p_sys = sys;
    dec->b_need_packetized = true;

    sys->opaque = var_InheritBool(dec, MMAL_OPAQUE_NAME);
    bcm_host_init();

    status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, &sys->component);
    if (status != MMAL_SUCCESS) {
        msg_Err(dec, "Failed to create MMAL component %s (status=%"PRIx32" %s)",
                MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, status, mmal_status_to_string(status));
        ret = VLC_EGENERIC;
        goto out;
    }

    sys->component->control->userdata = (struct MMAL_PORT_USERDATA_T *)dec;
    status = mmal_port_enable(sys->component->control, control_port_cb);
    if (status != MMAL_SUCCESS) {
        msg_Err(dec, "Failed to enable control port %s (status=%"PRIx32" %s)",
                sys->component->control->name, status, mmal_status_to_string(status));
        ret = VLC_EGENERIC;
        goto out;
    }

    sys->input = sys->component->input[0];
    sys->input->userdata = (struct MMAL_PORT_USERDATA_T *)dec;
    if (dec->fmt_in.i_codec == VLC_CODEC_MPGV)
        sys->input->format->encoding = MMAL_ENCODING_MP2V;
    else
        sys->input->format->encoding = MMAL_ENCODING_H264;

    if (dec->fmt_in.i_codec == VLC_CODEC_H264) {
        if (dec->fmt_in.i_extra > 0) {
            status = mmal_format_extradata_alloc(sys->input->format,
                    dec->fmt_in.i_extra);
            if (status == MMAL_SUCCESS) {
                memcpy(sys->input->format->extradata, dec->fmt_in.p_extra,
                        dec->fmt_in.i_extra);
                sys->input->format->extradata_size = dec->fmt_in.i_extra;
            } else {
                msg_Err(dec, "Failed to allocate extra format data on input port %s (status=%"PRIx32" %s)",
                        sys->input->name, status, mmal_status_to_string(status));
            }
        }
    }

    status = mmal_port_format_commit(sys->input);
    if (status != MMAL_SUCCESS) {
        msg_Err(dec, "Failed to commit format for input port %s (status=%"PRIx32" %s)",
                sys->input->name, status, mmal_status_to_string(status));
        ret = VLC_EGENERIC;
        goto out;
    }
    sys->input->buffer_size = sys->input->buffer_size_recommended;
    sys->input->buffer_num = sys->input->buffer_num_recommended;

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

    sys->output = sys->component->output[0];
    sys->output->userdata = (struct MMAL_PORT_USERDATA_T *)dec;

    if (sys->opaque) {
        extra_buffers.hdr.id = MMAL_PARAMETER_EXTRA_BUFFERS;
        extra_buffers.hdr.size = sizeof(MMAL_PARAMETER_UINT32_T);
        extra_buffers.value = NUM_EXTRA_BUFFERS;
        status = mmal_port_parameter_set(sys->output, &extra_buffers.hdr);
        if (status != MMAL_SUCCESS) {
            msg_Err(dec, "Failed to set MMAL_PARAMETER_EXTRA_BUFFERS on output port (status=%"PRIx32" %s)",
                    status, mmal_status_to_string(status));
            ret = VLC_EGENERIC;
            goto out;
        }

        msg_Dbg(dec, "Activate zero-copy for output port");
        MMAL_PARAMETER_BOOLEAN_T zero_copy = {
            { MMAL_PARAMETER_ZERO_COPY, sizeof(MMAL_PARAMETER_BOOLEAN_T) },
            1
        };

        status = mmal_port_parameter_set(sys->output, &zero_copy.hdr);
        if (status != MMAL_SUCCESS) {
           msg_Err(dec, "Failed to set zero copy on port %s (status=%"PRIx32" %s)",
                    sys->output->name, status, mmal_status_to_string(status));
           goto out;
        }
    }

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

    status = mmal_component_enable(sys->component);
    if (status != MMAL_SUCCESS) {
        msg_Err(dec, "Failed to enable component %s (status=%"PRIx32" %s)",
                sys->component->name, status, mmal_status_to_string(status));
        ret = VLC_EGENERIC;
        goto out;
    }

    sys->input_pool = mmal_pool_create(sys->input->buffer_num, 0);
    sys->decoded_pictures = mmal_queue_create();

    if (sys->opaque) {
        dec->fmt_out.i_codec = VLC_CODEC_MMAL_OPAQUE;
        dec->fmt_out.video.i_chroma = VLC_CODEC_MMAL_OPAQUE;
    } else {
        dec->fmt_out.i_codec = VLC_CODEC_I420;
        dec->fmt_out.video.i_chroma = VLC_CODEC_I420;
    }

    dec->fmt_out.i_cat = VIDEO_ES;
    dec->pf_decode_video = decode;

    vlc_mutex_init_recursive(&sys->mutex);
    vlc_sem_init(&sys->sem, 0);

out:
    if (ret != VLC_SUCCESS)
        CloseDecoder(dec);

    return ret;
}
Exemple #21
0
bool CMMALVideo::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options, MMALVideoPtr myself)
{
  if (g_advancedSettings.CanLogComponent(LOGVIDEO))
    CLog::Log(LOGDEBUG, "%s::%s usemmal:%d software:%d %dx%d", CLASSNAME, __func__, CSettings::Get().GetBool("videoplayer.usemmal"), hints.software, hints.width, hints.height);

  // we always qualify even if DVDFactoryCodec does this too.
  if (!CSettings::Get().GetBool("videoplayer.usemmal") || hints.software)
    return false;

  m_hints = hints;
  MMAL_STATUS_T status;
  MMAL_PARAMETER_BOOLEAN_T error_concealment;

  m_myself = myself;
  m_decoded_width  = hints.width;
  m_decoded_height = hints.height;

  // use aspect in stream if available
  if (m_hints.forced_aspect)
    m_aspect_ratio = m_hints.aspect;
  else
    m_aspect_ratio = 0.0;

  switch (hints.codec)
  {
    case AV_CODEC_ID_H264:
      // H.264
      m_codingType = MMAL_ENCODING_H264;
      m_pFormatName = "mmal-h264";
    break;
    case AV_CODEC_ID_H263:
    case AV_CODEC_ID_MPEG4:
      // MPEG-4, DivX 4/5 and Xvid compatible
      m_codingType = MMAL_ENCODING_MP4V;
      m_pFormatName = "mmal-mpeg4";
    break;
    case AV_CODEC_ID_MPEG1VIDEO:
    case AV_CODEC_ID_MPEG2VIDEO:
      // MPEG-2
      m_codingType = MMAL_ENCODING_MP2V;
      m_pFormatName = "mmal-mpeg2";
    break;
    case AV_CODEC_ID_VP6:
      // this form is encoded upside down
      // fall through
    case AV_CODEC_ID_VP6F:
    case AV_CODEC_ID_VP6A:
      // VP6
      m_codingType = MMAL_ENCODING_VP6;
      m_pFormatName = "mmal-vp6";
    break;
    case AV_CODEC_ID_VP8:
      // VP8
      m_codingType = MMAL_ENCODING_VP8;
      m_pFormatName = "mmal-vp8";
    break;
    case AV_CODEC_ID_THEORA:
      // theora
      m_codingType = MMAL_ENCODING_THEORA;
      m_pFormatName = "mmal-theora";
    break;
    case AV_CODEC_ID_MJPEG:
    case AV_CODEC_ID_MJPEGB:
      // mjpg
      m_codingType = MMAL_ENCODING_MJPEG;
      m_pFormatName = "mmal-mjpg";
    break;
    case AV_CODEC_ID_VC1:
    case AV_CODEC_ID_WMV3:
      // VC-1, WMV9
      m_codingType = MMAL_ENCODING_WVC1;
      m_pFormatName = "mmal-vc1";
      break;
    default:
      CLog::Log(LOGERROR, "%s::%s : Video codec unknown: %x", CLASSNAME, __func__, hints.codec);
      return false;
    break;
  }

  if ( (m_codingType == MMAL_ENCODING_MP2V && !g_RBP.GetCodecMpg2() ) ||
       (m_codingType == MMAL_ENCODING_WVC1 && !g_RBP.GetCodecWvc1() ) )
  {
    CLog::Log(LOGWARNING, "%s::%s Codec %s is not supported", CLASSNAME, __func__, m_pFormatName);
    return false;
  }

  // initialize mmal.
  status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, &m_dec);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to create MMAL decoder component %s (status=%x %s)", CLASSNAME, __func__, MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, status, mmal_status_to_string(status));
    return false;
  }

  m_dec->control->userdata = (struct MMAL_PORT_USERDATA_T *)this;
  status = mmal_port_enable(m_dec->control, dec_control_port_cb_static);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to enable decoder control port %s (status=%x %s)", CLASSNAME, __func__, MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, status, mmal_status_to_string(status));
    return false;
  }

  m_dec_input = m_dec->input[0];

  m_dec_input->format->type = MMAL_ES_TYPE_VIDEO;
  m_dec_input->format->encoding = m_codingType;
  if (m_hints.width && m_hints.height)
  {
    m_dec_input->format->es->video.crop.width = m_hints.width;
    m_dec_input->format->es->video.crop.height = m_hints.height;

    m_dec_input->format->es->video.width = ALIGN_UP(m_hints.width, 32);
    m_dec_input->format->es->video.height = ALIGN_UP(m_hints.height, 16);
  }
  m_dec_input->format->flags |= MMAL_ES_FORMAT_FLAG_FRAMED;

  error_concealment.hdr.id = MMAL_PARAMETER_VIDEO_DECODE_ERROR_CONCEALMENT;
  error_concealment.hdr.size = sizeof(MMAL_PARAMETER_BOOLEAN_T);
  error_concealment.enable = MMAL_FALSE;
  status = mmal_port_parameter_set(m_dec_input, &error_concealment.hdr);
  if (status != MMAL_SUCCESS)
    CLog::Log(LOGERROR, "%s::%s Failed to disable error concealment on %s (status=%x %s)", CLASSNAME, __func__, m_dec_input->name, status, mmal_status_to_string(status));

  status = mmal_port_parameter_set_uint32(m_dec_input, MMAL_PARAMETER_EXTRA_BUFFERS, NUM_BUFFERS);
  if (status != MMAL_SUCCESS)
    CLog::Log(LOGERROR, "%s::%s Failed to enable extra buffers on %s (status=%x %s)", CLASSNAME, __func__, m_dec_input->name, status, mmal_status_to_string(status));

  status = mmal_port_format_commit(m_dec_input);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to commit format for decoder input port %s (status=%x %s)", CLASSNAME, __func__, m_dec_input->name, status, mmal_status_to_string(status));
    return false;
  }
  m_dec_input->buffer_size = m_dec_input->buffer_size_recommended;
  m_dec_input->buffer_num = m_dec_input->buffer_num_recommended;

  m_dec_input->userdata = (struct MMAL_PORT_USERDATA_T *)this;
  status = mmal_port_enable(m_dec_input, dec_input_port_cb);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to enable decoder input port %s (status=%x %s)", CLASSNAME, __func__, m_dec_input->name, status, mmal_status_to_string(status));
    return false;
  }

  m_dec_output = m_dec->output[0];

  // set up initial decoded frame format - will likely change from this
  m_dec_output->format->encoding = MMAL_ENCODING_OPAQUE;
  mmal_format_copy(m_es_format, m_dec_output->format);

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

  m_dec_output->buffer_size = m_dec_output->buffer_size_min;
  m_dec_output->buffer_num = m_dec_output->buffer_num_recommended;
  m_dec_output->userdata = (struct MMAL_PORT_USERDATA_T *)this;
  status = mmal_port_enable(m_dec_output, dec_output_port_cb_static);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to enable decoder output port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }

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

  m_dec_input_pool = mmal_pool_create(m_dec_input->buffer_num, m_dec_input->buffer_size);
  if (!m_dec_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;
  }

  m_dec_output_pool = mmal_pool_create(m_dec_output->buffer_num, m_dec_output->buffer_size);
  if(!m_dec_output_pool)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to create pool for decode output port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }

  if (!SendCodecConfigData())
    return false;

  m_drop_state = false;
  m_startframe = false;

  return true;
}
Exemple #22
0
bool CMMALVideo::CreateDeinterlace(EINTERLACEMETHOD interlace_method)
{
  MMAL_STATUS_T status;

  if (g_advancedSettings.CanLogComponent(LOGVIDEO))
    CLog::Log(LOGDEBUG, "%s::%s method:%d", CLASSNAME, __func__, interlace_method);

  assert(!m_deint);
  assert(m_dec_output == m_dec->output[0]);

  status = mmal_port_disable(m_dec_output);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to disable decoder output port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }

  /* Create deinterlace filter */
  status = mmal_component_create("vc.ril.image_fx", &m_deint);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to create deinterlace component (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }
  MMAL_PARAMETER_IMAGEFX_PARAMETERS_T imfx_param = {{MMAL_PARAMETER_IMAGE_EFFECT_PARAMETERS, sizeof(imfx_param)},
        interlace_method == VS_INTERLACEMETHOD_MMAL_ADVANCED || interlace_method == VS_INTERLACEMETHOD_MMAL_ADVANCED_HALF ?
            MMAL_PARAM_IMAGEFX_DEINTERLACE_ADV : MMAL_PARAM_IMAGEFX_DEINTERLACE_FAST,
        3, {3, 0, interlace_method == VS_INTERLACEMETHOD_MMAL_ADVANCED_HALF || interlace_method == VS_INTERLACEMETHOD_MMAL_BOB_HALF }};
  status = mmal_port_parameter_set(m_deint->output[0], &imfx_param.hdr);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to set deinterlace parameters (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }

  MMAL_PORT_T *m_deint_input = m_deint->input[0];
  m_deint_input->userdata = (struct MMAL_PORT_USERDATA_T *)this;

  // Now connect the decoder output port to deinterlace input port
  status =  mmal_connection_create(&m_deint_connection, m_dec->output[0], m_deint->input[0], MMAL_CONNECTION_FLAG_TUNNELLING | MMAL_CONNECTION_FLAG_ALLOCATION_ON_INPUT);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to connect deinterlacer component %s (status=%x %s)", CLASSNAME, __func__, m_deint->name, status, mmal_status_to_string(status));
    return false;
  }

  status =  mmal_connection_enable(m_deint_connection);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to enable connection %s (status=%x %s)", CLASSNAME, __func__, m_deint->name, status, mmal_status_to_string(status));
    return false;
  }

  mmal_format_copy(m_deint->output[0]->format, m_es_format);
  status = mmal_port_format_commit(m_deint->output[0]);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to commit deint output format (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }

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

  m_deint->output[0]->buffer_size = m_deint->output[0]->buffer_size_min;
  m_deint->output[0]->buffer_num = m_deint->output[0]->buffer_num_recommended;
  m_deint->output[0]->userdata = (struct MMAL_PORT_USERDATA_T *)this;
  status = mmal_port_enable(m_deint->output[0], dec_output_port_cb_static);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to enable decoder output port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }

  m_dec_output = m_deint->output[0];
  m_interlace_method = interlace_method;

  return true;
}
Exemple #23
0
static int send_output_buffer(decoder_t *dec)
{
    decoder_sys_t *sys = dec->p_sys;
    MMAL_BUFFER_HEADER_T *buffer;
    picture_sys_t *p_sys;
    picture_t *picture;
    MMAL_STATUS_T status;
    unsigned buffer_size = 0;
    int ret = 0;

    if (!sys->output->is_enabled)
        return VLC_EGENERIC;

    /* If local output pool is allocated, use it - this is only the case for
     * non-opaque modes */
    if (sys->output_pool) {
        buffer = mmal_queue_get(sys->output_pool->queue);
        if (!buffer) {
            msg_Warn(dec, "Failed to get new buffer");
            return VLC_EGENERIC;
        }
    }

    picture = decoder_NewPicture(dec);
    if (!picture) {
        msg_Warn(dec, "Failed to get new picture");
        ret = -1;
        goto err;
    }

    p_sys = picture->p_sys;
    for (int i = 0; i < picture->i_planes; i++)
        buffer_size += picture->p[i].i_lines * picture->p[i].i_pitch;

    if (sys->output_pool) {
        mmal_buffer_header_reset(buffer);
        buffer->user_data = picture;
        buffer->alloc_size = sys->output->buffer_size;
        if (buffer_size < sys->output->buffer_size) {
            msg_Err(dec, "Retrieved picture with too small data block (%d < %d)",
                    buffer_size, sys->output->buffer_size);
            ret = VLC_EGENERIC;
            goto err;
        }

        if (!sys->opaque)
            buffer->data = picture->p[0].p_pixels;
    } else {
        buffer = p_sys->buffer;
        if (!buffer) {
            msg_Warn(dec, "Picture has no buffer attached");
            picture_Release(picture);
            return VLC_EGENERIC;
        }
        buffer->data = p_sys->buffer->data;
    }
    buffer->cmd = 0;

    status = mmal_port_send_buffer(sys->output, buffer);
    if (status != MMAL_SUCCESS) {
        msg_Err(dec, "Failed to send buffer to output port (status=%"PRIx32" %s)",
                status, mmal_status_to_string(status));
        ret = -1;
        goto err;
    }
    atomic_fetch_add(&sys->output_in_transit, 1);

    return ret;

err:
    if (picture)
        picture_Release(picture);
    if (sys->output_pool && buffer) {
        buffer->data = NULL;
        mmal_buffer_header_release(buffer);
    }
    return ret;
}
Exemple #24
0
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;
}
Exemple #25
0
void CMMALVideo::Recycle(MMAL_BUFFER_HEADER_T *buffer)
{
  if (g_advancedSettings.CanLogComponent(LOGVIDEO))
    CLog::Log(LOGDEBUG, "%s::%s %p", CLASSNAME, __func__, buffer);

  MMAL_STATUS_T status;
  mmal_buffer_header_reset(buffer);
  buffer->cmd = 0;
  if (g_advancedSettings.CanLogComponent(LOGVIDEO))
    CLog::Log(LOGDEBUG, "%s::%s Send buffer %p from pool to decoder output port %p dts_queue(%d) ready_queue(%d) busy_queue(%d)", CLASSNAME, __func__, buffer, m_dec_output,
      m_dts_queue.size(), m_output_ready.size(), m_output_busy);
  status = mmal_port_send_buffer(m_dec_output, buffer);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s - Failed send buffer to decoder output port (status=0%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return;
  }
}
Exemple #26
0
bool CMMALVideo::DestroyDeinterlace()
{
  MMAL_STATUS_T status;

  if (g_advancedSettings.CanLogComponent(LOGVIDEO))
    CLog::Log(LOGDEBUG, "%s::%s", CLASSNAME, __func__);

  assert(m_deint);
  assert(m_dec_output == m_deint->output[0]);

  status = mmal_port_disable(m_dec_output);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to disable decoder output port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }

  status = mmal_connection_destroy(m_deint_connection);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to destroy deinterlace connection (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }
  m_deint_connection = NULL;

  status = mmal_component_disable(m_deint);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to disable deinterlace component (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }

  status = mmal_component_destroy(m_deint);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to destroy deinterlace component (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }
  m_deint = NULL;

  m_dec->output[0]->buffer_size = m_dec->output[0]->buffer_size_min;
  m_dec->output[0]->buffer_num = m_dec->output[0]->buffer_num_recommended;
  m_dec->output[0]->userdata = (struct MMAL_PORT_USERDATA_T *)this;
  status = mmal_port_enable(m_dec->output[0], dec_output_port_cb_static);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed to enable decoder output port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }

  m_dec_output = m_dec->output[0];
  m_interlace_method = VS_INTERLACEMETHOD_NONE;
  return true;
}
Exemple #27
0
static int do_mmal_stats(int argc, const char **argv)
{
   unsigned comp_index = 0;
   MMAL_BOOL_T more_ports = MMAL_TRUE, reset = MMAL_FALSE;
   unsigned port_index = 0;
   MMAL_PORT_TYPE_T type = MMAL_PORT_TYPE_INPUT;

   if (argc >= 3)
      reset = strcasecmp(argv[2], "reset") == 0;

   printf("component\t\tport\t\tbuffers\t\tfps\tdelay\n");
   while (more_ports)
   {
      int dir;
      const char *dirnames[] = {"rx","tx"};
      MMAL_STATS_RESULT_T result;

      for (dir = MMAL_CORE_STATS_RX; dir <= MMAL_CORE_STATS_TX; dir++)
      {
         double framerate;
         MMAL_CORE_STATISTICS_T stats;
         char name[32];
         MMAL_STATUS_T status = mmal_vc_get_core_stats(&stats,
                                                      &result,
                                                      name, sizeof(name),
                                                      type,
                                                      comp_index,
                                                      port_index,
                                                      dir,
                                                      reset);
         if (status != MMAL_SUCCESS)
         {
            fprintf(stderr, "could not get core stats: %s\n",
                  mmal_status_to_string(status));
            exit(1);
         }

         if (result == MMAL_STATS_FOUND)
         {
            if (stats.first_buffer_time == stats.last_buffer_time)
               framerate = 0;
            else
               framerate = 1.0e6*(1+stats.buffer_count)/(stats.last_buffer_time-stats.first_buffer_time);

            printf("%-20s\t%d [%s]%2s\t%-10d\t%4.1f\t%d\n",
                  name, port_index,
                  type == MMAL_PORT_TYPE_INPUT ? "in " : "out",
                  dirnames[dir],
                  stats.buffer_count, framerate, stats.max_delay);

         }
      }

      switch (result)
      {
      case MMAL_STATS_FOUND:
         port_index++;
         break;

      case MMAL_STATS_COMPONENT_NOT_FOUND:
         more_ports = MMAL_FALSE;
         break;

      case MMAL_STATS_PORT_NOT_FOUND:
         port_index = 0;
         if (type == MMAL_PORT_TYPE_INPUT)
         {
            type = MMAL_PORT_TYPE_OUTPUT;
         }
         else
         {
            type = MMAL_PORT_TYPE_INPUT;
            comp_index++;
         }
         break;
      default:
         fprintf(stderr, "bad result from query: %d\n", result);
         vcos_assert(0);
         exit(1);
      }
   }
   return 0;
}
Exemple #28
0
static picture_t *decode(decoder_t *dec, block_t **pblock)
{
    decoder_sys_t *sys = dec->p_sys;
    block_t *block;
    MMAL_BUFFER_HEADER_T *buffer;
    bool need_flush = false;
    uint32_t len;
    uint32_t flags = 0;
    MMAL_STATUS_T status;
    picture_t *ret = NULL;

    /*
     * Configure output port if necessary
     */
    if (sys->output_format) {
        if (change_output_format(dec) < 0)
            msg_Err(dec, "Failed to change output port format");
    }

    if (!pblock)
        goto out;

    block = *pblock;

    /*
     * Check whether full flush is required
     */
    if (block && block->i_flags & BLOCK_FLAG_DISCONTINUITY) {
        flush_decoder(dec);
        block_Release(*pblock);
        return NULL;
    }

    /*
     * Send output buffers
     */
    if (atomic_load(&sys->started)) {
        buffer = mmal_queue_get(sys->decoded_pictures);
        if (buffer) {
            ret = (picture_t *)buffer->user_data;
            ret->date = buffer->pts;
            ret->b_progressive = sys->b_progressive;
            ret->b_top_field_first = sys->b_top_field_first;

            if (sys->output_pool) {
                buffer->data = NULL;
                mmal_buffer_header_reset(buffer);
                mmal_buffer_header_release(buffer);
            }
        }

        fill_output_port(dec);
    }

    if (ret)
        goto out;

    /*
     * Process input
     */
    if (!block)
        goto out;

    *pblock = NULL;

    if (block->i_flags & BLOCK_FLAG_CORRUPTED)
        flags |= MMAL_BUFFER_HEADER_FLAG_CORRUPTED;

    vlc_mutex_lock(&sys->mutex);
    while (block->i_buffer > 0) {
        buffer = mmal_queue_timedwait(sys->input_pool->queue, 2);
        if (!buffer) {
            msg_Err(dec, "Failed to retrieve buffer header for input data");
            need_flush = true;
            break;
        }
        mmal_buffer_header_reset(buffer);
        buffer->cmd = 0;
        buffer->pts = block->i_pts != 0 ? block->i_pts : block->i_dts;
        buffer->dts = block->i_dts;
        buffer->alloc_size = sys->input->buffer_size;

        len = block->i_buffer;
        if (len > buffer->alloc_size)
            len = buffer->alloc_size;

        buffer->data = block->p_buffer;
        block->p_buffer += len;
        block->i_buffer -= len;
        buffer->length = len;
        if (block->i_buffer == 0)
            buffer->user_data = block;
        buffer->flags = flags;

        status = mmal_port_send_buffer(sys->input, buffer);
        if (status != MMAL_SUCCESS) {
            msg_Err(dec, "Failed to send buffer to input port (status=%"PRIx32" %s)",
                    status, mmal_status_to_string(status));
            break;
        }
        atomic_fetch_add(&sys->input_in_transit, 1);
    }
    vlc_mutex_unlock(&sys->mutex);

out:
    if (need_flush)
        flush_decoder(dec);

    return ret;
}
Exemple #29
0
int CMMALVideo::Decode(uint8_t* pData, int iSize, double dts, double pts)
{
  //if (g_advancedSettings.CanLogComponent(LOGVIDEO))
  //  CLog::Log(LOGDEBUG, "%s::%s - %-8p %-6d dts:%.3f pts:%.3f dts_queue(%d) ready_queue(%d) busy_queue(%d)",
  //    CLASSNAME, __func__, pData, iSize, dts == DVD_NOPTS_VALUE ? 0.0 : dts*1e-6, pts == DVD_NOPTS_VALUE ? 0.0 : pts*1e-6, m_dts_queue.size(), m_output_ready.size(), m_output_busy);

  unsigned int demuxer_bytes = 0;
  uint8_t *demuxer_content = NULL;
  MMAL_BUFFER_HEADER_T *buffer;
  MMAL_STATUS_T status;

  while (buffer = mmal_queue_get(m_dec_output_pool->queue), buffer)
    Recycle(buffer);
  // we need to queue then de-queue the demux packet, seems silly but
  // mmal might not have an input buffer available when we are called
  // and we must store the demuxer packet and try again later.
  // try to send any/all demux packets to mmal decoder.
  unsigned space = mmal_queue_length(m_dec_input_pool->queue) * m_dec_input->buffer_size;
  if (pData && m_demux_queue.empty() && space >= (unsigned int)iSize)
  {
    demuxer_bytes = iSize;
    demuxer_content = pData;
  }
  else if (pData && iSize)
  {
    mmal_demux_packet demux_packet;
    demux_packet.dts = dts;
    demux_packet.pts = pts;
    demux_packet.size = iSize;
    demux_packet.buff = new uint8_t[iSize];
    memcpy(demux_packet.buff, pData, iSize);
    m_demux_queue_length += demux_packet.size;
    m_demux_queue.push(demux_packet);
  }

  uint8_t *buffer_to_free = NULL;

  while (1)
  {
     while (buffer = mmal_queue_get(m_dec_output_pool->queue), buffer)
       Recycle(buffer);

     space = mmal_queue_length(m_dec_input_pool->queue) * m_dec_input->buffer_size;
     if (!demuxer_bytes && !m_demux_queue.empty())
     {
       mmal_demux_packet &demux_packet = m_demux_queue.front();
       if (space >= (unsigned int)demux_packet.size)
       {
         // need to lock here to retrieve an input buffer and pop the queue
         m_demux_queue_length -= demux_packet.size;
         m_demux_queue.pop();
         demuxer_bytes = (unsigned int)demux_packet.size;
         demuxer_content = demux_packet.buff;
         buffer_to_free = demux_packet.buff;
         dts = demux_packet.dts;
         pts = demux_packet.pts;
       }
     }
     if (demuxer_content)
     {
       // 500ms timeout
       buffer = mmal_queue_timedwait(m_dec_input_pool->queue, 500);
       if (!buffer)
       {
         CLog::Log(LOGERROR, "%s::%s - mmal_queue_get failed", CLASSNAME, __func__);
         return VC_ERROR;
       }

       mmal_buffer_header_reset(buffer);
       buffer->cmd = 0;
       if (m_startframe && pts == DVD_NOPTS_VALUE)
         pts = 0;
       buffer->pts = pts == DVD_NOPTS_VALUE ? MMAL_TIME_UNKNOWN : pts;
       buffer->dts = dts == DVD_NOPTS_VALUE ? MMAL_TIME_UNKNOWN : dts;
       buffer->length = demuxer_bytes > buffer->alloc_size ? buffer->alloc_size : demuxer_bytes;
       buffer->user_data = (void *)m_decode_frame_number;
       // set a flag so we can identify primary frames from generated frames (deinterlace)
       buffer->flags = MMAL_BUFFER_HEADER_FLAG_USER0;

       // Request decode only (maintain ref frames, but don't return a picture)
       if (m_drop_state)
         buffer->flags |= MMAL_BUFFER_HEADER_FLAG_DECODEONLY;

       memcpy(buffer->data, demuxer_content, buffer->length);
       demuxer_bytes   -= buffer->length;
       demuxer_content += buffer->length;

       if (demuxer_bytes == 0)
         buffer->flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_END;

       if (g_advancedSettings.CanLogComponent(LOGVIDEO))
         CLog::Log(LOGDEBUG, "%s::%s - %-8p %-6d/%-6d dts:%.3f pts:%.3f flags:%x dts_queue(%d) ready_queue(%d) busy_queue(%d) demux_queue(%d) space(%d)",
            CLASSNAME, __func__, buffer, buffer->length, demuxer_bytes, dts == DVD_NOPTS_VALUE ? 0.0 : dts*1e-6, pts == DVD_NOPTS_VALUE ? 0.0 : pts*1e-6, buffer->flags, m_dts_queue.size(), m_output_ready.size(), m_output_busy, m_demux_queue_length, mmal_queue_length(m_dec_input_pool->queue) * m_dec_input->buffer_size);
       assert((int)buffer->length > 0);
       status = mmal_port_send_buffer(m_dec_input, buffer);
       if (status != MMAL_SUCCESS)
       {
         CLog::Log(LOGERROR, "%s::%s Failed send buffer to decoder input port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
         return VC_ERROR;
       }

       if (demuxer_bytes == 0)
       {
         m_decode_frame_number++;
         m_startframe = true;
         if (m_drop_state)
         {
           m_droppedPics += m_deint ? 2:1;
         }
         else
         {
           // only push if we are successful with feeding mmal
           pthread_mutex_lock(&m_output_mutex);
           m_dts_queue.push(dts);
           assert(m_dts_queue.size() < 5000);
           pthread_mutex_unlock(&m_output_mutex);
         }
         if (m_changed_count_dec != m_changed_count)
         {
           if (g_advancedSettings.CanLogComponent(LOGVIDEO))
             CLog::Log(LOGDEBUG, "%s::%s format changed frame:%d(%d)", CLASSNAME, __func__, m_changed_count_dec, m_changed_count);
           m_changed_count_dec = m_changed_count;
           if (!change_dec_output_format())
           {
             CLog::Log(LOGERROR, "%s::%s - change_dec_output_format() failed", CLASSNAME, __func__);
             return VC_ERROR;
           }
         }
         EDEINTERLACEMODE deinterlace_request = CMediaSettings::Get().GetCurrentVideoSettings().m_DeinterlaceMode;
         EINTERLACEMETHOD interlace_method = g_renderManager.AutoInterlaceMethod(CMediaSettings::Get().GetCurrentVideoSettings().m_InterlaceMethod);

         bool deinterlace = m_interlace_mode != MMAL_InterlaceProgressive;

         if (deinterlace_request == VS_DEINTERLACEMODE_OFF)
           deinterlace = false;
         else if (deinterlace_request == VS_DEINTERLACEMODE_FORCE)
           deinterlace = true;

         if (((deinterlace && interlace_method != m_interlace_method) || !deinterlace) && m_deint)
           DestroyDeinterlace();
         if (deinterlace && !m_deint)
           CreateDeinterlace(interlace_method);

         if (buffer_to_free)
         {
           delete [] buffer_to_free;
           buffer_to_free = NULL;
           demuxer_content = NULL;
           continue;
         }
         while (buffer = mmal_queue_get(m_dec_output_pool->queue), buffer)
           Recycle(buffer);
       }
    }
    if (!demuxer_bytes)
      break;
  }
  int ret = 0;
  if (!m_output_ready.empty())
  {
    if (g_advancedSettings.CanLogComponent(LOGVIDEO))
      CLog::Log(LOGDEBUG, "%s::%s - got space for output: demux_queue(%d) space(%d)", CLASSNAME, __func__, m_demux_queue_length, mmal_queue_length(m_dec_input_pool->queue) * m_dec_input->buffer_size);
    ret |= VC_PICTURE;
  }
  if (mmal_queue_length(m_dec_input_pool->queue) > 0 && !m_demux_queue_length)
  {
    if (g_advancedSettings.CanLogComponent(LOGVIDEO))
      CLog::Log(LOGDEBUG, "%s::%s -  got output picture:%d", CLASSNAME, __func__, m_output_ready.size());
    ret |= VC_BUFFER;
  }
  if (!ret)
  {
    if (g_advancedSettings.CanLogComponent(LOGVIDEO))
      CLog::Log(LOGDEBUG, "%s::%s - Nothing to do: dts_queue(%d) ready_queue(%d) busy_queue(%d) demux_queue(%d) space(%d)",
        CLASSNAME, __func__, m_dts_queue.size(), m_output_ready.size(), m_output_busy, m_demux_queue_length, mmal_queue_length(m_dec_input_pool->queue) * m_dec_input->buffer_size);
    Sleep(10); // otherwise we busy spin
  }
  return ret;
}
Exemple #30
0
bool CMMALVideo::SendCodecConfigData()
{
  MMAL_STATUS_T status;
  if (!m_dec_input_pool)
    return true;
  // send code config data
  MMAL_BUFFER_HEADER_T *buffer = mmal_queue_timedwait(m_dec_input_pool->queue, 500);
  if (!buffer)
  {
    CLog::Log(LOGERROR, "%s::%s - mmal_queue_get failed", CLASSNAME, __func__);
    return false;
  }

  mmal_buffer_header_reset(buffer);
  buffer->cmd = 0;
  buffer->length = std::min(m_hints.extrasize, buffer->alloc_size);
  memcpy(buffer->data, m_hints.extradata, buffer->length);
  buffer->flags |= MMAL_BUFFER_HEADER_FLAG_FRAME_END | MMAL_BUFFER_HEADER_FLAG_CONFIG;
  if (g_advancedSettings.CanLogComponent(LOGVIDEO))
    CLog::Log(LOGDEBUG, "%s::%s - %-8p %-6d flags:%x", CLASSNAME, __func__, buffer, buffer->length, buffer->flags);
  status = mmal_port_send_buffer(m_dec_input, buffer);
  if (status != MMAL_SUCCESS)
  {
    CLog::Log(LOGERROR, "%s::%s Failed send buffer to decoder input port (status=%x %s)", CLASSNAME, __func__, status, mmal_status_to_string(status));
    return false;
  }
  return true;
}