static KHRN_IMAGE_FORMAT_T ximage_to_image_format(int bits_per_pixel, unsigned long red_mask, unsigned long green_mask, unsigned long blue_mask)
{
   if (bits_per_pixel == 16 /*&& red_mask == 0xf800 && green_mask == 0x07e0 && blue_mask == 0x001f*/)
      return RGB_565_RSO;
   //else if (bits_per_pixel == 24 && red_mask == 0xff0000 && green_mask == 0x00ff00 && blue_mask == 0x0000ff)
   //   return RGB_888_RSO;
   else if (bits_per_pixel == 24 && red_mask == 0x0000ff && green_mask == 0x00ff00 && blue_mask == 0xff0000)
      return BGR_888_RSO;
   else if (bits_per_pixel == 32 /*&& red_mask == 0x0000ff && green_mask == 0x00ff00 && blue_mask == 0xff0000*/)
      return ABGR_8888_RSO; //meego uses alpha channel
   else if (bits_per_pixel == 32 && red_mask == 0xff0000 && green_mask == 0x00ff00 && blue_mask == 0x0000ff)
      return ARGB_8888_RSO;
   else
   {
      vcos_log_warn("platform_get_pixmap_info unknown image format\n");
      return IMAGE_FORMAT_INVALID;
   }
}
/**
 * Reset the encoder component, set up its ports
 *
 * @param state Pointer to state control struct
 *
 * @return MMAL_SUCCESS if all OK, something else otherwise
 *
 */
MMAL_STATUS_T reset_encoder_component(RASPIVID_STATE *state)
{
    MMAL_COMPONENT_T *encoder = 0;
    MMAL_PORT_T *encoder_input = NULL, *encoder_output = NULL;
    MMAL_STATUS_T status;
    MMAL_POOL_T *pool;


    // Get the encoder component
    if( state->encoder_component == NULL ) {
        vcos_log_error("Unable to get video encoder component");
        goto error;
    }
    else {
        encoder = state->encoder_component;
    }

#ifdef __NOT_REQURED__
    if (!encoder->input_num || !encoder->output_num)
    {
        status = MMAL_ENOSYS;
        vcos_log_error("Video encoder doesn't have input/output ports");
        goto error;
    }

    encoder_input = encoder->input[0];
    encoder_output = encoder->output[0];

    // We want same format on input and output
    mmal_format_copy(encoder_output->format, encoder_input->format);

    // Only supporting H264 at the moment
    encoder_output->format->encoding = state->encoding;

    encoder_output->format->bitrate = state->bitrate;

    if (state->encoding == MMAL_ENCODING_H264)
        encoder_output->buffer_size = encoder_output->buffer_size_recommended;
    else
        encoder_output->buffer_size = 256<<10;


    if (encoder_output->buffer_size < encoder_output->buffer_size_min)
        encoder_output->buffer_size = encoder_output->buffer_size_min;

    encoder_output->buffer_num = encoder_output->buffer_num_recommended;

    if (encoder_output->buffer_num < encoder_output->buffer_num_min)
        encoder_output->buffer_num = encoder_output->buffer_num_min;

    // We need to set the frame rate on output to 0, to ensure it gets
    // updated correctly from the input framerate when port connected
    encoder_output->format->es->video.frame_rate.num = 0;
    encoder_output->format->es->video.frame_rate.den = 1;

    // Commit the port changes to the output port
    status = mmal_port_format_commit(encoder_output);

    if (status != MMAL_SUCCESS)
    {
        vcos_log_error("Unable to set format on video encoder output port");
        goto error;
    }

    if (state->encoding == MMAL_ENCODING_H264 &&
            state->intraperiod != -1)
    {
        MMAL_PARAMETER_UINT32_T param = {{ MMAL_PARAMETER_INTRAPERIOD, sizeof(param)}, state->intraperiod};
        status = mmal_port_parameter_set(encoder_output, &param.hdr);
        if (status != MMAL_SUCCESS)
        {
            vcos_log_error("Unable to set intraperiod");
            goto error;
        }
    }

    if (state->encoding == MMAL_ENCODING_H264 && state->quantisationParameter)
    {

        MMAL_PARAMETER_UINT32_T param =
        {{ MMAL_PARAMETER_VIDEO_ENCODE_INITIAL_QUANT, sizeof(param)}, state->quantisationInitialParameter};
        status = mmal_port_parameter_set(encoder_output, &param.hdr);
        if (status != MMAL_SUCCESS)
        {
            vcos_log_error("Unable to set initial QP");
            goto error;
        }

        MMAL_PARAMETER_UINT32_T param2 =
        {{ MMAL_PARAMETER_VIDEO_ENCODE_MIN_QUANT, sizeof(param)}, state->quantisationMinParameter};
        status = mmal_port_parameter_set(encoder_output, &param2.hdr);
        if (status != MMAL_SUCCESS)
        {
            vcos_log_error("Unable to set min QP");
            goto error;
        }

        MMAL_PARAMETER_UINT32_T param3 =
        {{ MMAL_PARAMETER_VIDEO_ENCODE_MAX_QUANT, sizeof(param)}, state->quantisationMaxParameter};
        status = mmal_port_parameter_set(encoder_output, &param3.hdr);
        if (status != MMAL_SUCCESS)
        {
            vcos_log_error("Unable to set max QP");
            goto error;
        }


    }

    if (state->encoding == MMAL_ENCODING_H264)
    {
        MMAL_PARAMETER_VIDEO_PROFILE_T  param;
        param.hdr.id = MMAL_PARAMETER_PROFILE;
        param.hdr.size = sizeof(param);

        param.profile[0].profile = state->profile;
        param.profile[0].level = MMAL_VIDEO_LEVEL_H264_4; // This is the only value supported

        status = mmal_port_parameter_set(encoder_output, &param.hdr);
        if (status != MMAL_SUCCESS)
        {
            vcos_log_error("Unable to set H264 profile");
            goto error;
        }
    }

    if (mmal_port_parameter_set_boolean(encoder_input,
                                        MMAL_PARAMETER_VIDEO_IMMUTABLE_INPUT, state->immutableInput) != MMAL_SUCCESS)
    {
        vcos_log_error("Unable to set immutable input flag");
        // Continue rather than abort..
    }

    //set INLINE HEADER flag to generate SPS and PPS for every IDR if requested
    if (mmal_port_parameter_set_boolean(encoder_output,
                                        MMAL_PARAMETER_VIDEO_ENCODE_INLINE_HEADER, state->bInlineHeaders) != MMAL_SUCCESS)
    {
        vcos_log_error("failed to set INLINE HEADER FLAG parameters");
        // Continue rather than abort..
    }

    //set Encode SPS Timing
    if (mmal_port_parameter_set_boolean(encoder_output,
                                        MMAL_PARAMETER_VIDEO_ENCODE_SPS_TIMING, MMAL_TRUE) != MMAL_SUCCESS)
    {
        vcos_log_error("failed to set SPS TIMING HEADER FLAG parameters");
        // Continue rather than abort..
    }

    // set Minimise Fragmentation
    if (mmal_port_parameter_set_boolean(encoder_output,
                                        MMAL_PARAMETER_MINIMISE_FRAGMENTATION, MMAL_FALSE) != MMAL_SUCCESS)
    {
        vcos_log_error("failed to set SPS TIMING HEADER FLAG parameters");
        // Continue rather than abort..
    }

    // Adaptive intra refresh settings
    if (state->encoding == MMAL_ENCODING_H264 &&
            state->intra_refresh_type != -1)
    {
        MMAL_PARAMETER_VIDEO_INTRA_REFRESH_T  param;
        param.hdr.id = MMAL_PARAMETER_VIDEO_INTRA_REFRESH;
        param.hdr.size = sizeof(param);

        // Get first so we don't overwrite anything unexpectedly
        status = mmal_port_parameter_get(encoder_output, &param.hdr);
        if (status != MMAL_SUCCESS)
        {
            vcos_log_warn("Unable to get existing H264 intra-refresh values. Please update your firmware");
            // Set some defaults, don't just pass random stack data
            param.air_mbs = param.air_ref = param.cir_mbs = param.pir_mbs = 0;
        }

        param.refresh_mode = state->intra_refresh_type;

        //if (state->intra_refresh_type == MMAL_VIDEO_INTRA_REFRESH_CYCLIC_MROWS)
        //   param.cir_mbs = 10;

        status = mmal_port_parameter_set(encoder_output, &param.hdr);
        if (status != MMAL_SUCCESS)
        {
            vcos_log_error("Unable to set H264 intra-refresh values");
            goto error;
        }
    }
#endif	/* NOT_REQUIRED */

    //  Enable component
    status = mmal_component_enable(encoder);

    if (status != MMAL_SUCCESS)
    {
        vcos_log_error("Unable to enable video encoder component");
        goto error;
    }

#ifdef __NOT_REQURED__
    /* Create pool of buffer headers for the output port to consume */
    pool = mmal_port_pool_create(encoder_output, encoder_output->buffer_num, encoder_output->buffer_size);

    if (!pool)
    {
        vcos_log_error("Failed to create buffer header pool for encoder output port %s", encoder_output->name);
    }

    state->encoder_pool = pool;
    state->encoder_component = encoder;
#endif	/* NOT_REQUIRED */

    return status;

error:
    if (encoder)
        mmal_component_destroy(encoder);

    state->encoder_component = NULL;

    return status;
}
예제 #3
0
void *vcos_generic_blockpool_alloc(VCOS_BLOCKPOOL_T *pool)
{
   VCOS_UNSIGNED i;
   void* ret = NULL;
   VCOS_BLOCKPOOL_SUBPOOL_T *subpool = NULL;

   ASSERT_POOL(pool);
   vcos_mutex_lock(&pool->mutex);

   /* Starting with the main pool try and find a free block */
   for (i = 0; i < pool->num_subpools; ++i)
   {
      if (pool->subpools[i].start && pool->subpools[i].available_blocks > 0)
      {
         subpool = &pool->subpools[i];
         break; /* Found a subpool with free blocks */
      }
   }

   if (! subpool)
   {
      /* All current subpools are full, try to allocate a new one */
      for (i = 1; i < pool->num_subpools; ++i)
      {
         if (! pool->subpools[i].start)
         {
            VCOS_BLOCKPOOL_SUBPOOL_T *s = &pool->subpools[i];
            size_t size = VCOS_BLOCKPOOL_SIZE(pool->num_extension_blocks,
                  pool->block_data_size, pool->align);
            void *mem = vcos_malloc(size, pool->name);
            if (mem)
            {
               vcos_log_trace("%s: Allocated subpool %d", VCOS_FUNCTION, i);
               vcos_generic_blockpool_subpool_init(pool, s, mem, size,
                     pool->num_extension_blocks,
                     pool->align,
                     VCOS_BLOCKPOOL_SUBPOOL_FLAG_OWNS_MEM |
                     VCOS_BLOCKPOOL_SUBPOOL_FLAG_EXTENSION);
               subpool = s;
               break; /* Created a subpool */
            }
            else
            {
               vcos_log_warn("%s: Failed to allocate subpool", VCOS_FUNCTION);
            }
         }
      }
   }

   if (subpool)
   {
      /* Remove from free list */
      VCOS_BLOCKPOOL_HEADER_T* nb = subpool->free_list;

      vcos_assert(subpool->free_list);
      subpool->free_list = nb->owner.next;

      /* Owner is pool so free can be called without passing pool
       * as a parameter */
      nb->owner.subpool = subpool;

      ret = nb + 1; /* Return pointer to block data */
      --(subpool->available_blocks);
   }
   vcos_mutex_unlock(&pool->mutex);
   VCOS_BLOCKPOOL_DEBUG_LOG("pool %p subpool %p ret %p", pool, subpool, ret);

   if (ret)
   {
      vcos_assert(ret > subpool->start);
      vcos_assert(ret < subpool->end);
   }
   return ret;
}