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, ¶m.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, ¶m.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, ¶m2.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, ¶m3.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, ¶m.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, ¶m.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, ¶m.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; }
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; }