* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
+#define HAVE_OLD_H264_ENCODER 0
#include "gstvaapiencoder_h264.h"
+#include "config.h"
#include <string.h>
#include <stdlib.h>
#include <va/va.h>
#include <va/va_x11.h>
+#if !HAVE_OLD_H264_ENCODER
#include <va/va_enc_h264.h>
+#endif
#include <X11/Xlib.h>
#include <glib.h>
VABufferID packed_seq_data_id;
VABufferID packed_pic_param_id;
VABufferID packed_pic_data_id;
-#ifdef _SIMPLE_LIB_VA_
+#if HAVE_OLD_H264_ENCODER
VAEncSliceParameterBuffer *slice_param_buffers;
#else
VAEncSliceParameterBufferH264 *slice_param_buffers;
GstVaapiEncoderH264Private *priv = encoder->priv;
priv->slice_param_buffers =
-#ifdef _SIMPLE_LIB_VA_
+#if HAVE_OLD_H264_ENCODER
(VAEncSliceParameterBuffer*)
#else
(VAEncSliceParameterBufferH264*)
*s2 = tmp;
}
-#ifdef _SIMPLE_LIB_VA_
-
-static EncoderStatus
-gst_vaapi_encoder_h264_rendering(GstVaapiBaseEncoder *encoder, GstVaapiDisplay *display,
- GstVaapiContext *context, GstVaapiSurface *surface,
- guint frame_index, VABufferID coded_buf, gboolean *is_key)
+static inline const char *
+get_slice_type(H264_SLICE_TYPE type)
{
- EncoderStatus ret = ENCODER_NO_ERROR;
- VAStatus va_status = VA_STATUS_SUCCESS;
- GstVaapiEncoderH264 *h264_encoder = GST_VAAPI_ENCODER_H264_CAST(encoder);
- GstVaapiEncoderH264Private *priv = h264_encoder->priv;
- VAEncPictureParameterBufferH264 pic_param;
- VAEncSliceParameterBuffer *slice_param = NULL;
-
- gboolean is_locked = FALSE;
-
- ENCODER_ASSERT(display && context);
- VADisplay va_dpy = gst_vaapi_display_get_display(display);
- VAContextID context_id = GST_VAAPI_OBJECT_ID(context);
+ switch (type) {
+ case SLICE_TYPE_I:
+ return "I";
+ case SLICE_TYPE_P:
+ return "P";
+ case SLICE_TYPE_B:
+ return "B";
+ default:
+ return "Unknown";
+ }
+}
- *is_key = (priv->cur_slice_type == SLICE_TYPE_I);
+#if HAVE_OLD_H264_ENCODER
- /* lock display */
- ENCODER_ACQUIRE_DISPLAY_LOCK(display);
- /*handle first surface_index*/
- /*only need first frame*/
- if (VA_INVALID_ID == priv->seq_param_id) { /*first time*/
- VAEncSequenceParameterBufferH264 seq = { 0 };
- seq.level_idc = h264_encoder->level; /* 3.0 */
- seq.max_num_ref_frames = 1; /*Only I, P frames*/
- seq.picture_width_in_mbs = (ENCODER_WIDTH(h264_encoder)+15)/16;
- seq.picture_height_in_mbs = (ENCODER_HEIGHT(h264_encoder)+15)/16;
-
- seq.bits_per_second = h264_encoder->bitrate;
- seq.frame_rate = ENCODER_FPS(h264_encoder);
- seq.initial_qp = h264_encoder->init_qp; /*qp_value; 15, 24, 26?*/
- seq.min_qp = h264_encoder->min_qp; /*1, 6, 10*/
- seq.basic_unit_size = 0;
- seq.intra_period = h264_encoder->intra_period;
- seq.intra_idr_period = h264_encoder->intra_period;
-
- va_status = vaCreateBuffer(va_dpy, context_id,
- VAEncSequenceParameterBufferType,
- sizeof(seq), 1, &seq, &priv->seq_param_id);
- ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
- ENCODER_ENC_RES_ERR, "alloc seq-buffer failed.");
- va_status = vaRenderPicture(va_dpy, context_id, &priv->seq_param_id, 1);
- ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
- ENCODER_PICTURE_ERR, "vaRenderPicture seq-parameters failed.");
- }
+static gboolean
+set_sequence_parameters(
+ GstVaapiEncoderH264 *encoder,
+ VAEncSequenceParameterBufferH264 *seq_param
+)
+{
+ seq_param->seq_parameter_set_id = 0;
+ seq_param->level_idc = encoder->level; /* 3.0 */
+ seq_param->intra_period = encoder->intra_period;
+ seq_param->intra_idr_period = encoder->intra_period;
+ seq_param->max_num_ref_frames = 1; /*Only I, P frames*/
+ seq_param->picture_width_in_mbs = (ENCODER_WIDTH(encoder)+15)/16;
+ seq_param->picture_height_in_mbs = (ENCODER_HEIGHT(encoder)+15)/16;
+
+ seq_param->bits_per_second = encoder->bitrate;
+ seq_param->frame_rate = ENCODER_FPS(encoder);
+ seq_param->initial_qp = encoder->init_qp; /*qp_value; 15, 24, 26?*/
+ seq_param->min_qp = encoder->min_qp; /*1, 6, 10*/
+ seq_param->basic_unit_size = 0;
+ seq_param->vui_flag = FALSE;
- /* set pic_parameters*/
- if (!priv->ref_surface1) {
- priv->ref_surface1 = gst_vaapi_context_get_surface(context);
- ENCODER_CHECK_STATUS(priv->ref_surface1,
- ENCODER_SURFACE_ERR,
- "reference surface, h264_pop_free_surface failed.");
- }
- if (!priv->recon_surface) {
- priv->recon_surface = gst_vaapi_context_get_surface(context);
- ENCODER_CHECK_STATUS(priv->recon_surface,
- ENCODER_SURFACE_ERR,
- "reconstructed surface, h264_pop_free_surface failed.");
- }
+ return TRUE;
+}
- pic_param.reference_picture = GST_VAAPI_OBJECT_ID(priv->ref_surface1);
- pic_param.reconstructed_picture = GST_VAAPI_OBJECT_ID(priv->recon_surface);
- pic_param.coded_buf = coded_buf;
- pic_param.picture_width = ENCODER_WIDTH(h264_encoder);
- pic_param.picture_height = ENCODER_HEIGHT(h264_encoder);
- pic_param.last_picture = 0; // last pic or not
+static gboolean
+set_picture_parameters(
+ GstVaapiEncoderH264 *encoder,
+ VAEncPictureParameterBufferH264 *pic_param,
+ VABufferID coded_buf
+)
+{
+ GstVaapiEncoderH264Private *priv = encoder->priv;
- if (VA_INVALID_ID != priv->pic_param_id) { /* share the same pic_param_id*/
- vaDestroyBuffer(va_dpy, priv->pic_param_id);
- priv->pic_param_id = VA_INVALID_ID;
- }
- va_status = vaCreateBuffer(va_dpy, context_id, VAEncPictureParameterBufferType,
- sizeof(pic_param), 1, &pic_param, &priv->pic_param_id);
+ pic_param->reference_picture = GST_VAAPI_OBJECT_ID(priv->ref_surface1);
+ pic_param->reconstructed_picture = GST_VAAPI_OBJECT_ID(priv->recon_surface);
+ pic_param->coded_buf = coded_buf;
+ pic_param->picture_width = ENCODER_WIDTH(encoder);
+ pic_param->picture_height = ENCODER_HEIGHT(encoder);
+ pic_param->last_picture = 0; // last pic or not
- ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
- ENCODER_PICTURE_ERR,
- "creating pic-param buffer failed.");
+ return TRUE;
+}
- va_status = vaRenderPicture(va_dpy, context_id, &priv->pic_param_id, 1);
- ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
- ENCODER_PICTURE_ERR,
- "rendering pic-param buffer failed.");
+static gboolean
+set_slices_parameters(
+ GstVaapiEncoderH264 *encoder,
+ VAEncSliceParameterBuffer *slices,
+ guint slice_num
+)
+{
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ VAEncSliceParameterBuffer *slice_param;
- /* set slice parameters, support multiple slices */
int i = 0;
guint32 last_row_num = 0;
guint32 slice_mod_num = priv->slice_mod_mb_num;
- memset(priv->slice_param_buffers, 0, h264_encoder->slice_num*sizeof(priv->slice_param_buffers[0]));
- for (i = 0; i < h264_encoder->slice_num; ++i) {
- slice_param = &priv->slice_param_buffers[i];
+ for (i = 0; i < slice_num; ++i) {
+ slice_param = &slices[i];
slice_param->start_row_number = last_row_num; /* unit MB*/
slice_param->slice_height = priv->default_slice_height; /* unit MB */
if (slice_mod_num) {
--slice_mod_num;
}
last_row_num += slice_param->slice_height;
- slice_param->slice_flags.bits.is_intra = *is_key;
- slice_param->slice_flags.bits.disable_deblocking_filter_idc = 0;
-
+ slice_param->slice_flags.bits.is_intra =
+ (priv->cur_slice_type == SLICE_TYPE_I);
+ slice_param->slice_flags.bits.disable_deblocking_filter_idc = FALSE;
+ slice_param->slice_flags.bits.uses_long_term_ref = FALSE;
+ slice_param->slice_flags.bits.is_long_term_ref = FALSE;
}
- ENCODER_ASSERT(last_row_num == (ENCODER_HEIGHT(h264_encoder)+15)/16);
-
- if (VA_INVALID_ID != priv->slice_param_id) {
- vaDestroyBuffer(va_dpy, priv->slice_param_id);
- priv->slice_param_id = VA_INVALID_ID;
- }
- va_status = vaCreateBuffer(va_dpy,
- context_id,
- VAEncSliceParameterBufferType,
- sizeof(priv->slice_param_buffers[0]),
- h264_encoder->slice_num,
- priv->slice_param_buffers,
- &priv->slice_param_id);
- ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
- ENCODER_PICTURE_ERR,
- "creating slice-parameters buffer failed.");
-
- va_status = vaRenderPicture(va_dpy, context_id, &priv->slice_param_id, 1);
- ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
- ENCODER_PICTURE_ERR,
- "rendering slice-parameters buffer failed.");
-
- /*after finished, set ref_surface1_index, recon_surface_index */
- GstVaapiSurface *swap = priv->ref_surface1;
- priv->ref_surface1 = priv->recon_surface;
- priv->recon_surface = swap;
- end:
- ENCODER_RELEASE_DISPLAY_LOCK(display);
- return ret;
+ ENCODER_ASSERT(last_row_num == (ENCODER_HEIGHT(encoder)+15)/16);
+ return TRUE;
}
#else /* extended libva, new parameter structures*/
}
static gboolean
-h264_fill_sequence_buffer(GstVaapiEncoderH264 *encoder)
+ensure_packed_sps_data(
+ GstVaapiEncoderH264 *encoder,
+ VAEncSequenceParameterBufferH264 *seq_param
+)
{
GstVaapiEncoderH264Private *priv = encoder->priv;
- VAEncSequenceParameterBufferH264 seq_param = { 0 };
- VADisplay va_dpy = ENCODER_VA_DISPLAY(encoder);
+ VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
+ VADisplay va_dpy = ENCODER_VA_DISPLAY(encoder);
VAContextID context_id = ENCODER_VA_CONTEXT(encoder);
+ guint32 length_in_bits;
+ guint8 *packed_seq_buffer = NULL;
+ H264Bitstream bitstream;
gboolean ret = TRUE;
VAStatus va_status = VA_STATUS_SUCCESS;
- /* only once */
- if (VA_INVALID_ID != priv->seq_param_id)
+ if (priv->sps_data)
return TRUE;
- set_sequence_parameters(encoder, &seq_param);
- va_status = vaCreateBuffer(va_dpy, context_id,
- VAEncSequenceParameterBufferType,
- sizeof(seq_param), 1,
- &seq_param, &priv->seq_param_id);
+ h264_bitstream_init(&bitstream, 128*8);
+ h264_bitstream_write_uint(&bitstream, 0x00000001, 32); /* start code*/
+ h264_bitstream_write_nal_header(&bitstream, NAL_REF_IDC_HIGH, NAL_SPS);
+ h264_bitstream_write_sps(&bitstream, seq_param, encoder->profile);
+ ENCODER_ASSERT(BIT_STREAM_BIT_SIZE(&bitstream)%8 == 0);
+ length_in_bits = BIT_STREAM_BIT_SIZE(&bitstream);
+ packed_seq_buffer = BIT_STREAM_BUFFER(&bitstream);
+
+ /* set codec data sps */
+ priv->sps_data = gst_buffer_new_and_alloc((length_in_bits+7)/8);
+ GST_BUFFER_SIZE(priv->sps_data) = (length_in_bits+7)/8-4; /* start code size == 4*/
+ memcpy(GST_BUFFER_DATA(priv->sps_data),
+ packed_seq_buffer+4,
+ GST_BUFFER_SIZE(priv->sps_data));
+
+ packed_header_param_buffer.type = VAEncPackedHeaderSequence;
+ packed_header_param_buffer.bit_length = length_in_bits;
+ packed_header_param_buffer.has_emulation_bytes = 0;
+ va_status = vaCreateBuffer(va_dpy,
+ context_id,
+ VAEncPackedHeaderParameterBufferType,
+ sizeof(packed_header_param_buffer), 1,
+ &packed_header_param_buffer,
+ &priv->packed_seq_param_id);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
FALSE,
- "alloc seq-buffer failed.");
-
- /*pack sps header buffer/data */
- if (NULL == priv->sps_data) {
- VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
- guint32 length_in_bits;
- guint8 *packed_seq_buffer = NULL;
- H264Bitstream bitstream;
- h264_bitstream_init(&bitstream, 128*8);
- h264_bitstream_write_uint(&bitstream, 0x00000001, 32); /* start code*/
- h264_bitstream_write_nal_header(&bitstream, NAL_REF_IDC_HIGH, NAL_SPS);
- h264_bitstream_write_sps(&bitstream, &seq_param, encoder->profile);
- ENCODER_ASSERT(BIT_STREAM_BIT_SIZE(&bitstream)%8 == 0);
- length_in_bits = BIT_STREAM_BIT_SIZE(&bitstream);
- packed_seq_buffer = BIT_STREAM_BUFFER(&bitstream);
-
- /* set codec data sps */
- priv->sps_data = gst_buffer_new_and_alloc((length_in_bits+7)/8);
- GST_BUFFER_SIZE(priv->sps_data) = (length_in_bits+7)/8-4; /* start code size == 4*/
- memcpy(GST_BUFFER_DATA(priv->sps_data),
- packed_seq_buffer+4,
- GST_BUFFER_SIZE(priv->sps_data));
-
- packed_header_param_buffer.type = VAEncPackedHeaderSequence;
- packed_header_param_buffer.bit_length = length_in_bits;
- packed_header_param_buffer.has_emulation_bytes = 0;
- va_status = vaCreateBuffer(va_dpy,
- context_id,
- VAEncPackedHeaderParameterBufferType,
- sizeof(packed_header_param_buffer), 1,
- &packed_header_param_buffer,
- &priv->packed_seq_param_id);
- ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
- FALSE,
- "EncPackedSeqHeaderParameterBuffer failed");
- va_status = vaCreateBuffer(va_dpy,
- context_id,
- VAEncPackedHeaderDataBufferType,
- (length_in_bits + 7) / 8, 1,
- packed_seq_buffer,
- &priv->packed_seq_data_id);
- h264_bitstream_destroy(&bitstream, TRUE);
- ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
- FALSE,
- "EncPackedSeqHeaderDataBuffer failed");
- }
+ "EncPackedSeqHeaderParameterBuffer failed");
+ va_status = vaCreateBuffer(va_dpy,
+ context_id,
+ VAEncPackedHeaderDataBufferType,
+ (length_in_bits + 7) / 8, 1,
+ packed_seq_buffer,
+ &priv->packed_seq_data_id);
+ h264_bitstream_destroy(&bitstream, TRUE);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
+ FALSE,
+ "EncPackedSeqHeaderDataBuffer failed");
end:
+ return ret;
- return ret;
}
static gboolean
set_picture_parameters(
GstVaapiEncoderH264 *encoder,
- VAEncPictureParameterBufferH264 *pic_param
+ VAEncPictureParameterBufferH264 *pic_param,
+ VABufferID coded_buf
)
{
GstVaapiEncoderH264Private *priv = encoder->priv;
pic_param->pic_fields.bits.pic_order_present_flag = FALSE;
pic_param->pic_fields.bits.pic_scaling_matrix_present_flag = FALSE;
- return TRUE;
-}
+ /* reference list, */
+ pic_param->CurrPic.picture_id = GST_VAAPI_OBJECT_ID(priv->recon_surface);
+ pic_param->CurrPic.TopFieldOrderCnt = priv->cur_display_num * 2; // ??? /**/
+ pic_param->ReferenceFrames[0].picture_id = GST_VAAPI_OBJECT_ID(priv->ref_surface1);
+ pic_param->ReferenceFrames[1].picture_id = GST_VAAPI_OBJECT_ID(priv->ref_surface2);
+ pic_param->ReferenceFrames[2].picture_id = VA_INVALID_ID;
+ pic_param->coded_buf = coded_buf;
-static inline const char *
-get_slice_type(H264_SLICE_TYPE type)
-{
- switch (type) {
- case SLICE_TYPE_I:
- return "I";
- case SLICE_TYPE_P:
- return "P";
- case SLICE_TYPE_B:
- return "B";
- default:
- return "Unknown";
- }
+ ENCODER_LOG_INFO("type:%s, frame_num:%d, display_num:%d",
+ get_slice_type(priv->cur_slice_type),
+ pic_param->frame_num,
+ pic_param->CurrPic.TopFieldOrderCnt);
+ return TRUE;
}
static gboolean
-h264_fill_picture_buffer(
+ensure_packed_pps_data(
GstVaapiEncoderH264 *encoder,
- VABufferID coded_buf
+ VAEncPictureParameterBufferH264 *pic_param
)
{
GstVaapiEncoderH264Private *priv = encoder->priv;
- VAEncPictureParameterBufferH264 pic_param;
- VADisplay va_dpy = ENCODER_VA_DISPLAY(encoder);
+ VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
+ H264Bitstream bitstream;
+ VADisplay va_dpy = ENCODER_VA_DISPLAY(encoder);
VAContextID context_id = ENCODER_VA_CONTEXT(encoder);
+ guint32 length_in_bits;
+ guint8 *packed_pic_buffer = NULL;
gboolean ret = TRUE;
VAStatus va_status = VA_STATUS_SUCCESS;
- VAAPI_UNUSED_ARG(va_status);
- memset(&pic_param, 0, sizeof(pic_param));
- set_picture_parameters(encoder, &pic_param);
- pic_param.CurrPic.picture_id = GST_VAAPI_OBJECT_ID(priv->recon_surface);
- pic_param.CurrPic.TopFieldOrderCnt = priv->cur_display_num * 2; // ??? /**/
- pic_param.ReferenceFrames[0].picture_id = GST_VAAPI_OBJECT_ID(priv->ref_surface1);
- pic_param.ReferenceFrames[1].picture_id = GST_VAAPI_OBJECT_ID(priv->ref_surface2);
- pic_param.ReferenceFrames[2].picture_id = VA_INVALID_ID;
- pic_param.coded_buf = coded_buf;
+ if (VA_INVALID_ID != priv->packed_pic_data_id)
+ return TRUE;
- ENCODER_LOG_INFO("type:%s, frame_num:%d, display_num:%d",
- get_slice_type(priv->cur_slice_type),
- pic_param.frame_num,
- pic_param.CurrPic.TopFieldOrderCnt);
+ h264_bitstream_init(&bitstream, 128*8);
+ h264_bitstream_write_uint(&bitstream, 0x00000001, 32); /* start code*/
+ h264_bitstream_write_nal_header(&bitstream, NAL_REF_IDC_HIGH, NAL_PPS);
+ h264_bitstream_write_pps(&bitstream, pic_param);
+ ENCODER_ASSERT(BIT_STREAM_BIT_SIZE(&bitstream)%8 == 0);
+ length_in_bits = BIT_STREAM_BIT_SIZE(&bitstream);
+ packed_pic_buffer = BIT_STREAM_BUFFER(&bitstream);
+
+ /*set codec data pps*/
+ priv->pps_data = gst_buffer_new_and_alloc((length_in_bits+7)/8);
+ GST_BUFFER_SIZE(priv->pps_data) = (length_in_bits+7)/8-4;
+ memcpy(GST_BUFFER_DATA(priv->pps_data),
+ packed_pic_buffer+4,
+ GST_BUFFER_SIZE(priv->pps_data));
+
+ packed_header_param_buffer.type = VAEncPackedHeaderPicture;
+ packed_header_param_buffer.bit_length = length_in_bits;
+ packed_header_param_buffer.has_emulation_bytes = 0;
- if (VA_INVALID_ID != priv->pic_param_id) { /* share the same pic_param_id*/
- vaDestroyBuffer(va_dpy, priv->pic_param_id);
- priv->pic_param_id = VA_INVALID_ID;
- }
va_status = vaCreateBuffer(va_dpy,
context_id,
- VAEncPictureParameterBufferType,
- sizeof(pic_param), 1,
- &pic_param,
- &priv->pic_param_id);
-
+ VAEncPackedHeaderParameterBufferType,
+ sizeof(packed_header_param_buffer), 1,
+ &packed_header_param_buffer,
+ &priv->packed_pic_param_id);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
FALSE,
- "creating pic-param buffer failed.");
+ "EncPackedPicHeaderParameterBuffer failed");
- if (VA_INVALID_ID == priv->packed_pic_data_id) {
- VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
- guint32 length_in_bits;
- guint8 *packed_pic_buffer = NULL;
- H264Bitstream bitstream;
- h264_bitstream_init(&bitstream, 128*8);
- h264_bitstream_write_uint(&bitstream, 0x00000001, 32); /* start code*/
- h264_bitstream_write_nal_header(&bitstream, NAL_REF_IDC_HIGH, NAL_PPS);
- h264_bitstream_write_pps(&bitstream, &pic_param);
- ENCODER_ASSERT(BIT_STREAM_BIT_SIZE(&bitstream)%8 == 0);
- length_in_bits = BIT_STREAM_BIT_SIZE(&bitstream);
- packed_pic_buffer = BIT_STREAM_BUFFER(&bitstream);
-
- /*set codec data pps*/
- priv->pps_data = gst_buffer_new_and_alloc((length_in_bits+7)/8);
- GST_BUFFER_SIZE(priv->pps_data) = (length_in_bits+7)/8-4;
- memcpy(GST_BUFFER_DATA(priv->pps_data), packed_pic_buffer+4, GST_BUFFER_SIZE(priv->pps_data));
-
- packed_header_param_buffer.type = VAEncPackedHeaderPicture;
- packed_header_param_buffer.bit_length = length_in_bits;
- packed_header_param_buffer.has_emulation_bytes = 0;
-
- va_status = vaCreateBuffer(va_dpy,
- context_id,
- VAEncPackedHeaderParameterBufferType,
- sizeof(packed_header_param_buffer), 1,
- &packed_header_param_buffer,
- &priv->packed_pic_param_id);
- ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
- FALSE,
- "EncPackedPicHeaderParameterBuffer failed");
-
- va_status = vaCreateBuffer(va_dpy,
- context_id,
- VAEncPackedHeaderDataBufferType,
- (length_in_bits + 7) / 8, 1,
- packed_pic_buffer,
- &priv->packed_pic_data_id);
- h264_bitstream_destroy(&bitstream, TRUE);
- ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
- FALSE,
- "EncPackedPicHeaderDataBuffer failed");
- }
+ va_status = vaCreateBuffer(va_dpy,
+ context_id,
+ VAEncPackedHeaderDataBufferType,
+ (length_in_bits + 7) / 8, 1,
+ packed_pic_buffer,
+ &priv->packed_pic_data_id);
+ h264_bitstream_destroy(&bitstream, TRUE);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
+ FALSE,
+ "EncPackedPicHeaderDataBuffer failed");
end:
return ret;
}
-
static gboolean
-h264_fill_slice_buffers(
- GstVaapiEncoderH264 *encoder
+set_slices_parameters(
+ GstVaapiEncoderH264 *encoder,
+ VAEncSliceParameterBufferH264 *slices,
+ guint slice_num
)
{
GstVaapiEncoderH264Private *priv = encoder->priv;
- VAEncSliceParameterBufferH264 *slice_param = NULL;
- VADisplay va_dpy = ENCODER_VA_DISPLAY(encoder);
- VAContextID context_id = ENCODER_VA_CONTEXT(encoder);
- guint width_in_mbs;
- gboolean ret = TRUE;
- VAStatus va_status = VA_STATUS_SUCCESS;
-
- width_in_mbs = (ENCODER_WIDTH(encoder)+15)/16;
+ VAEncSliceParameterBufferH264 *slice_param;
+ guint width_in_mbs = (ENCODER_WIDTH(encoder)+15)/16;
int i = 0;
guint32 last_row_num = 0;
guint32 slice_mod_num = priv->slice_mod_mb_num;
- memset(priv->slice_param_buffers,
- 0,
- encoder->slice_num*sizeof(priv->slice_param_buffers[0]));
- for (i = 0; i < encoder->slice_num; ++i) {
+ for (i = 0; i < slice_num; ++i) {
int i_pic = 0;
- slice_param = &priv->slice_param_buffers[i];
+ slice_param = slices + i;
slice_param->macroblock_address = last_row_num*width_in_mbs;
slice_param->num_macroblocks = width_in_mbs*priv->default_slice_height;
}
ENCODER_ASSERT(last_row_num == (ENCODER_HEIGHT(encoder)+15)/16);
+ return TRUE;
+}
+
+#endif
+
+static gboolean
+h264_fill_sequence_buffer(GstVaapiEncoderH264 *encoder)
+{
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ VAEncSequenceParameterBufferH264 seq_param = { 0 };
+ VADisplay va_dpy = ENCODER_VA_DISPLAY(encoder);
+ VAContextID context_id = ENCODER_VA_CONTEXT(encoder);
+ gboolean ret = TRUE;
+ VAStatus va_status = VA_STATUS_SUCCESS;
+
+ /* only once */
+ if (VA_INVALID_ID != priv->seq_param_id)
+ return TRUE;
+
+ set_sequence_parameters(encoder, &seq_param);
+ va_status = vaCreateBuffer(va_dpy, context_id,
+ VAEncSequenceParameterBufferType,
+ sizeof(seq_param), 1,
+ &seq_param, &priv->seq_param_id);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
+ FALSE,
+ "alloc seq-buffer failed.");
+
+#if !HAVE_OLD_H264_ENCODER
+ ensure_packed_sps_data(encoder, &seq_param);
+#endif
+
+end:
+ return ret;
+}
+
+static gboolean
+h264_fill_picture_buffer(
+ GstVaapiEncoderH264 *encoder,
+ VABufferID coded_buf
+)
+{
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ VAEncPictureParameterBufferH264 pic_param;
+ VADisplay va_dpy = ENCODER_VA_DISPLAY(encoder);
+ VAContextID context_id = ENCODER_VA_CONTEXT(encoder);
+ gboolean ret = TRUE;
+ VAStatus va_status = VA_STATUS_SUCCESS;
+
+ VAAPI_UNUSED_ARG(va_status);
+ memset(&pic_param, 0, sizeof(pic_param));
+ set_picture_parameters(encoder, &pic_param, coded_buf);
+
+ if (VA_INVALID_ID != priv->pic_param_id) { /* share the same pic_param_id*/
+ vaDestroyBuffer(va_dpy, priv->pic_param_id);
+ priv->pic_param_id = VA_INVALID_ID;
+ }
+ va_status = vaCreateBuffer(va_dpy,
+ context_id,
+ VAEncPictureParameterBufferType,
+ sizeof(pic_param), 1,
+ &pic_param,
+ &priv->pic_param_id);
+
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
+ FALSE,
+ "creating pic-param buffer failed.");
+#if !HAVE_OLD_H264_ENCODER
+ ensure_packed_pps_data(encoder, &pic_param);
+#endif
+
+end:
+ return ret;
+}
+
+static gboolean
+h264_fill_slice_buffers(
+ GstVaapiEncoderH264 *encoder
+)
+{
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ VADisplay va_dpy = ENCODER_VA_DISPLAY(encoder);
+ VAContextID context_id = ENCODER_VA_CONTEXT(encoder);
+ gboolean ret = TRUE;
+ VAStatus va_status = VA_STATUS_SUCCESS;
+
+ memset(priv->slice_param_buffers,
+ 0,
+ encoder->slice_num * sizeof(priv->slice_param_buffers[0]));
+ set_slices_parameters(encoder,
+ priv->slice_param_buffers,
+ encoder->slice_num);
if (VA_INVALID_ID != priv->slice_param_id) {
vaDestroyBuffer(va_dpy, priv->slice_param_id);
return ret;
}
-#endif
-
static const guint8 *
h264_next_nal(const guint8 *buffer, guint32 len, guint32 *nal_size)
{
return TRUE;
}
+#if !HAVE_OLD_H264_ENCODER
+
static gboolean
h264_bitstream_write_sps(
H264Bitstream *bitstream,
h264_bitstream_write_trailing_bits(bitstream);
return TRUE;
}
+#endif