struct _GstH264EncoderPrivate {
GstH264Encoder *public;
- uint32_t format; /*NV12, I420,*/
+ guint32 format; /*NV12, I420,*/
gboolean es_flag; /*elementary flag*/
/* private data*/
//GstVaapiDisplay *vaapi_display;
- GstVaapiContext *vaapi_context;
+ //GstVaapiContext *vaapi_context;
GQueue *video_buffer_caches; /*not used for baseline*/
GstVaapiSurface *ref_surface; /* reference buffer*/
VABufferID pic_parameter;
VABufferID slice_parameter;
VAEncSliceParameterBuffer *slice_param_buffers;
- uint32_t default_slice_height;
- uint32_t slice_mod_mb_num;
+ guint32 default_slice_height;
+ guint32 slice_mod_mb_num;
VABufferID *coded_bufs;
- uint32_t coded_buf_num;
- uint32_t cur_coded_index;
+ guint32 coded_buf_num;
+ guint32 cur_coded_index;
/*total encoded frames*/
- uint32_t frame_count;
+ guint32 frame_count;
GstBuffer *sps_data;
GstBuffer *pps_data;
#define BIT_STREAM_BIT_SIZE(stream) ((stream)->bit_size)
struct _H264Bitstream {
- uint8_t *buffer;
- uint32_t bit_size;
- uint32_t max_bit_capability;
+ guint8 *buffer;
+ guint32 bit_size;
+ guint32 max_bit_capability;
};
typedef struct _H264Bitstream H264Bitstream;
-static const uint8_t h264_bit_mask[9] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
+static const guint8 h264_bit_mask[9] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
static GstBufferClass *h264_encode_buffer_parent_class = NULL;
-static EncoderStatus gst_h264_encoder_initialize(GstVaapiEncoder* encoder);
-static EncoderStatus gst_h264_encoder_uninitialize(GstVaapiEncoder* encoder);
-static EncoderStatus gst_h264_encoder_open(GstVaapiEncoder* encoder, void* private_data);
-static EncoderStatus gst_h264_encoder_close(GstVaapiEncoder* encoder);
-static EncoderStatus gst_h264_encoder_encode(GstVaapiEncoder* encoder, GstBuffer *raw_pic, GList **coded_pics);
-static EncoderStatus gst_h264_encoder_flush(GstVaapiEncoder* encoder, GList **coded_pics);
-
-static gboolean gst_h264_validate_parameters(GstH264Encoder *encoder);
-static void gst_h264_encoder_finalize(GObject *object);
-static void gst_h264_encoder_init_public_values(GstH264Encoder* encoder);
-
-static VAProfile h264_get_va_profile(uint32_t profile);
-static EncoderStatus h264_encoder_alloc_buffers(GstH264EncoderPrivate *h264_prv);
-static EncoderStatus h264_encoder_release_buffers(GstH264EncoderPrivate *h264_prv);
-static EncoderStatus h264_put_raw_buffer_to_surface(GstH264EncoderPrivate *h264_prv,
- GstBuffer *raw_pic,
- GstVaapiSurface *surface);
-
-static EncoderStatus h264_prepare_encoding(GstH264EncoderPrivate *h264_prv,
- GstBuffer *raw_pic, gboolean is_key,
- VABufferID coded_buf);
-static EncoderStatus h264_query_encoding_status(GstH264EncoderPrivate *h264_prv,
- VASurfaceID surface_id,
- gboolean is_key,
- GstClockTime timestamp,
- GstClockTime duration,
- VABufferID *coded_buf,
- GList **coded_pics);
+static EncoderStatus gst_h264_encoder_initialize(GstVaapiEncoder* encoder, GstVaapiDisplay *display);
+static EncoderStatus gst_h264_encoder_uninitialize(GstVaapiEncoder* encoder, GstVaapiDisplay *display);
+static EncoderStatus gst_h264_encoder_open(GstVaapiEncoder* encoder, GstVaapiDisplay *display, void* private_data, GstVaapiContext **context);
+static EncoderStatus gst_h264_encoder_close(GstVaapiEncoder* encoder, GstVaapiDisplay *display, GstVaapiContext *context);
+static EncoderStatus gst_h264_encoder_encode(GstVaapiEncoder* encoder, GstVaapiDisplay *display,
+ GstVaapiContext *context, GstBuffer *raw_pic, GList **coded_pics);
+static EncoderStatus gst_h264_encoder_flush(GstVaapiEncoder* encoder, GstVaapiDisplay *display,
+ GstVaapiContext *context, GList **coded_pics);
+/*other functions*/
+static EncoderStatus gst_h264_encoder_get_avcC_codec_data(GstVaapiEncoder* encoder, GstBuffer **buffer);
+static EncoderStatus gst_h264_encoder_get_nal_codec_data(GstVaapiEncoder* encoder, GstBuffer **buffer);
+
+static gboolean gst_h264_validate_parameters(GstH264Encoder *encoder);
+static void gst_h264_encoder_finalize(GObject *object);
+static void gst_h264_encoder_init_public_values(GstH264Encoder* encoder);
+
+static VAProfile h264_get_va_profile(guint32 profile);
+static EncoderStatus h264_encoder_alloc_buffers(GstH264Encoder *h264_encoder,
+ GstVaapiDisplay *display, GstVaapiContext *context);
+static EncoderStatus h264_encoder_release_buffers(GstH264Encoder *h264_encoder,
+ GstVaapiDisplay *display, GstVaapiContext *context);
+static EncoderStatus h264_put_raw_buffer_to_surface(GstH264Encoder *h264_encoder,
+ GstVaapiDisplay *display,
+ GstBuffer *raw_pic,
+ GstVaapiSurface *surface);
+
+static EncoderStatus h264_prepare_encoding(GstH264Encoder *h264_encoder, GstVaapiDisplay *display,
+ GstVaapiContext *context, gboolean is_key, VABufferID coded_buf);
+static EncoderStatus h264_query_encoding_status(GstH264Encoder *h264_encoder,
+ GstVaapiDisplay *display,
+ GstVaapiSurface *buffer_surface,
+ gboolean is_key,
+ GstClockTime timestamp,
+ GstClockTime duration,
+ VABufferID *coded_buf,
+ GList **coded_pics);
static EncoderStatus
-h264_encoder_read_sps_pps(GstH264EncoderPrivate *h264_prv, const uint8_t *buf, uint32_t size);
+h264_encoder_read_sps_pps(GstH264EncoderPrivate *h264_prv, const guint8 *buf, guint32 size);
static GstBuffer *h264_encoder_create_coded_buffer(GstH264EncoderPrivate *h264_prv,
- uint8_t *frame,
- uint32_t frame_size,
+ guint8 *frame,
+ guint32 frame_size,
VABufferID *coded_buf);
VABufferID *coded_id);
/* h264 bitstream functions */
-static void h264_bitstream_init(H264Bitstream *bitstream, uint32_t bit_capability);
-static gboolean h264_bitstream_write_uint(H264Bitstream *bitstream, uint32_t value, uint32_t bit_size);
-static gboolean h264_bitstream_align(H264Bitstream *bitstream, uint32_t value);
-static gboolean h264_bitstream_write_ue(H264Bitstream *bitstream, uint32_t value);
-static gboolean h264_bitstream_write_se(H264Bitstream *bitstream, int32_t value);
+static void h264_bitstream_init(H264Bitstream *bitstream, guint32 bit_capability);
+static gboolean h264_bitstream_write_uint(H264Bitstream *bitstream, guint32 value, guint32 bit_size);
+static gboolean h264_bitstream_align(H264Bitstream *bitstream, guint32 value);
+static gboolean h264_bitstream_write_ue(H264Bitstream *bitstream, guint32 value);
+static gboolean h264_bitstream_write_se(H264Bitstream *bitstream, guint32 value);
static gboolean h264_bitstream_write_trailing_bits(H264Bitstream *bitstream);
-static gboolean h264_bitstream_write_byte_array(H264Bitstream *bitstream, const uint8_t *buf, uint32_t byte_size);
+static gboolean h264_bitstream_write_byte_array(H264Bitstream *bitstream, const guint8 *buf, guint32 byte_size);
static void h264_bitstream_destroy(H264Bitstream *bitstream, gboolean free_flag);
-static gboolean h264_bitstream_auto_grow(H264Bitstream *bitstream, uint32_t extra_bit_size);
+static gboolean h264_bitstream_auto_grow(H264Bitstream *bitstream, guint32 extra_bit_size);
static gboolean h264_bitstream_write_sps(H264Bitstream *bitstream, GstH264EncoderPrivate *h264_prv);
static gboolean h264_bitstream_write_pps(H264Bitstream *bitstream, GstH264EncoderPrivate *h264_prv);
-static const uint8_t *h264_next_nal(const uint8_t *buffer, uint32_t len, uint32_t *nal_size);
-static gboolean h264_read_sps_attributes(const uint8_t *sps_data, uint32_t sps_size,
- uint32_t *profile_idc, uint32_t *profile_comp, uint32_t *level_idc);
-
-/*other functions*/
-static EncoderStatus gst_h264_encoder_get_avcC_codec_data(GstVaapiEncoder* encoder, GstBuffer **buffer);
-static EncoderStatus gst_h264_encoder_get_nal_codec_data(GstVaapiEncoder* encoder, GstBuffer **buffer);
-
+static const guint8 *h264_next_nal(const guint8 *buffer, guint32 len, guint32 *nal_size);
+static gboolean h264_read_sps_attributes(const guint8 *sps_data, guint32 sps_size,
+ guint32 *profile_idc, guint32 *profile_comp, guint32 *level_idc);
+
+/* available_coded_buffer actions */
+static VABufferID *pop_available_coded_buffer(GstH264EncoderPrivate *h264_prv);
+static gboolean push_available_coded_buffer(GstH264EncoderPrivate *h264_prv, VABufferID *buf);
+static gboolean alloc_all_available_coded_buffers(GstH264EncoderPrivate *h264_prv,
+ GstVaapiDisplay *display, GstVaapiContext *context,
+ guint32 buffer_size, gboolean need_display_lock);
+static void wait_and_clear_available_coded_buffers(GstH264EncoderPrivate *h264_prv,
+ GstVaapiDisplay *display, gboolean need_display_lock);
static void
gst_h264_encoder_class_init(GstH264EncoderClass *klass)
encoder_class->close = gst_h264_encoder_close;
encoder_class->encode = gst_h264_encoder_encode;
encoder_class->flush = gst_h264_encoder_flush;
+ encoder_class->get_codec_data = gst_h264_encoder_get_avcC_codec_data;
+ /* encoder_class->get_codec_data = gst_h264_encoder_get_nal_codec_data; */
+
/*
object_class->set_property = gst_h264_encoder_set_property;
object_class->get_property = gst_h264_encoder_get_property;
VABufferID* coded_id = NULL;
GstVaapiDisplay *display = NULL;
+ gboolean is_locked = FALSE;
+
h264_prv = h264_buffer->encoder;
coded_id = h264_buffer->coded_id;
display = ENCODER_DISPLAY(h264_prv->public);
ENCODER_ASSERT(display);
- ENCODER_ASSERT(h264_prv->vaapi_context);
VADisplay va_dpy = gst_vaapi_display_get_display(display);
ENCODER_ASSERT(h264_prv);
ENCODER_ASSERT(coded_id && VA_INVALID_ID!= *coded_id);
- ENCODER_ASSERT(h264_prv->available_code_buffers);
- g_mutex_lock(h264_prv->code_buffer_lock);
/*if (--(*h264_buffer->ref_coded_id) == 0) */
{
/*g_free(h264_buffer->ref_coded_id);*/
+ ENCODER_ACQUIRE_DISPLAY_LOCK(display);
vaUnmapBuffer(va_dpy, *coded_id);
- g_queue_push_head(h264_prv->available_code_buffers, coded_id);
- g_cond_signal(h264_prv->code_buffer_cond);
+ ENCODER_RELEASE_DISPLAY_LOCK(display);
+ push_available_coded_buffer(h264_prv, coded_id);
}
- g_mutex_unlock(h264_prv->code_buffer_lock);
-
if (GST_MINI_OBJECT_CLASS(h264_encode_buffer_parent_class)->finalize) {
GST_MINI_OBJECT_CLASS(h264_encode_buffer_parent_class)->finalize(GST_MINI_OBJECT(h264_buffer));
}
#endif
}
-static GstVaapiSurface *
-h264_pop_free_surface(GstH264EncoderPrivate *h264_prv)
-{
- ENCODER_ASSERT(h264_prv && h264_prv->vaapi_context);
-
- /*may need lock*/
- GstVaapiSurface *surface = gst_vaapi_context_get_surface(h264_prv->vaapi_context);
- return surface;
-}
-
-static void
-h264_push_free_surface(GstH264EncoderPrivate *h264_prv, GstVaapiSurface *surface)
-{
- ENCODER_ASSERT(surface);
- if (!surface) {
- return;
- }
- gst_vaapi_context_put_surface(h264_prv->vaapi_context, surface);
-}
-
-
static VAProfile
-h264_get_va_profile(uint32_t profile)
+h264_get_va_profile(guint32 profile)
{
switch (profile) {
case H264_PROFILE_BASELINE:
h264_prv->es_flag = TRUE;
//h264_prv->vaapi_display = NULL;
- h264_prv->vaapi_context= NULL;
h264_prv->ref_surface = NULL;
h264_prv->recon_surface = NULL;
h264_prv->video_buffer_caches = g_queue_new();
h264_prv->code_buffer_cond = g_cond_new();
h264_prv->available_code_buffers = g_queue_new();
- encoder_prv->get_codec_data = gst_h264_encoder_get_avcC_codec_data;
- /* encoder_prv->get_codec_data = gst_h264_encoder_get_nal_codec_data; */
-
}
static void
gst_h264_encoder_finalize(GObject *object)
{
/*free private buffers*/
+ GstVaapiEncoder *encoder = GST_VAAPI_ENCODER(object);
GstH264EncoderPrivate *h264_prv = ENCPRV(object);
+ if (gst_vaapi_encoder_get_state(encoder) != VAAPI_ENC_NULL) {
+ gst_vaapi_encoder_uninitialize(encoder);
+ }
+
g_mutex_free(h264_prv->code_buffer_lock);
g_cond_free(h264_prv->code_buffer_cond);
if (h264_prv->available_code_buffers) {
h264_prv->available_code_buffers = NULL;
}
- if (h264_prv->ref_surface) {
- if (h264_prv->vaapi_context) {
- h264_push_free_surface(h264_prv, h264_prv->ref_surface);
- } else {
- g_object_unref(h264_prv->ref_surface);
- }
- h264_prv->ref_surface = NULL;
- }
- if (h264_prv->recon_surface) {
- if (h264_prv->vaapi_context) {
- h264_push_free_surface(h264_prv, h264_prv->recon_surface);
- } else {
- g_object_unref(h264_prv->recon_surface);
- }
- h264_prv->recon_surface = NULL;
- }
- if (h264_prv->vaapi_context) {
- g_object_unref(h264_prv->vaapi_context);
- h264_prv->vaapi_context= NULL;
- }
-
if (h264_prv->video_buffer_caches) {
g_queue_free(h264_prv->video_buffer_caches);
h264_prv->video_buffer_caches = NULL;
}
void
-gst_h264_encoder_set_input_format(GstH264Encoder* encoder, uint32_t format)
+gst_h264_encoder_set_input_format(GstH264Encoder* encoder, guint32 format)
{
GstH264EncoderPrivate *h264_prv = ENCPRV(encoder);
h264_prv->format = format;
}
EncoderStatus
-gst_h264_encoder_initialize(GstVaapiEncoder* encoder)
+gst_h264_encoder_initialize(GstVaapiEncoder* encoder, GstVaapiDisplay *display)
{
return ENCODER_NO_ERROR;
}
EncoderStatus
-gst_h264_encoder_uninitialize(GstVaapiEncoder* encoder)
+gst_h264_encoder_uninitialize(GstVaapiEncoder* encoder, GstVaapiDisplay *display)
{
return ENCODER_NO_ERROR;
}
EncoderStatus
-gst_h264_encoder_open(GstVaapiEncoder* encoder, void* private_data)
+gst_h264_encoder_open(GstVaapiEncoder* encoder, GstVaapiDisplay *display, void* private_data, GstVaapiContext **context)
{
GstH264Encoder* h264_encoder = GST_H264_ENCODER(encoder);
GstVaapiSurfacePool *surfaces_pool = private_data;
- GstVaapiDisplay *display = ENCODER_DISPLAY(encoder);
GstH264EncoderPrivate *h264_prv = ENCPRV(h264_encoder);
+ GstVaapiContext *out_context = NULL;
+ VAProfile va_profile = -1;
EncoderStatus ret = ENCODER_NO_ERROR;
- VAProfile va_profile = -1;
- VAEntrypoint entrypoints[5];
- int num_entrypoints,slice_entrypoint;
- VAConfigAttrib attrib[5];
VAStatus va_status = VA_STATUS_SUCCESS;
/*check and set default values*/
va_profile = h264_get_va_profile(h264_encoder->profile);
ENCODER_ASSERT(ENCODER_DISPLAY(encoder));
- ENCODER_ASSERT(!h264_prv->vaapi_context);
ENCODER_CHECK_STATUS(-1 != va_profile, ENCODER_PROFILE_ERR, "profile(%d) is NOT supported.\n", h264_encoder->profile);
#ifdef _MRST_
- h264_prv->vaapi_context = g_object_new(
+ out_context = g_object_new(
GST_VAAPI_TYPE_CONTEXT,
"display", display,
"id", GST_VAAPI_ID(VA_INVALID_ID),
NULL
);
if (surfaces_pool) {
- gst_vaapi_context_set_surface_pool(h264_prv->vaapi_context, surfaces_pool);
+ gst_vaapi_context_set_surface_pool(out_context, surfaces_pool);
}
- g_object_set(h264_prv->vaapi_context, "profile", gst_vaapi_profile(va_profile), NULL);
+ g_object_set(out_context, "profile", gst_vaapi_profile(va_profile), NULL);
#else
VAAPI_UNUSED_ARG(surfaces_pool);
- h264_prv->vaapi_context = gst_vaapi_context_new(display,
+ out_context = gst_vaapi_context_new(display,
gst_vaapi_profile(va_profile),
gst_vaapi_entrypoint(VAEntrypointEncSlice),
ENCODER_WIDTH(encoder),
ENCODER_HEIGHT(encoder));
#endif
- ENCODER_CHECK_STATUS(h264_prv->vaapi_context, ENCODER_CONTEXT_ERR, "gst_vaapi_context_new failed.\n");
- ret = h264_encoder_alloc_buffers(h264_prv);
+ ENCODER_CHECK_STATUS(out_context, ENCODER_CONTEXT_ERR, "gst_vaapi_context_new failed.\n");
+ ret = h264_encoder_alloc_buffers(h264_encoder, display, out_context);
if (ENCODER_NO_ERROR != ret) {
goto end;
}
-
+ *context = out_context;
return ENCODER_NO_ERROR;
- end:
+end:
// clear resources
- gst_h264_encoder_close(encoder);
+ if (ENCODER_NO_ERROR != ret) {
+ gst_h264_encoder_close(encoder, display, out_context);
+ if (out_context) {
+ g_object_unref(out_context);
+ }
+ }
return ret;
}
EncoderStatus
-gst_h264_encoder_close(GstVaapiEncoder* encoder)
+gst_h264_encoder_close(GstVaapiEncoder* encoder, GstVaapiDisplay *display, GstVaapiContext *context)
{
GstH264Encoder* h264_encoder = GST_H264_ENCODER(encoder);
EncoderStatus ret = ENCODER_NO_ERROR;
GstH264EncoderPrivate *h264_prv = ENCPRV(h264_encoder);
/* release buffers first */
- h264_encoder_release_buffers(h264_prv);
+ h264_encoder_release_buffers(h264_encoder, display, context);
/*remove ref_surface*/
if (h264_prv->ref_surface) {
- if (h264_prv->vaapi_context) {
- h264_push_free_surface(h264_prv, h264_prv->ref_surface);
+ if (context) {
+ gst_vaapi_context_put_surface(context, h264_prv->ref_surface);
} else {
g_object_unref(h264_prv->ref_surface);
}
/*remove recon_surface*/
if (h264_prv->recon_surface) {
- if (h264_prv->vaapi_context) {
- h264_push_free_surface(h264_prv, h264_prv->recon_surface);
+ if (context) {
+ gst_vaapi_context_put_surface(context, h264_prv->recon_surface);
} else {
g_object_unref(h264_prv->recon_surface);
}
h264_prv->recon_surface = NULL;
}
- /*remove vaapi_context*/
- if (h264_prv->vaapi_context) {
- g_object_unref(h264_prv->vaapi_context);
- h264_prv->vaapi_context = NULL;
- }
-
h264_prv->frame_count = 0;
if (h264_prv->sps_data) {
}
static EncoderStatus
-h264_encoder_alloc_buffers(GstH264EncoderPrivate *h264_prv)
+h264_encoder_alloc_buffers(GstH264Encoder *h264_encoder, GstVaapiDisplay *display, GstVaapiContext *context)
{
EncoderStatus ret = ENCODER_NO_ERROR;
VAStatus va_status = VA_STATUS_SUCCESS;
- GstVaapiDisplay *display = ENCODER_DISPLAY(h264_prv->public);
- uint32_t i;
+ GstH264EncoderPrivate *h264_prv = ENCPRV(h264_encoder);
+ guint32 i;
- ENCODER_ASSERT(display);
- ENCODER_ASSERT(h264_prv->vaapi_context);
+ ENCODER_ASSERT(display && context);
VADisplay va_dpy = gst_vaapi_display_get_display(display);
- VAContextID context_id = GST_VAAPI_OBJECT_ID(h264_prv->vaapi_context);
+ VAContextID context_id = GST_VAAPI_OBJECT_ID(context);
gboolean is_locked = FALSE;
- GST_VAAPI_DISPLAY_LOCK(display);
- is_locked = TRUE;
-
- /* create coded buffers */
- h264_prv->coded_bufs = (VABufferID*)g_malloc0(h264_prv->coded_buf_num * sizeof(h264_prv->coded_bufs[0]));
- { // check width, height ????
- uint32_t codedbuf_size = (ENCODER_WIDTH(h264_prv->public) * ENCODER_HEIGHT(h264_prv->public) * 400) / (16*16);
- for (i = 0; i < h264_prv->coded_buf_num; i++) {
- va_status = vaCreateBuffer(va_dpy, context_id,VAEncCodedBufferType,
- codedbuf_size, 1, NULL, &h264_prv->coded_bufs[i]);
-
- ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, ENCODER_ENC_RES_ERR, "alloc coded buffer failed.\n");
- }
- }
-
- /* unlock here */
- GST_VAAPI_DISPLAY_UNLOCK(display);
- is_locked = FALSE;
-
- ENCODER_ASSERT(h264_prv->available_code_buffers);
+ guint32 codedbuf_size = (ENCODER_WIDTH(h264_encoder) * ENCODER_HEIGHT(h264_encoder) * 400) / (16*16);
+ ENCODER_CHECK_STATUS(alloc_all_available_coded_buffers(h264_prv, display, context, codedbuf_size, TRUE),
+ ENCODER_ENC_RES_ERR,
+ "alloc_all_available_coded_buffers failed.\n");
/* create slice_param_buffers */
- h264_prv->slice_param_buffers = (VAEncSliceParameterBuffer*)g_malloc0_n(h264_prv->public->slice_num,
+ h264_prv->slice_param_buffers = (VAEncSliceParameterBuffer*)g_malloc0_n(h264_encoder->slice_num,
sizeof(h264_prv->slice_param_buffers[0]));
-
- /* init queue available_code_buffers */
- g_mutex_lock(h264_prv->code_buffer_lock);
- for (i = 0; i < h264_prv->coded_buf_num; i++) {
- g_queue_push_tail (h264_prv->available_code_buffers, &h264_prv->coded_bufs[i]);
- }
- g_cond_signal(h264_prv->code_buffer_cond);
- g_mutex_unlock(h264_prv->code_buffer_lock);
-
- return ENCODER_NO_ERROR;
-
- end:
- if (is_locked) {
- GST_VAAPI_DISPLAY_UNLOCK(display);
- is_locked = FALSE;
- }
+end:
return ret;
-
}
static EncoderStatus
-h264_encoder_release_buffers(GstH264EncoderPrivate *h264_prv)
+h264_encoder_release_buffers(GstH264Encoder *h264_encoder, GstVaapiDisplay *display, GstVaapiContext *context)
{
VAStatus va_status = VA_STATUS_SUCCESS;
- uint32_t available_buf_count = h264_prv->coded_buf_num;
- GstVaapiDisplay *display = ENCODER_DISPLAY(h264_prv->public);
- uint32_t i;
+ GstH264EncoderPrivate *h264_prv = ENCPRV(h264_encoder);
+ guint32 available_buf_count = h264_prv->coded_buf_num;
+ guint32 i;
+
+ gboolean is_locked = FALSE;
ENCODER_ASSERT(display);
- ENCODER_ASSERT(h264_prv->vaapi_context);
+ ENCODER_ASSERT(context);
VADisplay va_dpy = gst_vaapi_display_get_display(display);
- /* wait for all coded buffer freed*/
- g_mutex_lock(h264_prv->code_buffer_lock);
- while (available_buf_count) {
- if (g_queue_is_empty(h264_prv->available_code_buffers)) {
- g_cond_wait(h264_prv->code_buffer_cond, h264_prv->code_buffer_lock);
- } else {
- g_queue_pop_head(h264_prv->available_code_buffers);
- available_buf_count--;
- }
- }
- g_mutex_unlock(h264_prv->code_buffer_lock);
+ /* wait clear all coded buffer freed*/
+ wait_and_clear_available_coded_buffers(h264_prv, display, TRUE);
- GST_VAAPI_DISPLAY_LOCK(display);
- for (i = 0; i < h264_prv->coded_buf_num; i++) {
- va_status = vaDestroyBuffer(va_dpy, h264_prv->coded_bufs[i]);
- }
+ ENCODER_ACQUIRE_DISPLAY_LOCK(display);
va_status = vaDestroyBuffer(va_dpy, h264_prv->seq_parameter);
- GST_VAAPI_DISPLAY_UNLOCK(display);
-
- if (h264_prv->coded_bufs) {
- g_free(h264_prv->coded_bufs);
- h264_prv->coded_bufs = NULL;
- }
+ ENCODER_RELEASE_DISPLAY_LOCK(display);
if (h264_prv->slice_param_buffers) {
g_free(h264_prv->slice_param_buffers);
}
EncoderStatus
-gst_h264_encoder_encode(GstVaapiEncoder* encoder, GstBuffer *raw_pic, GList **coded_pics)
+gst_h264_encoder_encode(GstVaapiEncoder* encoder, GstVaapiDisplay *display,
+ GstVaapiContext *context, GstBuffer *raw_pic, GList **coded_pics)
{
GstH264Encoder* h264_encoder = GST_H264_ENCODER(encoder);
GstH264EncoderPrivate *h264_prv = ENCPRV(h264_encoder);
- GstVaapiDisplay *display = ENCODER_DISPLAY(encoder);
EncoderStatus ret = ENCODER_NO_ERROR;
gboolean is_key = FALSE;
VASurfaceID buffer_surface_id = VA_INVALID_SURFACE;
GstVaapiSurface *buffer_surface = NULL;
- ENCODER_ASSERT(display);
- ENCODER_ASSERT(h264_prv->vaapi_context);
+ gboolean is_locked = FALSE;
+
+ ENCODER_ASSERT(display && context);
VADisplay va_dpy = gst_vaapi_display_get_display(display);
- VAContextID context_id = GST_VAAPI_OBJECT_ID(h264_prv->vaapi_context);
+ VAContextID context_id = GST_VAAPI_OBJECT_ID(context);
GstVaapiSurface *new_surface = NULL;
if (GST_VAAPI_IS_VIDEO_BUFFER(raw_pic)) {
buffer_surface = h264_get_video_surface(h264_prv, GST_VAAPI_VIDEO_BUFFER(raw_pic));
} else {
- new_surface = h264_pop_free_surface(h264_prv);
+ new_surface = gst_vaapi_context_get_surface(context);
buffer_surface = new_surface;
ENCODER_CHECK_STATUS(buffer_surface, ENCODER_SURFACE_ERR, "h264_pop_free_surface failed.\n");
/*input picture to h264_prv->cur_surface_index*/
- va_status = h264_put_raw_buffer_to_surface(h264_prv, raw_pic, buffer_surface);
+ va_status = h264_put_raw_buffer_to_surface(h264_encoder, display, raw_pic, buffer_surface);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, ENCODER_PICTURE_ERR, "va put buffer to surface failed.\n");
}
buffer_surface_id = (VASurfaceID)GST_VAAPI_OBJECT_ID(buffer_surface);
ENCODER_CHECK_STATUS(buffer_surface_id != VA_INVALID_SURFACE, ENCODER_SURFACE_ERR, "surface id == VA_INVALID_SURFACE.\n");
/* begin picture, using default sid 0*/
- GST_VAAPI_DISPLAY_LOCK(display);
+ ENCODER_ACQUIRE_DISPLAY_LOCK(display);
va_status = vaBeginPicture(va_dpy, context_id, buffer_surface_id);
- GST_VAAPI_DISPLAY_UNLOCK(display);
+ ENCODER_RELEASE_DISPLAY_LOCK(display);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, ENCODER_PICTURE_ERR, "vaBeginPicture error.\n");
is_key = ((h264_prv->frame_count % h264_encoder->intra_period) == 0);
/*get valid coded buffer*/
- g_mutex_lock(h264_prv->code_buffer_lock);
- ENCODER_ASSERT(h264_prv->available_code_buffers);
- while (g_queue_is_empty(h264_prv->available_code_buffers)) {
- g_cond_wait(h264_prv->code_buffer_cond, h264_prv->code_buffer_lock);
- }
+ coded_buf = pop_available_coded_buffer(h264_prv);
+ ENCODER_CHECK_STATUS(coded_buf, ENCODER_ENC_RES_ERR, "dequeue_available_coded_buffer error.\n");
- coded_buf = (VABufferID*)g_queue_pop_head (h264_prv->available_code_buffers);
- ret = h264_prepare_encoding(h264_prv, raw_pic, is_key, *coded_buf);
+ ret = h264_prepare_encoding(h264_encoder, display, context, is_key, *coded_buf);
if (ENCODER_NO_ERROR != ret) {
- g_queue_push_head(h264_prv->available_code_buffers, coded_buf);
+ push_available_coded_buffer(h264_prv, coded_buf);
}
- g_mutex_unlock(h264_prv->code_buffer_lock);
-
ENCODER_CHECK_STATUS(ENCODER_NO_ERROR == ret, ENCODER_PICTURE_ERR, "h264_prepare_encoding failed.\n");
/* end picture */
- GST_VAAPI_DISPLAY_LOCK(display);
+ ENCODER_ACQUIRE_DISPLAY_LOCK(display);
va_status = vaEndPicture(va_dpy, context_id);
- GST_VAAPI_DISPLAY_UNLOCK(display);
+ ENCODER_RELEASE_DISPLAY_LOCK(display);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, ENCODER_PICTURE_ERR, "vaEndPicture error.\n");
/*query surface result*/
- ret = h264_query_encoding_status(h264_prv, buffer_surface_id,
+ ret = h264_query_encoding_status(h264_encoder, display, buffer_surface,
is_key, GST_BUFFER_TIMESTAMP(raw_pic), GST_BUFFER_DURATION(raw_pic), coded_buf, coded_pics);
if (ENCODER_NO_ERROR != ret) {
goto end;
h264_prv->frame_count++;
-
- end:
+end:
+ ENCODER_RELEASE_DISPLAY_LOCK(display);
if (new_surface) {
- h264_push_free_surface(h264_prv, new_surface);
+ gst_vaapi_context_put_surface(context, new_surface);
+ }
+ return ret;
+}
+
+static VABufferID *
+pop_available_coded_buffer(GstH264EncoderPrivate *h264_prv)
+{
+ VABufferID *coded_buf = NULL;
+ gboolean ret = TRUE;
+
+ g_mutex_lock(h264_prv->code_buffer_lock);
+
+ ENCODER_CHECK_STATUS(h264_prv->available_code_buffers, FALSE, "coded buffer not found");
+ while (g_queue_is_empty(h264_prv->available_code_buffers)) {
+ g_cond_wait(h264_prv->code_buffer_cond, h264_prv->code_buffer_lock);
+ }
+ coded_buf = (VABufferID*)g_queue_pop_head (h264_prv->available_code_buffers);
+
+end:
+ g_mutex_unlock(h264_prv->code_buffer_lock);
+ return coded_buf;
+}
+
+static gboolean
+push_available_coded_buffer(GstH264EncoderPrivate *h264_prv, VABufferID *buf)
+{
+ g_mutex_lock(h264_prv->code_buffer_lock);
+ g_queue_push_head(h264_prv->available_code_buffers, buf);
+ g_cond_signal(h264_prv->code_buffer_cond);
+ g_mutex_unlock(h264_prv->code_buffer_lock);
+ return TRUE;
+}
+
+static gboolean
+alloc_all_available_coded_buffers(GstH264EncoderPrivate *h264_prv, GstVaapiDisplay *display,
+ GstVaapiContext *context, guint32 buffer_size, gboolean need_display_lock)
+{
+ guint32 i = 0;
+ gboolean ret = TRUE;
+ VADisplay va_dpy = gst_vaapi_display_get_display(display);
+ VAContextID context_id = GST_VAAPI_OBJECT_ID(context);
+ VAStatus va_status = VA_STATUS_SUCCESS;
+
+ ENCODER_ASSERT(h264_prv->available_code_buffers);
+ ENCODER_ASSERT(!h264_prv->coded_bufs);
+
+ h264_prv->coded_bufs = (VABufferID*)g_malloc0(h264_prv->coded_buf_num * sizeof(h264_prv->coded_bufs[0]));
+
+ if (need_display_lock) { /* lock */
+ GST_VAAPI_DISPLAY_LOCK(display);
+ }
+ for (i = 0; i < h264_prv->coded_buf_num; i++) {
+ va_status = vaCreateBuffer(va_dpy, context_id,VAEncCodedBufferType,
+ buffer_size, 1, NULL, &h264_prv->coded_bufs[i]);
+ if (VA_STATUS_SUCCESS != va_status)
+ break;
+ }
+ if (need_display_lock) { /* unlock */
+ GST_VAAPI_DISPLAY_UNLOCK(display);
+ }
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status, FALSE, "alloc coded buffer failed.\n");
+
+ /* init queue available_code_buffers */
+ g_mutex_lock(h264_prv->code_buffer_lock);
+ for (i = 0; i < h264_prv->coded_buf_num; i++) {
+ g_queue_push_head(h264_prv->available_code_buffers, &h264_prv->coded_bufs[i]);
}
+ g_cond_signal(h264_prv->code_buffer_cond);
+ g_mutex_unlock(h264_prv->code_buffer_lock);
+
+end:
return ret;
}
+static void
+wait_and_clear_available_coded_buffers(GstH264EncoderPrivate *h264_prv,
+ GstVaapiDisplay *display, gboolean need_display_lock)
+{
+ guint32 available_buf_count = h264_prv->coded_buf_num;
+ VADisplay va_dpy = gst_vaapi_display_get_display(display);
+ VAStatus va_status = VA_STATUS_SUCCESS;
+ guint32 i = 0;
+
+ g_mutex_lock(h264_prv->code_buffer_lock);
+ while (available_buf_count) {
+ if (g_queue_is_empty(h264_prv->available_code_buffers)) {
+ g_cond_wait(h264_prv->code_buffer_cond, h264_prv->code_buffer_lock);
+ } else {
+ g_queue_pop_head(h264_prv->available_code_buffers);
+ available_buf_count--;
+ }
+ }
+ g_mutex_unlock(h264_prv->code_buffer_lock);
+
+ if (need_display_lock) {
+ GST_VAAPI_DISPLAY_LOCK(display);
+ }
+ for (i = 0; i < h264_prv->coded_buf_num; i++) {
+ va_status = vaDestroyBuffer(va_dpy, h264_prv->coded_bufs[i]);
+ }
+ if (need_display_lock) {
+ GST_VAAPI_DISPLAY_UNLOCK(display);
+ }
+
+ if (h264_prv->coded_bufs) {
+ g_free(h264_prv->coded_bufs);
+ h264_prv->coded_bufs = NULL;
+ }
+}
+
static EncoderStatus
-h264_put_raw_buffer_to_surface(GstH264EncoderPrivate *h264_prv,
+h264_put_raw_buffer_to_surface(GstH264Encoder *h264_encoder,
+ GstVaapiDisplay *display,
GstBuffer *raw_pic,
GstVaapiSurface *surface)
{
VADisplay va_dpy;
GstVaapiImage *image;
GstVaapiImageFormat image_format;
- uint8_t *y_src = NULL, *u_src = NULL, *v_src = NULL;
- uint8_t *y_dst = NULL, *u_dst = NULL, *v_dst = NULL;
+ guint8 *y_src = NULL, *u_src = NULL, *v_src = NULL;
+ guint8 *y_dst = NULL, *u_dst = NULL, *v_dst = NULL;
int y_size = 0, u_size = 0;
int row = 0, col = 0;
- uint32_t plane_count = 0;
- uint32_t image_width = 0, image_height = 0;
- uint32_t pitchy = 0, pitchu = 0, pitchv = 0;
- GstVaapiDisplay *display = ENCODER_DISPLAY(h264_prv->public);
+ guint32 plane_count = 0;
+ guint32 image_width = 0, image_height = 0;
+ guint32 pitchy = 0, pitchu = 0, pitchv = 0;
+ GstH264EncoderPrivate *h264_prv = ENCPRV(h264_encoder);
ENCODER_ASSERT(display);
va_dpy = gst_vaapi_display_get_display(display);
/* copy buffer to surface */
ENCODER_ASSERT(GST_BUFFER_SIZE(raw_pic) >= y_size + (y_size>>1));
- y_size = ENCODER_WIDTH(h264_prv->public) * ENCODER_HEIGHT(h264_prv->public);
- u_size = ((ENCODER_WIDTH(h264_prv->public)+1) >> 1) * ((ENCODER_HEIGHT(h264_prv->public)+1) >> 1);
+ y_size = ENCODER_WIDTH(h264_encoder) * ENCODER_HEIGHT(h264_encoder);
+ u_size = ((ENCODER_WIDTH(h264_encoder)+1) >> 1) * ((ENCODER_HEIGHT(h264_encoder)+1) >> 1);
y_src = GST_BUFFER_DATA(raw_pic);
u_src = y_src + y_size;
for (row = 0; row < image_height; row++) {
memcpy(y_dst, y_src, image_width);
y_dst += pitchy;
- y_src += ENCODER_WIDTH(h264_prv->public);
+ y_src += ENCODER_WIDTH(h264_encoder);
}
if (GST_VAAPI_IMAGE_NV12 == image_format) { /* UV plane */
}
u_dst += pitchu;
- u_src += (ENCODER_WIDTH(h264_prv->public)>>1);
- v_src += (ENCODER_WIDTH(h264_prv->public)>>1);
+ u_src += (ENCODER_WIDTH(h264_encoder)>>1);
+ v_src += (ENCODER_WIDTH(h264_encoder)>>1);
}
} else if (GST_VAAPI_IMAGE_NV12 == h264_prv->format){
for (row = 0; row < image_height / 2; row++) {
memcpy(u_dst, u_src, image_width);
- u_src += ENCODER_WIDTH(h264_prv->public);
+ u_src += ENCODER_WIDTH(h264_encoder);
u_dst += pitchu;
}
} else {
static EncoderStatus
-h264_prepare_encoding(GstH264EncoderPrivate *h264_prv, GstBuffer *raw_pic, gboolean is_key, VABufferID coded_buf)
+h264_prepare_encoding(GstH264Encoder *h264_encoder, GstVaapiDisplay *display,
+ GstVaapiContext *context, gboolean is_key, VABufferID coded_buf)
{
EncoderStatus ret = ENCODER_NO_ERROR;
VAStatus va_status = VA_STATUS_SUCCESS;
- GstVaapiDisplay *display = ENCODER_DISPLAY(h264_prv->public);
+ GstH264EncoderPrivate *h264_prv = ENCPRV(h264_encoder);
VAEncPictureParameterBufferH264 pic_h264;
VAEncSliceParameterBuffer *slice_h264 = NULL;
- ENCODER_ASSERT(display);
- ENCODER_ASSERT(h264_prv->vaapi_context);
+ gboolean is_locked = FALSE;
+
+ ENCODER_ASSERT(display && context);
VADisplay va_dpy = gst_vaapi_display_get_display(display);
- VAContextID context_id = GST_VAAPI_OBJECT_ID(h264_prv->vaapi_context);
+ VAContextID context_id = GST_VAAPI_OBJECT_ID(context);
/* lock display */
- GST_VAAPI_DISPLAY_LOCK(display);
+ ENCODER_ACQUIRE_DISPLAY_LOCK(display);
/*handle first surface_index*/
/*only need first frame*/
if (VA_INVALID_ID == h264_prv->seq_parameter) { /*first time*/
VAEncSequenceParameterBufferH264 seq_h264 = {0};
- seq_h264.level_idc = h264_prv->public->level; /* 3.0 */
+ seq_h264.level_idc = h264_encoder->level; /* 3.0 */
seq_h264.max_num_ref_frames = 1; /*Only I, P frames*/
- seq_h264.picture_width_in_mbs = (ENCODER_WIDTH(h264_prv->public)+15)/16;
- seq_h264.picture_height_in_mbs = (ENCODER_HEIGHT(h264_prv->public)+15)/16;
+ seq_h264.picture_width_in_mbs = (ENCODER_WIDTH(h264_encoder)+15)/16;
+ seq_h264.picture_height_in_mbs = (ENCODER_HEIGHT(h264_encoder)+15)/16;
- seq_h264.bits_per_second = h264_prv->public->bitrate;
- seq_h264.frame_rate = ENCODER_FPS(h264_prv->public);
- seq_h264.initial_qp = h264_prv->public->init_qp; /*qp_value; 15, 24, 26?*/
- seq_h264.min_qp = h264_prv->public->min_qp; /*1, 6, 10*/
+ seq_h264.bits_per_second = h264_encoder->bitrate;
+ seq_h264.frame_rate = ENCODER_FPS(h264_encoder);
+ seq_h264.initial_qp = h264_encoder->init_qp; /*qp_value; 15, 24, 26?*/
+ seq_h264.min_qp = h264_encoder->min_qp; /*1, 6, 10*/
seq_h264.basic_unit_size = 0;
- seq_h264.intra_period = h264_prv->public->intra_period;
- seq_h264.intra_idr_period = h264_prv->public->intra_period;
+ seq_h264.intra_period = h264_encoder->intra_period;
+ seq_h264.intra_idr_period = h264_encoder->intra_period;
va_status = vaCreateBuffer(va_dpy, context_id,
VAEncSequenceParameterBufferType,
/* set pic_parameters*/
if (!h264_prv->ref_surface) {
- h264_prv->ref_surface = h264_pop_free_surface(h264_prv);
+ h264_prv->ref_surface = gst_vaapi_context_get_surface(context);
ENCODER_CHECK_STATUS(h264_prv->ref_surface, ENCODER_SURFACE_ERR, "reference surface, h264_pop_free_surface failed.\n");
}
if (!h264_prv->recon_surface) {
- h264_prv->recon_surface = h264_pop_free_surface(h264_prv);
+ h264_prv->recon_surface = gst_vaapi_context_get_surface(context);
ENCODER_CHECK_STATUS(h264_prv->recon_surface, ENCODER_SURFACE_ERR, "reconstructed surface, h264_pop_free_surface failed.\n");
}
pic_h264.reference_picture = GST_VAAPI_OBJECT_ID(h264_prv->ref_surface);
pic_h264.reconstructed_picture = GST_VAAPI_OBJECT_ID(h264_prv->recon_surface);
pic_h264.coded_buf = coded_buf;
- pic_h264.picture_width = ENCODER_WIDTH(h264_prv->public);
- pic_h264.picture_height = ENCODER_HEIGHT(h264_prv->public);
+ pic_h264.picture_width = ENCODER_WIDTH(h264_encoder);
+ pic_h264.picture_height = ENCODER_HEIGHT(h264_encoder);
pic_h264.last_picture = 0; // last pic or not
if (VA_INVALID_ID != h264_prv->pic_parameter) { /* share the same pic_parameter*/
/* set slice parameters, support multiple slices */
int i = 0;
- uint32_t last_row_num = 0;
- uint32_t slice_mod_num = h264_prv->slice_mod_mb_num;
+ guint32 last_row_num = 0;
+ guint32 slice_mod_num = h264_prv->slice_mod_mb_num;
- memset(h264_prv->slice_param_buffers, 0, h264_prv->public->slice_num*sizeof(h264_prv->slice_param_buffers[0]));
- for (i = 0; i < h264_prv->public->slice_num; ++i) {
+ memset(h264_prv->slice_param_buffers, 0, h264_encoder->slice_num*sizeof(h264_prv->slice_param_buffers[0]));
+ for (i = 0; i < h264_encoder->slice_num; ++i) {
slice_h264 = &h264_prv->slice_param_buffers[i];
slice_h264->start_row_number = last_row_num; /* unit MB*/
slice_h264->slice_height = h264_prv->default_slice_height; /* unit MB */
slice_h264->slice_flags.bits.disable_deblocking_filter_idc = 0;
}
- ENCODER_ASSERT(last_row_num == (ENCODER_HEIGHT(h264_prv->public)+15)/16);
+ ENCODER_ASSERT(last_row_num == (ENCODER_HEIGHT(h264_encoder)+15)/16);
if (VA_INVALID_ID != h264_prv->slice_parameter) {
vaDestroyBuffer(va_dpy, h264_prv->slice_parameter);
context_id,
VAEncSliceParameterBufferType,
sizeof(h264_prv->slice_param_buffers[0]),
- h264_prv->public->slice_num,
+ h264_encoder->slice_num,
h264_prv->slice_param_buffers,
&h264_prv->slice_parameter);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, ENCODER_PICTURE_ERR, "creating slice-parameters buffer failed.\n");
va_status = vaRenderPicture(va_dpy, context_id, &h264_prv->slice_parameter, 1);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, ENCODER_PICTURE_ERR, "rendering slice-parameters buffer failed.\n");
-
/*after finished, set ref_surface_index, recon_surface_index */
GstVaapiSurface *swap = h264_prv->ref_surface;
h264_prv->ref_surface = h264_prv->recon_surface;
h264_prv->recon_surface = swap;
end:
- GST_VAAPI_DISPLAY_UNLOCK(display);
+ ENCODER_RELEASE_DISPLAY_LOCK(display);
return ret;
}
static EncoderStatus
-h264_query_encoding_status(GstH264EncoderPrivate *h264_prv,
- VASurfaceID surface_id,
+h264_query_encoding_status(GstH264Encoder *h264_encoder,
+ GstVaapiDisplay *display,
+ GstVaapiSurface *buffer_surface,
gboolean is_key,
GstClockTime timestamp,
GstClockTime duration,
GstBuffer* ret_buffer = NULL;
gboolean has_coded_data = FALSE;
gboolean is_locked = FALSE;
+ GstH264EncoderPrivate *h264_prv = ENCPRV(h264_encoder);
- GstVaapiDisplay *display = ENCODER_DISPLAY(h264_prv->public);
-
- ENCODER_ASSERT(display);
- ENCODER_ASSERT(h264_prv->vaapi_context);
+ ENCODER_ASSERT(display && context);
+ VASurfaceID surface_id = (VASurfaceID)GST_VAAPI_OBJECT_ID(buffer_surface);
VADisplay va_dpy = gst_vaapi_display_get_display(display);
- //VAContextID context_id = GST_VAAPI_OBJECT_ID(h264_prv->vaapi_context);
ENCODER_ASSERT(coded_pics && *coded_pics == NULL);
/* lock display */
- GST_VAAPI_DISPLAY_LOCK(display);
- is_locked = TRUE;
+ ENCODER_ACQUIRE_DISPLAY_LOCK(display);
va_status = vaSyncSurface(va_dpy, surface_id);
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, ENCODER_QUERY_STATUS_ERR, "vaSyncSurface failed.\n");
ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status, ENCODER_QUERY_STATUS_ERR, "vaMapBuffer failed.\n");
/*unlock display*/
- if (is_locked) {
- GST_VAAPI_DISPLAY_UNLOCK(display);
- is_locked = FALSE;
- }
+ ENCODER_RELEASE_DISPLAY_LOCK(display);
while (buf_list != NULL) {
if (!h264_prv->sps_data || !h264_prv->pps_data) {
if (!has_coded_data)
#endif
{ // if non-related, push back to available_code_buffers
- g_mutex_lock(h264_prv->code_buffer_lock);
- GST_VAAPI_DISPLAY_LOCK(display);
+ ENCODER_ACQUIRE_DISPLAY_LOCK(display);
vaUnmapBuffer(va_dpy, *coded_buf);
- GST_VAAPI_DISPLAY_UNLOCK(display);
- g_queue_push_head(h264_prv->available_code_buffers, coded_buf);
- g_cond_signal(h264_prv->code_buffer_cond);
- g_mutex_unlock(h264_prv->code_buffer_lock);
+ ENCODER_RELEASE_DISPLAY_LOCK(display);
+ push_available_coded_buffer(h264_prv, coded_buf);
}
return ENCODER_NO_ERROR;
- end:
+end:
/*unlock display*/
- if (is_locked) {
- GST_VAAPI_DISPLAY_UNLOCK(display);
- is_locked = FALSE;
- }
+ ENCODER_RELEASE_DISPLAY_LOCK(display);
return ret;
}
static GstBuffer *
h264_encoder_create_coded_buffer(GstH264EncoderPrivate *h264_prv,
- uint8_t *frame,
- uint32_t frame_size,
+ guint8 *frame,
+ guint32 frame_size,
VABufferID *coded_buf)
{
GstBuffer *ret_buffer;
- uint32_t nal_size;
- const uint8_t *nal_start;
- uint8_t *frame_end;
+ guint32 nal_size;
+ const guint8 *nal_start;
+ guint8 *frame_end;
#if SHARE_CODED_BUF
ret_buffer = gst_h264_encode_buffer_new(h264_prv, coded_buf);
}
static EncoderStatus
-h264_encoder_read_sps_pps(GstH264EncoderPrivate *h264_prv, const uint8_t *buf, uint32_t size)
+h264_encoder_read_sps_pps(GstH264EncoderPrivate *h264_prv, const guint8 *buf, guint32 size)
{
- const uint8_t *end = buf + size;
- const uint8_t *nal_start = buf;
- uint32_t nal_size = 0;
- uint8_t nal_type;
+ const guint8 *end = buf + size;
+ const guint8 *nal_start = buf;
+ guint32 nal_size = 0;
+ guint8 nal_type;
GstBuffer *sps = NULL, *pps = NULL;
while((!sps || !pps) && (nal_start = h264_next_nal(nal_start, end-nal_start, &nal_size)) != NULL) {
}
static gboolean
-h264_read_sps_attributes(const uint8_t *sps_data, uint32_t sps_size,
- uint32_t *profile_idc, uint32_t *profile_comp, uint32_t *level_idc)
+h264_read_sps_attributes(const guint8 *sps_data, guint32 sps_size,
+ guint32 *profile_idc, guint32 *profile_comp, guint32 *level_idc)
{
ENCODER_ASSERT(profile_idc && profile_comp && level_idc);
ENCODER_ASSERT(sps_size >= 4);
EncoderStatus
-gst_h264_encoder_flush(GstVaapiEncoder* encoder, GList **coded_pics)
+gst_h264_encoder_flush(GstVaapiEncoder* encoder, GstVaapiDisplay *display,
+ GstVaapiContext *context, GList **coded_pics)
{
GstH264Encoder* h264_encoder = GST_H264_ENCODER(encoder);
EncoderStatus ret = ENCODER_NO_ERROR;
GstH264EncoderPrivate *h264_prv = ENCPRV(h264_encoder);
- GstVaapiDisplay *display = ENCODER_DISPLAY(h264_prv->public);
h264_prv->frame_count = 0;
/*do we need destroy h264_prv->seq_parameter? */
GList *coded_pics = NULL;
GstBuffer **raw_buffer = NULL;
- const uint32_t raw_buffer_num = 20;
+ const guint32 raw_buffer_num = 20;
GstBuffer *tmp_buffer;
- uint32_t i = 0, k = 0;
+ guint32 i = 0, k = 0;
gst_init (&argc, &argv);
ret = gst_vaapi_encoder_open(encoder, NULL);
ENCODER_ASSERT(ret == ENCODER_NO_ERROR);
- uint32_t buffer_size = encoder->width * encoder->width *3 /2;
- uint32_t y_width = encoder->width, y_size = encoder->width * encoder->height;
- uint32_t u_width = encoder->width/2, u_size = (encoder->width/2) * (encoder->height/2);
- uint32_t v_width = encoder->width/2;
- uint8_t *y_src, *u_src, *v_src;
+ guint32 buffer_size = encoder->width * encoder->width *3 /2;
+ guint32 y_width = encoder->width, y_size = encoder->width * encoder->height;
+ guint32 u_width = encoder->width/2, u_size = (encoder->width/2) * (encoder->height/2);
+ guint32 v_width = encoder->width/2;
+ guint8 *y_src, *u_src, *v_src;
/*set buffers*/
int box_width=8;
GstH264Encoder *h264_encoder = GST_H264_ENCODER(encoder);
GstH264EncoderPrivate *h264_prv = ENCPRV(h264_encoder);
GstBuffer *avc_codec;
- const uint32_t configuration_version = 0x01;
- const uint32_t length_size_minus_one = 0x03;
- uint32_t profile, profile_comp, level_idc;
+ const guint32 configuration_version = 0x01;
+ const guint32 length_size_minus_one = 0x03;
+ guint32 profile, profile_comp, level_idc;
ENCODER_ASSERT(buffer);
if (!h264_prv->sps_data || !h264_prv->pps_data) {
}
static void
-h264_bitstream_init(H264Bitstream *bitstream, uint32_t bit_capability)
+h264_bitstream_init(H264Bitstream *bitstream, guint32 bit_capability)
{
bitstream->bit_size = 0;
bitstream->buffer = NULL;
}
static gboolean
-h264_bitstream_write_uint(H264Bitstream *bitstream, uint32_t value, uint32_t bit_size)
+h264_bitstream_write_uint(H264Bitstream *bitstream, guint32 value, guint32 bit_size)
{
gboolean ret = TRUE;
- uint32_t byte_pos, bit_offset;
- uint8_t *cur_byte;
- uint32_t fill_bits;
+ guint32 byte_pos, bit_offset;
+ guint8 *cur_byte;
+ guint32 fill_bits;
if(!bit_size) {
return TRUE;
return FALSE;
}
-static gboolean h264_bitstream_align(H264Bitstream *bitstream, uint32_t value)
+static gboolean h264_bitstream_align(H264Bitstream *bitstream, guint32 value)
{
- uint32_t bit_offset, bit_left;
+ guint32 bit_offset, bit_left;
bit_offset = (bitstream->bit_size&0x07);
if (!bit_offset) {
static gboolean
-h264_bitstream_write_byte_array(H264Bitstream *bitstream, const uint8_t *buf, uint32_t byte_size)
+h264_bitstream_write_byte_array(H264Bitstream *bitstream, const guint8 *buf, guint32 byte_size)
{
gboolean ret = TRUE;
if (!byte_size) {
}
return TRUE;
- end:
+end:
return FALSE;
}
static gboolean
-h264_bitstream_write_ue(H264Bitstream *bitstream, uint32_t value)
+h264_bitstream_write_ue(H264Bitstream *bitstream, guint32 value)
{
gboolean ret = TRUE;
- uint32_t size_in_bits = 0;
- uint32_t tmp_value = ++value;
+ guint32 size_in_bits = 0;
+ guint32 tmp_value = ++value;
while (tmp_value) {
++size_in_bits;
tmp_value >>= 1;
ENCODER_CHECK_STATUS(h264_bitstream_write_uint(bitstream, value, size_in_bits), FALSE, "h264_bitstream_write_ue failed.\n");
return TRUE;
- end:
+end:
return FALSE;
}
static gboolean
-h264_bitstream_write_se(H264Bitstream *bitstream, int32_t value)
+h264_bitstream_write_se(H264Bitstream *bitstream, guint32 value)
{
gboolean ret = TRUE;
- uint32_t new_val;
+ guint32 new_val;
if (value <= 0) {
new_val = -(value<<1);
}
static gboolean
-h264_bitstream_auto_grow(H264Bitstream *bitstream, uint32_t extra_bit_size)
+h264_bitstream_auto_grow(H264Bitstream *bitstream, guint32 extra_bit_size)
{
- uint32_t new_bit_size = extra_bit_size + bitstream->bit_size;
- uint32_t clear_pos;
+ guint32 new_bit_size = extra_bit_size + bitstream->bit_size;
+ guint32 clear_pos;
ENCODER_ASSERT(bitstream->bit_size <= bitstream->max_bit_capability);
if (new_bit_size <= bitstream->max_bit_capability) {
static gboolean
h264_bitstream_write_sps(H264Bitstream *bitstream, GstH264EncoderPrivate *h264_prv)
{
- uint32_t constraint_set0_flag, constraint_set1_flag, constraint_set2_flag, constraint_set3_flag;
- uint32_t seq_parameter_set_id = 0;
+ guint32 constraint_set0_flag, constraint_set1_flag, constraint_set2_flag, constraint_set3_flag;
+ guint32 seq_parameter_set_id = 0;
/*need to set the values*/
- uint32_t log2_max_frame_num_minus4 = 0; // 1? 3?
- uint32_t pic_order_cnt_type = 0; // Must be 0
- uint32_t log2_max_pic_order_cnt_lsb_minus4 = 0; // 2 ? 4?
- uint32_t num_ref_frames = 1; // only P frames
- uint32_t gaps_in_frame_num_value_allowed_flag = 0; // ??
- uint32_t mb_width = (ENCODER_WIDTH(h264_prv->public)+15)/16; // mb_width
- uint32_t mb_height = (ENCODER_HEIGHT(h264_prv->public)+15)/16; // mb_height
- int32_t frame_mbs_only_flag = 1; // only mbs
- uint32_t frame_cropping_flag = 0;
- uint32_t frame_crop_bottom_offset = 0;
- uint32_t vui_present_flag = 0; // no vui flags
+ guint32 log2_max_frame_num_minus4 = 0; // 1? 3?
+ guint32 pic_order_cnt_type = 0; // Must be 0
+ guint32 log2_max_pic_order_cnt_lsb_minus4 = 0; // 2 ? 4?
+ guint32 num_ref_frames = 1; // only P frames
+ guint32 gaps_in_frame_num_value_allowed_flag = 0; // ??
+ guint32 mb_width = (ENCODER_WIDTH(h264_prv->public)+15)/16; // mb_width
+ guint32 mb_height = (ENCODER_HEIGHT(h264_prv->public)+15)/16; // mb_height
+ guint32 frame_mbs_only_flag = 1; // only mbs
+ guint32 frame_cropping_flag = 0;
+ guint32 frame_crop_bottom_offset = 0;
+ guint32 vui_present_flag = 0; // no vui flags
constraint_set0_flag = h264_prv->public->profile == H264_PROFILE_BASELINE;
}
-static const uint8_t *
-h264_next_nal(const uint8_t *buffer, uint32_t len, uint32_t *nal_size)
+static const guint8 *
+h264_next_nal(const guint8 *buffer, guint32 len, guint32 *nal_size)
{
- const uint8_t *cur = buffer;
- const uint8_t *end = buffer + len;
- const uint8_t *nal_start = NULL;
- uint32_t flag = 0xFFFFFFFF;
- uint32_t nal_start_len = 0;
+ const guint8 *cur = buffer;
+ const guint8 *end = buffer + len;
+ const guint8 *nal_start = NULL;
+ guint32 flag = 0xFFFFFFFF;
+ guint32 nal_start_len = 0;
ENCODER_ASSERT(len >= 0 && buffer && nal_size);
if (len < 3) {