static gboolean fill_sequence (GstVaapiEncoderVP8 * encoder, GstVaapiEncSequence * sequence) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); VAEncSequenceParameterBufferVP8 *const seq_param = sequence->param; memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferVP8)); seq_param->frame_width = GST_VAAPI_ENCODER_WIDTH (encoder); seq_param->frame_height = GST_VAAPI_ENCODER_HEIGHT (encoder); if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR || GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_VBR) seq_param->bits_per_second = base_encoder->bitrate * 1000; seq_param->intra_period = base_encoder->keyframe_period; return TRUE; }
static gboolean set_misc_parameters (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPicture * picture) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); GstVaapiEncMiscParam *misc = NULL; VAEncMiscParameterHRD *hrd; VAEncMiscParameterRateControl *rate_control; /* add hrd */ misc = GST_VAAPI_ENC_MISC_PARAM_NEW (HRD, encoder); g_assert (misc); if (!misc) return FALSE; gst_vaapi_enc_picture_add_misc_param (picture, misc); hrd = misc->data; if (base_encoder->bitrate > 0) { hrd->initial_buffer_fullness = base_encoder->bitrate * 1000 * 4; hrd->buffer_size = base_encoder->bitrate * 1000 * 8; } else { hrd->initial_buffer_fullness = 0; hrd->buffer_size = 0; } gst_vaapi_codec_object_replace (&misc, NULL); /* add ratecontrol */ if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CBR) { misc = GST_VAAPI_ENC_MISC_PARAM_NEW (RateControl, encoder); g_assert (misc); if (!misc) return FALSE; gst_vaapi_enc_picture_add_misc_param (picture, misc); rate_control = misc->data; memset (rate_control, 0, sizeof (VAEncMiscParameterRateControl)); if (base_encoder->bitrate) rate_control->bits_per_second = base_encoder->bitrate * 1000; else rate_control->bits_per_second = 0; rate_control->target_percentage = 70; rate_control->window_size = 500; rate_control->initial_qp = encoder->cqp; rate_control->min_qp = 0; rate_control->basic_unit_size = 0; gst_vaapi_codec_object_replace (&misc, NULL); } return TRUE; }
/* Updates video context */ static gboolean set_context_info (GstVaapiEncoder * encoder) { GstVaapiContextInfo *const cip = &encoder->context_info; GstVaapiConfigInfoEncoder *const config = &cip->config.encoder; const GstVideoFormat format = GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder)); const GstVaapiEncoderClassData *const cdata = GST_VAAPI_ENCODER_GET_CLASS (encoder)->class_data; cip->usage = GST_VAAPI_CONTEXT_USAGE_ENCODE; cip->profile = encoder->profile; cip->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; if (cdata->codec != GST_VAAPI_CODEC_JPEG) cip->entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE; else cip->entrypoint = GST_VAAPI_ENTRYPOINT_PICTURE_ENCODE; cip->chroma_type = gst_vaapi_video_format_get_chroma_type (format); cip->width = GST_VAAPI_ENCODER_WIDTH (encoder); cip->height = GST_VAAPI_ENCODER_HEIGHT (encoder); cip->ref_frames = encoder->num_ref_frames; if (!cip->chroma_type && (format != GST_VIDEO_FORMAT_ENCODED)) goto error_unsupported_format; if (cip->chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420 && format != GST_VIDEO_FORMAT_ENCODED) { GST_ERROR ("We are only supporting YUV:4:2:0 for encoding," "please try to use vaapipostproc to convert the input format!"); goto error_unsupported_format; } memset (config, 0, sizeof (*config)); config->rc_mode = GST_VAAPI_ENCODER_RATE_CONTROL (encoder); config->packed_headers = get_packed_headers (encoder); return TRUE; /* ERRORS */ error_unsupported_format: { GST_ERROR ("failed to determine chroma type for format %s", gst_vaapi_video_format_to_string (format)); return FALSE; } }
static gboolean ensure_bitrate (GstVaapiEncoderMpeg2 * encoder) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); /* Default compression: 64 bits per macroblock */ switch (GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) { case GST_VAAPI_RATECONTROL_CBR: if (!base_encoder->bitrate) base_encoder->bitrate = gst_util_uint64_scale (GST_VAAPI_ENCODER_WIDTH (encoder) * GST_VAAPI_ENCODER_HEIGHT (encoder), GST_VAAPI_ENCODER_FPS_N (encoder), GST_VAAPI_ENCODER_FPS_D (encoder)) / 4 / 1000; break; default: base_encoder->bitrate = 0; break; } return TRUE; }
static gboolean ensure_control_rate_params (GstVaapiEncoderVP8 * encoder) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP) return TRUE; /* RateControl params */ GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).initial_qp = encoder->yac_qi; GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).min_qp = 1; /* *INDENT-OFF* */ /* HRD params */ GST_VAAPI_ENCODER_VA_HRD (encoder) = (VAEncMiscParameterHRD) { .buffer_size = base_encoder->bitrate * 1000 * 2, .initial_buffer_fullness = base_encoder->bitrate * 1000, }; /* *INDENT-ON* */ return TRUE; } static gboolean ensure_misc_params (GstVaapiEncoderVP8 * encoder, GstVaapiEncPicture * picture) { GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder); if (!gst_vaapi_encoder_ensure_param_quality_level (base_encoder, picture)) return FALSE; if (!gst_vaapi_encoder_ensure_param_control_rate (base_encoder, picture)) return FALSE; return TRUE; }