{
GstVaBaseDec parent;
- GstFlowReturn last_ret;
-
- gint coded_width;
- gint coded_height;
gint dpb_size;
VAPictureParameterBufferHEVCExtension pic_param;
gint32 WpOffsetHalfRangeC;
struct slice prev_slice;
-
- gboolean need_negotiation;
};
+static GstElementClass *parent_class = NULL;
+
/* *INDENT-OFF* */
static const gchar *src_caps_str =
GST_VIDEO_CAPS_MAKE_WITH_FEATURES (GST_CAPS_FEATURE_MEMORY_VA,
static gboolean
_is_screen_content_ext_profile (VAProfile profile)
{
- if (profile == VAProfileHEVCSccMain
- || profile == VAProfileHEVCSccMain10
- || profile == VAProfileHEVCSccMain444)
+ if (profile == VAProfileHEVCSccMain || profile == VAProfileHEVCSccMain10
+ || profile == VAProfileHEVCSccMain444
+#if VA_CHECK_VERSION(1, 8, 0)
+ || profile == VAProfileHEVCSccMain444_10
+#endif
+ )
return TRUE;
return FALSE;
return ret;
}
-static gboolean
+static GstFlowReturn
gst_va_h265_dec_end_picture (GstH265Decoder * decoder, GstH265Picture * picture)
{
GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
if (!ret) {
GST_ERROR_OBJECT (self, "Failed to submit the previous slice");
- return FALSE;
+ return GST_FLOW_ERROR;
}
ret = gst_va_decoder_decode (base->decoder, va_pic);
if (!ret) {
GST_ERROR_OBJECT (self, "Failed at end picture %p, (poc %d)",
picture, picture->pic_order_cnt);
- return FALSE;
+ return GST_FLOW_ERROR;
}
- return TRUE;
+ return GST_FLOW_OK;
}
static GstFlowReturn
{
GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
GstVaH265Dec *self = GST_VA_H265_DEC (decoder);
+ GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
GstVaDecodePicture *va_pic;
+ gboolean ret;
va_pic = gst_h265_picture_get_user_data (picture);
g_assert (va_pic->gstbuffer);
GST_LOG_OBJECT (self,
"Outputting picture %p (poc %d)", picture, picture->pic_order_cnt);
- if (self->last_ret != GST_FLOW_OK) {
- gst_h265_picture_unref (picture);
- _replace_previous_slice (self, NULL, 0);
- gst_video_decoder_drop_frame (GST_VIDEO_DECODER (self), frame);
- return self->last_ret;
- }
-
gst_buffer_replace (&frame->output_buffer, va_pic->gstbuffer);
- if (base->copy_frames)
- gst_va_base_dec_copy_output_buffer (base, frame);
-
+ ret = gst_va_base_dec_process_output (base, frame, picture->buffer_flags);
gst_h265_picture_unref (picture);
- return gst_video_decoder_finish_frame (GST_VIDEO_DECODER (self), frame);
+ if (ret)
+ return gst_video_decoder_finish_frame (vdec, frame);
+ return GST_FLOW_ERROR;
}
static void
GstVaH265Dec *self = GST_VA_H265_DEC (decoder);
guint8 i;
+ if (!picture)
+ return 0xFF;
+
for (i = 0; i < 15; i++) {
VAPictureHEVC *ref_va_pic = &self->pic_param.base.ReferenceFrames[i];
return nal_header_bytes + (slice_hdr->header_size + 7) / 8 - epb_count;
}
-static gboolean
+static GstFlowReturn
gst_va_h265_dec_decode_slice (GstH265Decoder * decoder,
GstH265Picture * picture, GstH265Slice * slice, GArray * ref_pic_list0,
GArray * ref_pic_list1)
if (!_submit_previous_slice (base, va_pic)) {
_replace_previous_slice (self, NULL, 0);
GST_ERROR_OBJECT (base, "Failed to submit previous slice buffers");
- return FALSE;
+ return GST_FLOW_ERROR;
}
slice_param = &self->prev_slice.param;
_replace_previous_slice (self, slice->nalu.data + slice->nalu.offset,
slice->nalu.size);
- return TRUE;
+ return GST_FLOW_OK;
}
static void
{
VAPictureParameterBufferHEVCRext *pic_param = &decoder->pic_param.rext;
- GstH265SPSExtensionParams *sps_ext = &sps->sps_extnsion_params;
+ GstH265SPSExtensionParams *sps_ext = &sps->sps_extension_params;
GstH265PPSExtensionParams *pps_ext = &pps->pps_extension_params;
/* *INDENT-OFF* */
}
}
-static gboolean
+static GstFlowReturn
gst_va_h265_dec_start_picture (GstH265Decoder * decoder,
GstH265Picture * picture, GstH265Slice * slice, GstH265Dpb * dpb)
{
sizeof (*pic_param) : sizeof (pic_param->base);
if (!gst_va_decoder_add_param_buffer (base->decoder, va_pic,
VAPictureParameterBufferType, pic_param, pic_param_size))
- return FALSE;
+ return GST_FLOW_ERROR;
if (pps->scaling_list_data_present_flag ||
(sps->scaling_list_enabled_flag
iq_matrix.ScalingListDC32x32[i] =
scaling_list->scaling_list_dc_coef_minus8_32x32[i] + 8;
- return gst_va_decoder_add_param_buffer (base->decoder, va_pic,
- VAIQMatrixBufferType, &iq_matrix, sizeof (iq_matrix));
+ if (!gst_va_decoder_add_param_buffer (base->decoder, va_pic,
+ VAIQMatrixBufferType, &iq_matrix, sizeof (iq_matrix))) {
+ return GST_FLOW_ERROR;
+ }
}
- return TRUE;
+ return GST_FLOW_OK;
}
-static gboolean
+static GstFlowReturn
gst_va_h265_dec_new_picture (GstH265Decoder * decoder,
GstVideoCodecFrame * frame, GstH265Picture * picture)
{
GstVaDecodePicture *pic;
GstBuffer *output_buffer;
GstVideoDecoder *vdec = GST_VIDEO_DECODER (decoder);
+ GstFlowReturn ret = GST_FLOW_ERROR;
+
+ if (base->need_negotiation) {
+ if (!gst_video_decoder_negotiate (vdec)) {
+ GST_ERROR_OBJECT (self, "Failed to negotiate with downstream");
+ return GST_FLOW_NOT_NEGOTIATED;
+ }
+ }
output_buffer = gst_video_decoder_allocate_output_buffer (vdec);
- if (!output_buffer) {
- self->last_ret = GST_FLOW_ERROR;
+ if (!output_buffer)
goto error;
- }
- self->last_ret = GST_FLOW_OK;
pic = gst_va_decode_picture_new (base->decoder, output_buffer);
gst_buffer_unref (output_buffer);
GST_LOG_OBJECT (self, "New va decode picture %p - %#x", pic,
gst_va_decode_picture_get_surface (pic));
- return TRUE;
+ return GST_FLOW_OK;
error:
{
GST_WARNING_OBJECT (self,
"Failed to allocated output buffer, return %s",
- gst_flow_get_name (self->last_ret));
- return FALSE;
+ gst_flow_get_name (ret));
+ return ret;
}
}
P (SCREEN_EXTENDED_MAIN, SccMain),
P (SCREEN_EXTENDED_MAIN_10, SccMain10),
P (SCREEN_EXTENDED_MAIN_444, SccMain444),
- /*P (SCREEN_EXTENDED_MAIN_444_10, ),
- P (SCREEN_EXTENDED_HIGH_THROUGHPUT_444, ),
+#if VA_CHECK_VERSION(1, 8, 0)
+ P (SCREEN_EXTENDED_MAIN_444_10, SccMain444_10),
+#endif
+ /*P (SCREEN_EXTENDED_HIGH_THROUGHPUT_444, ),
P (SCREEN_EXTENDED_HIGH_THROUGHPUT_444_10, ),
P (SCREEN_EXTENDED_HIGH_THROUGHPUT_444_14, ),
P (MULTIVIEW_MAIN, ),
return VAProfileNone;
}
-static gboolean
+static GstFlowReturn
gst_va_h265_dec_new_sequence (GstH265Decoder * decoder, const GstH265SPS * sps,
gint max_dpb_size)
{
GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
GstVaH265Dec *self = GST_VA_H265_DEC (decoder);
+ GstVideoInfo *info = &base->output_info;
VAProfile profile;
gint display_width;
gint display_height;
profile = _get_profile (self, sps, max_dpb_size);
if (profile == VAProfileNone)
- return FALSE;
+ return GST_FLOW_NOT_NEGOTIATED;
rt_format = _get_rtformat (self, sps->bit_depth_luma_minus8 + 8,
sps->bit_depth_chroma_minus8 + 8, sps->chroma_format_idc);
if (rt_format == 0)
- return FALSE;
+ return GST_FLOW_NOT_NEGOTIATED;
if (!gst_va_decoder_config_is_equal (base->decoder, profile,
rt_format, sps->width, sps->height)) {
base->profile = profile;
base->rt_format = rt_format;
- self->coded_width = sps->width;
- self->coded_height = sps->height;
+ base->width = sps->width;
+ base->height = sps->height;
negotiation_needed = TRUE;
GST_INFO_OBJECT (self, "Format changed to %s [%x] (%dx%d)",
- gst_va_profile_name (profile), rt_format, self->coded_width,
- self->coded_height);
+ gst_va_profile_name (profile), rt_format, base->width, base->height);
}
- if (base->width != display_width || base->height != display_height) {
- base->width = display_width;
- base->height = display_height;
+ if (GST_VIDEO_INFO_WIDTH (info) != display_width ||
+ GST_VIDEO_INFO_HEIGHT (info) != display_height) {
+ GST_VIDEO_INFO_WIDTH (info) = display_width;
+ GST_VIDEO_INFO_HEIGHT (info) = display_height;
negotiation_needed = TRUE;
- GST_INFO_OBJECT (self, "Resolution changed to %dx%d", base->width,
- base->height);
+ GST_INFO_OBJECT (self, "Resolution changed to %dx%d",
+ GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info));
}
- base->need_valign = base->width < self->coded_width
- || base->height < self->coded_height;
+ base->need_valign = GST_VIDEO_INFO_WIDTH (info) < base->width ||
+ GST_VIDEO_INFO_HEIGHT (info) < base->height;
if (base->need_valign) {
/* *INDENT-OFF* */
if (base->valign.padding_left != padding_left ||
}
base->min_buffers = self->dpb_size + 4; /* dpb size + scratch surfaces */
-
- if (negotiation_needed) {
- self->need_negotiation = TRUE;
- if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) {
- GST_ERROR_OBJECT (self, "Failed to negotiate with downstream");
- return FALSE;
- }
- }
+ base->need_negotiation = negotiation_needed;
+ g_clear_pointer (&base->input_state, gst_video_codec_state_unref);
+ base->input_state = gst_video_codec_state_ref (decoder->input_state);
{
/* FIXME: We don't have parser API for sps_range_extension, so
1 << (high_precision_offsets_enabled_flag ? (bitdepthC - 1) : 7);
}
- return TRUE;
+ return GST_FLOW_OK;
}
static GstCaps *
return caps;
}
-static gboolean
-gst_va_h265_dec_negotiate (GstVideoDecoder * decoder)
-{
- GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
- GstVaH265Dec *self = GST_VA_H265_DEC (decoder);
- GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
- GstCapsFeatures *capsfeatures = NULL;
- GstH265Decoder *h265dec = GST_H265_DECODER (decoder);
-
- /* Ignore downstream renegotiation request. */
- if (!self->need_negotiation)
- return TRUE;
-
- self->need_negotiation = FALSE;
-
- if (gst_va_decoder_is_open (base->decoder)
- && !gst_va_decoder_close (base->decoder))
- return FALSE;
-
- if (!gst_va_decoder_open (base->decoder, base->profile, base->rt_format))
- return FALSE;
-
- if (!gst_va_decoder_set_frame_size (base->decoder, self->coded_width,
- self->coded_height))
- return FALSE;
-
- if (base->output_state)
- gst_video_codec_state_unref (base->output_state);
-
- gst_va_base_dec_get_preferred_format_and_caps_features (base, &format,
- &capsfeatures);
-
- base->output_state =
- gst_video_decoder_set_output_state (decoder, format,
- base->width, base->height, h265dec->input_state);
-
- base->output_state->caps = gst_video_info_to_caps (&base->output_state->info);
- if (capsfeatures)
- gst_caps_set_features_simple (base->output_state->caps, capsfeatures);
-
- GST_INFO_OBJECT (self, "Negotiated caps %" GST_PTR_FORMAT,
- base->output_state->caps);
-
- return GST_VIDEO_DECODER_CLASS (GST_VA_BASE_DEC_GET_PARENT_CLASS
- (decoder))->negotiate (decoder);
-}
-
static void
gst_va_h265_dec_dispose (GObject * object)
{
gst_va_base_dec_close (GST_VIDEO_DECODER (object));
- G_OBJECT_CLASS (GST_VA_BASE_DEC_GET_PARENT_CLASS (object))->dispose (object);
+ G_OBJECT_CLASS (parent_class)->dispose (object);
}
static void
sink_doc_caps = gst_caps_from_string (sink_caps_str);
src_doc_caps = gst_caps_from_string (src_caps_str);
+ parent_class = g_type_class_peek_parent (g_class);
+
+ /**
+ * GstVaH265Dec:device-path:
+ *
+ * It shows the DRM device path used for the VA operation, if any.
+ *
+ * Since: 1.22
+ */
gst_va_base_dec_class_init (GST_VA_BASE_DEC_CLASS (g_class), HEVC,
cdata->render_device_path, cdata->sink_caps, cdata->src_caps,
src_doc_caps, sink_doc_caps);
gobject_class->dispose = gst_va_h265_dec_dispose;
decoder_class->getcaps = GST_DEBUG_FUNCPTR (gst_va_h265_dec_getcaps);
- decoder_class->negotiate = GST_DEBUG_FUNCPTR (gst_va_h265_dec_negotiate);
h265decoder_class->new_sequence =
GST_DEBUG_FUNCPTR (gst_va_h265_dec_new_sequence);
type_info.class_data = cdata;
- type_name = g_strdup ("GstVaH265Dec");
- feature_name = g_strdup ("vah265dec");
-
/* The first decoder to be registered should use a constant name,
* like vah265dec, for any additional decoders, we create unique
* names, using inserting the render device name. */
- if (g_type_from_name (type_name)) {
+ if (device->index == 0) {
+ type_name = g_strdup ("GstVaH265Dec");
+ feature_name = g_strdup ("vah265dec");
+ } else {
gchar *basename = g_path_get_basename (device->render_device_path);
- g_free (type_name);
- g_free (feature_name);
type_name = g_strdup_printf ("GstVa%sH265Dec", basename);
feature_name = g_strdup_printf ("va%sh265dec", basename);
cdata->description = basename;