static gboolean ensure_sequence (GstVaapiEncoderVP8 * encoder, GstVaapiEncPicture * picture) { GstVaapiEncSequence *sequence; g_assert (picture); if (picture->type != GST_VAAPI_PICTURE_TYPE_I) return TRUE; sequence = GST_VAAPI_ENC_SEQUENCE_NEW (VP8, encoder); if (!sequence) goto error; if (!fill_sequence (encoder, sequence)) goto error; gst_vaapi_enc_picture_set_sequence (picture, sequence); gst_vaapi_codec_object_replace (&sequence, NULL); return TRUE; /* ERRORS */ error: { gst_vaapi_codec_object_replace (&sequence, NULL); return FALSE; } }
static gboolean fill_slices (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPicture * picture) { VAEncSliceParameterBufferMPEG2 *slice_param; GstVaapiEncSlice *slice; guint width_in_mbs, height_in_mbs; guint i_slice; g_assert (picture); width_in_mbs = (GST_VAAPI_ENCODER_WIDTH (encoder) + 15) / 16; height_in_mbs = (GST_VAAPI_ENCODER_HEIGHT (encoder) + 15) / 16; for (i_slice = 0; i_slice < height_in_mbs; ++i_slice) { slice = GST_VAAPI_ENC_SLICE_NEW (MPEG2, encoder); g_assert (slice && slice->param_id != VA_INVALID_ID); slice_param = slice->param; memset (slice_param, 0, sizeof (VAEncSliceParameterBufferMPEG2)); slice_param->macroblock_address = i_slice * width_in_mbs; slice_param->num_macroblocks = width_in_mbs; slice_param->is_intra_slice = (picture->type == GST_VAAPI_PICTURE_TYPE_I); slice_param->quantiser_scale_code = encoder->cqp / 2; gst_vaapi_enc_picture_add_slice (picture, slice); gst_vaapi_codec_object_replace (&slice, NULL); } return TRUE; }
static gboolean set_picture_packed_header (GstVaapiEncoderMpeg2 * encoder, GstVaapiEncPicture * picture) { GstVaapiEncPackedHeader *packed_pic; GstBitWriter writer; VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 }; const VAEncPictureParameterBufferMPEG2 *const pic_param = picture->param; guint32 data_bit_size; guint8 *data; gst_bit_writer_init (&writer, 128 * 8); gst_bit_writer_write_pps (&writer, pic_param); g_assert (GST_BIT_WRITER_BIT_SIZE (&writer) % 8 == 0); data_bit_size = GST_BIT_WRITER_BIT_SIZE (&writer); data = GST_BIT_WRITER_DATA (&writer); packed_header_param_buffer.type = VAEncPackedHeaderPicture; packed_header_param_buffer.bit_length = data_bit_size; packed_header_param_buffer.has_emulation_bytes = 0; packed_pic = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), &packed_header_param_buffer, sizeof (packed_header_param_buffer), data, (data_bit_size + 7) / 8); g_assert (packed_pic); gst_vaapi_enc_picture_add_packed_header (picture, packed_pic); gst_vaapi_codec_object_replace (&packed_pic, NULL); gst_bit_writer_clear (&writer, TRUE); return TRUE; }
static gboolean add_packed_header (GstVaapiEncoderJpeg * encoder, GstVaapiEncPicture * picture) { GstVaapiEncPackedHeader *packed_raw_data_hdr; GstBitWriter bs; VAEncPackedHeaderParameterBuffer packed_raw_data_hdr_param = { 0 }; guint32 data_bit_size; guint8 *data; gst_bit_writer_init (&bs, 128 * 8); bs_write_jpeg_header (&bs, encoder, picture); data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs); data = GST_BIT_WRITER_DATA (&bs); packed_raw_data_hdr_param.type = VAEncPackedHeaderRawData; packed_raw_data_hdr_param.bit_length = data_bit_size; packed_raw_data_hdr_param.has_emulation_bytes = 0; packed_raw_data_hdr = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder), &packed_raw_data_hdr_param, sizeof (packed_raw_data_hdr_param), data, (data_bit_size + 7) / 8); g_assert (packed_raw_data_hdr); gst_vaapi_enc_picture_add_packed_header (picture, packed_raw_data_hdr); gst_vaapi_codec_object_replace (&packed_raw_data_hdr, NULL); gst_bit_writer_clear (&bs, TRUE); return TRUE; }
static gboolean fill_slices (GstVaapiEncoderJpeg * encoder, GstVaapiEncPicture * picture) { VAEncSliceParameterBufferJPEG *slice_param; GstVaapiEncSlice *slice; VAEncPictureParameterBufferJPEG *const pic_param = picture->param; slice = GST_VAAPI_ENC_SLICE_NEW (JPEG, encoder); g_assert (slice && slice->param_id != VA_INVALID_ID); slice_param = slice->param; memset (slice_param, 0, sizeof (VAEncSliceParameterBufferJPEG)); slice_param->restart_interval = 0; slice_param->num_components = pic_param->num_components; slice_param->components[0].component_selector = 1; slice_param->components[0].dc_table_selector = 0; slice_param->components[0].ac_table_selector = 0; slice_param->components[1].component_selector = 2; slice_param->components[1].dc_table_selector = 1; slice_param->components[1].ac_table_selector = 1; slice_param->components[2].component_selector = 3; slice_param->components[2].dc_table_selector = 1; slice_param->components[2].ac_table_selector = 1; gst_vaapi_enc_picture_add_slice (picture, slice); gst_vaapi_codec_object_replace (&slice, NULL); 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; }