mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-15 22:01:27 +00:00
va: Add and use common decode negotiate vmethod.
This vmethod can be used by decoders with the same VA decoder reopen logic: same profile, chroma, width and height. Also a new public method called gst_va_base_dec_set_output_state() with the common GStreamer code for setting the output state, which is always called by the negotiate vmethod. In order to do this refactoring, new variables in vabasedec have to be populated by the decoders: * width and height define the resolution set in VA decoder. In the case of H264 would be de coded_width and codec_height, or max_width and max_height in AV1. * output_info is the downstream video info used for negotiation in gst_va_base_dec_set_output_state(). * input_state, from codec parent class shall be also held by vabasedec Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3480>
This commit is contained in:
parent
31c63a6e6c
commit
b6538e0560
6 changed files with 115 additions and 246 deletions
|
@ -101,9 +101,8 @@ gst_va_base_dec_stop (GstVideoDecoder * decoder)
|
||||||
if (!gst_va_decoder_close (base->decoder))
|
if (!gst_va_decoder_close (base->decoder))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (base->output_state)
|
g_clear_pointer (&base->output_state, gst_video_codec_state_unref);
|
||||||
gst_video_codec_state_unref (base->output_state);
|
g_clear_pointer (&base->input_state, gst_video_codec_state_unref);
|
||||||
base->output_state = NULL;
|
|
||||||
|
|
||||||
if (base->other_pool)
|
if (base->other_pool)
|
||||||
gst_buffer_pool_set_active (base->other_pool, FALSE);
|
gst_buffer_pool_set_active (base->other_pool, FALSE);
|
||||||
|
@ -662,10 +661,41 @@ gst_va_base_dec_set_context (GstElement * element, GstContext * context)
|
||||||
(element))->set_context (element, context);
|
(element))->set_context (element, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_va_base_dec_negotiate (GstVideoDecoder * decoder)
|
||||||
|
{
|
||||||
|
GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
|
||||||
|
|
||||||
|
/* Ignore downstream renegotiation request. */
|
||||||
|
if (!base->need_negotiation)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
base->need_negotiation = FALSE;
|
||||||
|
|
||||||
|
if (!gst_va_decoder_config_is_equal (base->decoder, base->profile,
|
||||||
|
base->rt_format, base->width, base->height)) {
|
||||||
|
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, base->width,
|
||||||
|
base->height))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gst_va_base_dec_set_output_state (base))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return GST_VIDEO_DECODER_CLASS (GST_VA_BASE_DEC_GET_PARENT_CLASS (decoder))
|
||||||
|
->negotiate (decoder);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gst_va_base_dec_init (GstVaBaseDec * base, GstDebugCategory * cat)
|
gst_va_base_dec_init (GstVaBaseDec * base, GstDebugCategory * cat)
|
||||||
{
|
{
|
||||||
base->debug_category = cat;
|
base->debug_category = cat;
|
||||||
|
gst_video_info_init (&base->output_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -713,6 +743,7 @@ gst_va_base_dec_class_init (GstVaBaseDecClass * klass, GstVaCodecs codec,
|
||||||
decoder_class->sink_query = GST_DEBUG_FUNCPTR (gst_va_base_dec_sink_query);
|
decoder_class->sink_query = GST_DEBUG_FUNCPTR (gst_va_base_dec_sink_query);
|
||||||
decoder_class->decide_allocation =
|
decoder_class->decide_allocation =
|
||||||
GST_DEBUG_FUNCPTR (gst_va_base_dec_decide_allocation);
|
GST_DEBUG_FUNCPTR (gst_va_base_dec_decide_allocation);
|
||||||
|
decoder_class->negotiate = GST_DEBUG_FUNCPTR (gst_va_base_dec_negotiate);
|
||||||
|
|
||||||
g_object_class_install_property (object_class, GST_VA_DEC_PROP_DEVICE_PATH,
|
g_object_class_install_property (object_class, GST_VA_DEC_PROP_DEVICE_PATH,
|
||||||
g_param_spec_string ("device-path", "Device Path",
|
g_param_spec_string ("device-path", "Device Path",
|
||||||
|
@ -978,7 +1009,7 @@ gst_va_base_dec_copy_output_buffer (GstVaBaseDec * base,
|
||||||
|
|
||||||
src_vinfo = &base->output_state->info;
|
src_vinfo = &base->output_state->info;
|
||||||
gst_video_info_set_format (&dest_vinfo, GST_VIDEO_INFO_FORMAT (src_vinfo),
|
gst_video_info_set_format (&dest_vinfo, GST_VIDEO_INFO_FORMAT (src_vinfo),
|
||||||
base->width, base->height);
|
GST_VIDEO_INFO_WIDTH (src_vinfo), GST_VIDEO_INFO_HEIGHT (src_vinfo));
|
||||||
|
|
||||||
ret = gst_buffer_pool_acquire_buffer (base->other_pool, &buffer, NULL);
|
ret = gst_buffer_pool_acquire_buffer (base->other_pool, &buffer, NULL);
|
||||||
if (ret != GST_FLOW_OK)
|
if (ret != GST_FLOW_OK)
|
||||||
|
@ -1003,8 +1034,8 @@ gst_va_base_dec_copy_output_buffer (GstVaBaseDec * base,
|
||||||
} else {
|
} else {
|
||||||
/* gst_video_frame_copy can crop this, but does not know, so let
|
/* gst_video_frame_copy can crop this, but does not know, so let
|
||||||
* make it think it's all right */
|
* make it think it's all right */
|
||||||
GST_VIDEO_INFO_WIDTH (&src_frame.info) = base->width;
|
GST_VIDEO_INFO_WIDTH (&src_frame.info) = GST_VIDEO_INFO_WIDTH (src_vinfo);
|
||||||
GST_VIDEO_INFO_HEIGHT (&src_frame.info) = base->height;
|
GST_VIDEO_INFO_HEIGHT (&src_frame.info) = GST_VIDEO_INFO_HEIGHT (src_vinfo);
|
||||||
|
|
||||||
if (!gst_video_frame_copy (&dest_frame, &src_frame)) {
|
if (!gst_video_frame_copy (&dest_frame, &src_frame)) {
|
||||||
gst_video_frame_unmap (&src_frame);
|
gst_video_frame_unmap (&src_frame);
|
||||||
|
@ -1070,3 +1101,35 @@ gst_va_base_dec_prepare_output_frame (GstVaBaseDec * base,
|
||||||
return gst_video_decoder_allocate_output_frame (vdec, frame);
|
return gst_video_decoder_allocate_output_frame (vdec, frame);
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_va_base_dec_set_output_state (GstVaBaseDec * base)
|
||||||
|
{
|
||||||
|
GstVideoDecoder *decoder = GST_VIDEO_DECODER (base);
|
||||||
|
GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
|
||||||
|
GstCapsFeatures *capsfeatures = NULL;
|
||||||
|
GstVideoInfo *info = &base->output_info;
|
||||||
|
|
||||||
|
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);
|
||||||
|
if (format == GST_VIDEO_FORMAT_UNKNOWN)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
base->output_state =
|
||||||
|
gst_video_decoder_set_interlaced_output_state (decoder, format,
|
||||||
|
GST_VIDEO_INFO_INTERLACE_MODE (info), GST_VIDEO_INFO_WIDTH (info),
|
||||||
|
GST_VIDEO_INFO_HEIGHT (info), base->input_state);
|
||||||
|
|
||||||
|
/* set caps feature */
|
||||||
|
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 (base, "Negotiated caps %" GST_PTR_FORMAT,
|
||||||
|
base->output_state->caps);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
|
@ -68,12 +68,15 @@ struct _GstVaBaseDec
|
||||||
|
|
||||||
VAProfile profile;
|
VAProfile profile;
|
||||||
guint rt_format;
|
guint rt_format;
|
||||||
|
/* coded or max resolution */
|
||||||
gint width;
|
gint width;
|
||||||
gint height;
|
gint height;
|
||||||
|
|
||||||
guint min_buffers;
|
guint min_buffers;
|
||||||
|
|
||||||
|
GstVideoInfo output_info;
|
||||||
GstVideoCodecState *output_state;
|
GstVideoCodecState *output_state;
|
||||||
|
GstVideoCodecState *input_state;
|
||||||
GstBufferPool *other_pool;
|
GstBufferPool *other_pool;
|
||||||
|
|
||||||
gboolean need_valign;
|
gboolean need_valign;
|
||||||
|
@ -137,5 +140,6 @@ gboolean gst_va_base_dec_process_output (GstVaBaseDec * base,
|
||||||
GstVideoBufferFlags buffer_flags);
|
GstVideoBufferFlags buffer_flags);
|
||||||
GstFlowReturn gst_va_base_dec_prepare_output_frame (GstVaBaseDec * base,
|
GstFlowReturn gst_va_base_dec_prepare_output_frame (GstVaBaseDec * base,
|
||||||
GstVideoCodecFrame * frame);
|
GstVideoCodecFrame * frame);
|
||||||
|
gboolean gst_va_base_dec_set_output_state (GstVaBaseDec * base);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
|
@ -75,8 +75,6 @@ struct _GstVaH264Dec
|
||||||
{
|
{
|
||||||
GstVaBaseDec parent;
|
GstVaBaseDec parent;
|
||||||
|
|
||||||
gint coded_width;
|
|
||||||
gint coded_height;
|
|
||||||
gint dpb_size;
|
gint dpb_size;
|
||||||
|
|
||||||
/* Used to fill VAPictureParameterBufferH264.ReferenceFrames */
|
/* Used to fill VAPictureParameterBufferH264.ReferenceFrames */
|
||||||
|
@ -643,6 +641,7 @@ gst_va_h264_dec_new_sequence (GstH264Decoder * decoder, const GstH264SPS * sps,
|
||||||
{
|
{
|
||||||
GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
|
GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
|
||||||
GstVaH264Dec *self = GST_VA_H264_DEC (decoder);
|
GstVaH264Dec *self = GST_VA_H264_DEC (decoder);
|
||||||
|
GstVideoInfo *info = &base->output_info;
|
||||||
VAProfile profile;
|
VAProfile profile;
|
||||||
gint display_width;
|
gint display_width;
|
||||||
gint display_height;
|
gint display_height;
|
||||||
|
@ -680,34 +679,35 @@ gst_va_h264_dec_new_sequence (GstH264Decoder * decoder, const GstH264SPS * sps,
|
||||||
rt_format, sps->width, sps->height)) {
|
rt_format, sps->width, sps->height)) {
|
||||||
base->profile = profile;
|
base->profile = profile;
|
||||||
base->rt_format = rt_format;
|
base->rt_format = rt_format;
|
||||||
self->coded_width = sps->width;
|
base->width = sps->width;
|
||||||
self->coded_height = sps->height;
|
base->height = sps->height;
|
||||||
|
|
||||||
negotiation_needed = TRUE;
|
negotiation_needed = TRUE;
|
||||||
GST_INFO_OBJECT (self, "Format changed to %s [%x] (%dx%d)",
|
GST_INFO_OBJECT (self, "Format changed to %s [%x] (%dx%d)",
|
||||||
gst_va_profile_name (profile), rt_format, self->coded_width,
|
gst_va_profile_name (profile), rt_format, base->width, base->height);
|
||||||
self->coded_height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (base->width != display_width || base->height != display_height) {
|
if (GST_VIDEO_INFO_WIDTH (info) != display_width ||
|
||||||
base->width = display_width;
|
GST_VIDEO_INFO_HEIGHT (info) != display_height) {
|
||||||
base->height = display_height;
|
GST_VIDEO_INFO_WIDTH (info) = display_width;
|
||||||
|
GST_VIDEO_INFO_HEIGHT (info) = display_height;
|
||||||
|
|
||||||
negotiation_needed = TRUE;
|
negotiation_needed = TRUE;
|
||||||
GST_INFO_OBJECT (self, "Resolution changed to %dx%d", base->width,
|
GST_INFO_OBJECT (self, "Resolution changed to %dx%d",
|
||||||
base->height);
|
GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info));
|
||||||
}
|
}
|
||||||
|
|
||||||
interlaced = !sps->frame_mbs_only_flag;
|
interlaced = !sps->frame_mbs_only_flag;
|
||||||
if (self->interlaced != interlaced) {
|
if (self->interlaced != interlaced) {
|
||||||
self->interlaced = interlaced;
|
self->interlaced = interlaced;
|
||||||
|
GST_VIDEO_INFO_INTERLACE_MODE (info) = interlaced ?
|
||||||
|
GST_VIDEO_INTERLACE_MODE_MIXED : GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
|
||||||
negotiation_needed = TRUE;
|
negotiation_needed = TRUE;
|
||||||
GST_INFO_OBJECT (self, "Interlaced mode changed to %d", interlaced);
|
GST_INFO_OBJECT (self, "Interlaced mode changed to %d", interlaced);
|
||||||
}
|
}
|
||||||
|
|
||||||
base->need_valign = base->width < self->coded_width
|
base->need_valign = GST_VIDEO_INFO_WIDTH (info) < base->width ||
|
||||||
|| base->height < self->coded_height;
|
GST_VIDEO_INFO_HEIGHT (info) < base->height;
|
||||||
if (base->need_valign) {
|
if (base->need_valign) {
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
if (base->valign.padding_left != padding_left ||
|
if (base->valign.padding_left != padding_left ||
|
||||||
|
@ -728,8 +728,9 @@ gst_va_h264_dec_new_sequence (GstH264Decoder * decoder, const GstH264SPS * sps,
|
||||||
}
|
}
|
||||||
|
|
||||||
base->min_buffers = self->dpb_size + 4; /* dpb size + scratch surfaces */
|
base->min_buffers = self->dpb_size + 4; /* dpb size + scratch surfaces */
|
||||||
|
|
||||||
base->need_negotiation = negotiation_needed;
|
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);
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
@ -823,56 +824,6 @@ gst_va_h264_dec_getcaps (GstVideoDecoder * decoder, GstCaps * filter)
|
||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gst_va_h264_dec_negotiate (GstVideoDecoder * decoder)
|
|
||||||
{
|
|
||||||
GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
|
|
||||||
GstVaH264Dec *self = GST_VA_H264_DEC (decoder);
|
|
||||||
GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
|
|
||||||
GstCapsFeatures *capsfeatures = NULL;
|
|
||||||
GstH264Decoder *h264dec = GST_H264_DECODER (decoder);
|
|
||||||
|
|
||||||
/* Ignore downstream renegotiation request. */
|
|
||||||
if (!base->need_negotiation)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
base->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);
|
|
||||||
if (format == GST_VIDEO_FORMAT_UNKNOWN)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
base->output_state =
|
|
||||||
gst_video_decoder_set_output_state (decoder, format,
|
|
||||||
base->width, base->height, h264dec->input_state);
|
|
||||||
if (self->interlaced)
|
|
||||||
base->output_state->info.interlace_mode = GST_VIDEO_INTERLACE_MODE_MIXED;
|
|
||||||
|
|
||||||
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 (parent_class)->negotiate (decoder);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_va_h264_dec_dispose (GObject * object)
|
gst_va_h264_dec_dispose (GObject * object)
|
||||||
{
|
{
|
||||||
|
@ -926,7 +877,6 @@ gst_va_h264_dec_class_init (gpointer g_class, gpointer class_data)
|
||||||
gobject_class->dispose = gst_va_h264_dec_dispose;
|
gobject_class->dispose = gst_va_h264_dec_dispose;
|
||||||
|
|
||||||
decoder_class->getcaps = GST_DEBUG_FUNCPTR (gst_va_h264_dec_getcaps);
|
decoder_class->getcaps = GST_DEBUG_FUNCPTR (gst_va_h264_dec_getcaps);
|
||||||
decoder_class->negotiate = GST_DEBUG_FUNCPTR (gst_va_h264_dec_negotiate);
|
|
||||||
|
|
||||||
h264decoder_class->new_sequence =
|
h264decoder_class->new_sequence =
|
||||||
GST_DEBUG_FUNCPTR (gst_va_h264_dec_new_sequence);
|
GST_DEBUG_FUNCPTR (gst_va_h264_dec_new_sequence);
|
||||||
|
|
|
@ -88,8 +88,6 @@ struct _GstVaH265Dec
|
||||||
{
|
{
|
||||||
GstVaBaseDec parent;
|
GstVaBaseDec parent;
|
||||||
|
|
||||||
gint coded_width;
|
|
||||||
gint coded_height;
|
|
||||||
gint dpb_size;
|
gint dpb_size;
|
||||||
|
|
||||||
VAPictureParameterBufferHEVCExtension pic_param;
|
VAPictureParameterBufferHEVCExtension pic_param;
|
||||||
|
@ -1047,6 +1045,7 @@ gst_va_h265_dec_new_sequence (GstH265Decoder * decoder, const GstH265SPS * sps,
|
||||||
{
|
{
|
||||||
GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
|
GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
|
||||||
GstVaH265Dec *self = GST_VA_H265_DEC (decoder);
|
GstVaH265Dec *self = GST_VA_H265_DEC (decoder);
|
||||||
|
GstVideoInfo *info = &base->output_info;
|
||||||
VAProfile profile;
|
VAProfile profile;
|
||||||
gint display_width;
|
gint display_width;
|
||||||
gint display_height;
|
gint display_height;
|
||||||
|
@ -1083,26 +1082,26 @@ gst_va_h265_dec_new_sequence (GstH265Decoder * decoder, const GstH265SPS * sps,
|
||||||
rt_format, sps->width, sps->height)) {
|
rt_format, sps->width, sps->height)) {
|
||||||
base->profile = profile;
|
base->profile = profile;
|
||||||
base->rt_format = rt_format;
|
base->rt_format = rt_format;
|
||||||
self->coded_width = sps->width;
|
base->width = sps->width;
|
||||||
self->coded_height = sps->height;
|
base->height = sps->height;
|
||||||
|
|
||||||
negotiation_needed = TRUE;
|
negotiation_needed = TRUE;
|
||||||
GST_INFO_OBJECT (self, "Format changed to %s [%x] (%dx%d)",
|
GST_INFO_OBJECT (self, "Format changed to %s [%x] (%dx%d)",
|
||||||
gst_va_profile_name (profile), rt_format, self->coded_width,
|
gst_va_profile_name (profile), rt_format, base->width, base->height);
|
||||||
self->coded_height);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (base->width != display_width || base->height != display_height) {
|
if (GST_VIDEO_INFO_WIDTH (info) != display_width ||
|
||||||
base->width = display_width;
|
GST_VIDEO_INFO_HEIGHT (info) != display_height) {
|
||||||
base->height = display_height;
|
GST_VIDEO_INFO_WIDTH (info) = display_width;
|
||||||
|
GST_VIDEO_INFO_HEIGHT (info) = display_height;
|
||||||
|
|
||||||
negotiation_needed = TRUE;
|
negotiation_needed = TRUE;
|
||||||
GST_INFO_OBJECT (self, "Resolution changed to %dx%d", base->width,
|
GST_INFO_OBJECT (self, "Resolution changed to %dx%d",
|
||||||
base->height);
|
GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info));
|
||||||
}
|
}
|
||||||
|
|
||||||
base->need_valign = base->width < self->coded_width
|
base->need_valign = GST_VIDEO_INFO_WIDTH (info) < base->width ||
|
||||||
|| base->height < self->coded_height;
|
GST_VIDEO_INFO_HEIGHT (info) < base->height;
|
||||||
if (base->need_valign) {
|
if (base->need_valign) {
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
if (base->valign.padding_left != padding_left ||
|
if (base->valign.padding_left != padding_left ||
|
||||||
|
@ -1123,8 +1122,9 @@ gst_va_h265_dec_new_sequence (GstH265Decoder * decoder, const GstH265SPS * sps,
|
||||||
}
|
}
|
||||||
|
|
||||||
base->min_buffers = self->dpb_size + 4; /* dpb size + scratch surfaces */
|
base->min_buffers = self->dpb_size + 4; /* dpb size + scratch surfaces */
|
||||||
|
|
||||||
base->need_negotiation = negotiation_needed;
|
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
|
/* FIXME: We don't have parser API for sps_range_extension, so
|
||||||
|
@ -1196,54 +1196,6 @@ gst_va_h265_dec_getcaps (GstVideoDecoder * decoder, GstCaps * filter)
|
||||||
return caps;
|
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 (!base->need_negotiation)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
base->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);
|
|
||||||
if (format == GST_VIDEO_FORMAT_UNKNOWN)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
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 (parent_class)->negotiate (decoder);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_va_h265_dec_dispose (GObject * object)
|
gst_va_h265_dec_dispose (GObject * object)
|
||||||
{
|
{
|
||||||
|
@ -1296,7 +1248,6 @@ gst_va_h265_dec_class_init (gpointer g_class, gpointer class_data)
|
||||||
gobject_class->dispose = gst_va_h265_dec_dispose;
|
gobject_class->dispose = gst_va_h265_dec_dispose;
|
||||||
|
|
||||||
decoder_class->getcaps = GST_DEBUG_FUNCPTR (gst_va_h265_dec_getcaps);
|
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 =
|
h265decoder_class->new_sequence =
|
||||||
GST_DEBUG_FUNCPTR (gst_va_h265_dec_new_sequence);
|
GST_DEBUG_FUNCPTR (gst_va_h265_dec_new_sequence);
|
||||||
|
|
|
@ -85,56 +85,6 @@ static const gchar *src_caps_str =
|
||||||
|
|
||||||
static const gchar *sink_caps_str = "video/x-mpeg2";
|
static const gchar *sink_caps_str = "video/x-mpeg2";
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gst_va_mpeg2_dec_negotiate (GstVideoDecoder * decoder)
|
|
||||||
{
|
|
||||||
GstCapsFeatures *capsfeatures = NULL;
|
|
||||||
GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
|
|
||||||
GstVaMpeg2Dec *self = GST_VA_MPEG2_DEC (decoder);
|
|
||||||
GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
|
|
||||||
GstMpeg2Decoder *mpeg2dec = GST_MPEG2_DECODER (decoder);
|
|
||||||
|
|
||||||
/* Ignore downstream renegotiation request. */
|
|
||||||
if (!base->need_negotiation)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
base->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, base->width, base->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);
|
|
||||||
if (format == GST_VIDEO_FORMAT_UNKNOWN)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
base->output_state =
|
|
||||||
gst_video_decoder_set_output_state (decoder, format,
|
|
||||||
base->width, base->height, mpeg2dec->input_state);
|
|
||||||
|
|
||||||
if (!self->progressive)
|
|
||||||
base->output_state->info.interlace_mode = GST_VIDEO_INTERLACE_MODE_MIXED;
|
|
||||||
|
|
||||||
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 (parent_class)->negotiate (decoder);
|
|
||||||
}
|
|
||||||
|
|
||||||
static VAProfile
|
static VAProfile
|
||||||
_map_profile (GstMpegVideoProfile profile)
|
_map_profile (GstMpegVideoProfile profile)
|
||||||
{
|
{
|
||||||
|
@ -226,6 +176,7 @@ gst_va_mpeg2_dec_new_sequence (GstMpeg2Decoder * decoder,
|
||||||
{
|
{
|
||||||
GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
|
GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
|
||||||
GstVaMpeg2Dec *self = GST_VA_MPEG2_DEC (decoder);
|
GstVaMpeg2Dec *self = GST_VA_MPEG2_DEC (decoder);
|
||||||
|
GstVideoInfo *info = &base->output_info;
|
||||||
VAProfile profile;
|
VAProfile profile;
|
||||||
GstMpegVideoProfile mpeg_profile;
|
GstMpegVideoProfile mpeg_profile;
|
||||||
gboolean negotiation_needed = FALSE;
|
gboolean negotiation_needed = FALSE;
|
||||||
|
@ -259,8 +210,8 @@ gst_va_mpeg2_dec_new_sequence (GstMpeg2Decoder * decoder,
|
||||||
rt_format, width, height)) {
|
rt_format, width, height)) {
|
||||||
base->profile = profile;
|
base->profile = profile;
|
||||||
base->rt_format = rt_format;
|
base->rt_format = rt_format;
|
||||||
base->width = width;
|
GST_VIDEO_INFO_WIDTH (info) = base->width = width;
|
||||||
base->height = height;
|
GST_VIDEO_INFO_HEIGHT (info) = base->height = height;
|
||||||
|
|
||||||
negotiation_needed = TRUE;
|
negotiation_needed = TRUE;
|
||||||
|
|
||||||
|
@ -271,16 +222,17 @@ gst_va_mpeg2_dec_new_sequence (GstMpeg2Decoder * decoder,
|
||||||
progressive = seq_ext ? seq_ext->progressive : 1;
|
progressive = seq_ext ? seq_ext->progressive : 1;
|
||||||
if (self->progressive != progressive) {
|
if (self->progressive != progressive) {
|
||||||
self->progressive = progressive;
|
self->progressive = progressive;
|
||||||
|
GST_VIDEO_INFO_INTERLACE_MODE (info) = progressive ?
|
||||||
|
GST_VIDEO_INTERLACE_MODE_PROGRESSIVE : GST_VIDEO_INTERLACE_MODE_MIXED;
|
||||||
negotiation_needed = TRUE;
|
negotiation_needed = TRUE;
|
||||||
GST_INFO_OBJECT (self, "Interlaced mode changed to %d", !progressive);
|
GST_INFO_OBJECT (self, "Interlaced mode changed to %d", !progressive);
|
||||||
}
|
}
|
||||||
|
|
||||||
base->need_valign = FALSE;
|
base->need_valign = FALSE;
|
||||||
|
|
||||||
base->min_buffers = 2 + 4; /* max num pic references + scratch surfaces */
|
base->min_buffers = 2 + 4; /* max num pic references + scratch surfaces */
|
||||||
|
|
||||||
base->need_negotiation = negotiation_needed;
|
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);
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
@ -594,7 +546,6 @@ gst_va_mpeg2_dec_class_init (gpointer g_class, gpointer class_data)
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
|
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
|
||||||
GstMpeg2DecoderClass *mpeg2decoder_class = GST_MPEG2_DECODER_CLASS (g_class);
|
GstMpeg2DecoderClass *mpeg2decoder_class = GST_MPEG2_DECODER_CLASS (g_class);
|
||||||
GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (g_class);
|
|
||||||
struct CData *cdata = class_data;
|
struct CData *cdata = class_data;
|
||||||
gchar *long_name;
|
gchar *long_name;
|
||||||
|
|
||||||
|
@ -627,8 +578,6 @@ gst_va_mpeg2_dec_class_init (gpointer g_class, gpointer class_data)
|
||||||
|
|
||||||
gobject_class->dispose = gst_va_mpeg2_dec_dispose;
|
gobject_class->dispose = gst_va_mpeg2_dec_dispose;
|
||||||
|
|
||||||
decoder_class->negotiate = GST_DEBUG_FUNCPTR (gst_va_mpeg2_dec_negotiate);
|
|
||||||
|
|
||||||
mpeg2decoder_class->new_sequence =
|
mpeg2decoder_class->new_sequence =
|
||||||
GST_DEBUG_FUNCPTR (gst_va_mpeg2_dec_new_sequence);
|
GST_DEBUG_FUNCPTR (gst_va_mpeg2_dec_new_sequence);
|
||||||
mpeg2decoder_class->new_picture =
|
mpeg2decoder_class->new_picture =
|
||||||
|
|
|
@ -82,53 +82,6 @@ static const gchar *src_caps_str =
|
||||||
|
|
||||||
static const gchar *sink_caps_str = "video/x-vp8";
|
static const gchar *sink_caps_str = "video/x-vp8";
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gst_va_vp8_dec_negotiate (GstVideoDecoder * decoder)
|
|
||||||
{
|
|
||||||
GstCapsFeatures *capsfeatures = NULL;
|
|
||||||
GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
|
|
||||||
GstVaVp8Dec *self = GST_VA_VP8_DEC (decoder);
|
|
||||||
GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
|
|
||||||
GstVp8Decoder *vp8dec = GST_VP8_DECODER (decoder);
|
|
||||||
|
|
||||||
/* Ignore downstream renegotiation request. */
|
|
||||||
if (!base->need_negotiation)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
base->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, base->width, base->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);
|
|
||||||
if (format == GST_VIDEO_FORMAT_UNKNOWN)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
base->output_state =
|
|
||||||
gst_video_decoder_set_output_state (decoder, format,
|
|
||||||
base->width, base->height, vp8dec->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 (parent_class)->negotiate (decoder);
|
|
||||||
}
|
|
||||||
|
|
||||||
static VAProfile
|
static VAProfile
|
||||||
_get_profile (GstVaVp8Dec * self, const GstVp8FrameHdr * frame_hdr)
|
_get_profile (GstVaVp8Dec * self, const GstVp8FrameHdr * frame_hdr)
|
||||||
{
|
{
|
||||||
|
@ -147,6 +100,7 @@ gst_va_vp8_dec_new_sequence (GstVp8Decoder * decoder,
|
||||||
{
|
{
|
||||||
GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
|
GstVaBaseDec *base = GST_VA_BASE_DEC (decoder);
|
||||||
GstVaVp8Dec *self = GST_VA_VP8_DEC (decoder);
|
GstVaVp8Dec *self = GST_VA_VP8_DEC (decoder);
|
||||||
|
GstVideoInfo *info = &base->output_info;
|
||||||
VAProfile profile;
|
VAProfile profile;
|
||||||
guint rt_format;
|
guint rt_format;
|
||||||
gboolean negotiation_needed = FALSE;
|
gboolean negotiation_needed = FALSE;
|
||||||
|
@ -169,15 +123,16 @@ gst_va_vp8_dec_new_sequence (GstVp8Decoder * decoder,
|
||||||
if (!gst_va_decoder_config_is_equal (base->decoder, profile,
|
if (!gst_va_decoder_config_is_equal (base->decoder, profile,
|
||||||
rt_format, frame_hdr->width, frame_hdr->height)) {
|
rt_format, frame_hdr->width, frame_hdr->height)) {
|
||||||
base->profile = profile;
|
base->profile = profile;
|
||||||
base->width = frame_hdr->width;
|
GST_VIDEO_INFO_WIDTH (info) = base->width = frame_hdr->width;
|
||||||
base->height = frame_hdr->height;
|
GST_VIDEO_INFO_HEIGHT (info) = base->height = frame_hdr->height;
|
||||||
base->rt_format = rt_format;
|
base->rt_format = rt_format;
|
||||||
negotiation_needed = TRUE;
|
negotiation_needed = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
base->min_buffers = 3 + 4; /* max num pic references + scratch surfaces */
|
base->min_buffers = 3 + 4; /* max num pic references + scratch surfaces */
|
||||||
|
|
||||||
base->need_negotiation = negotiation_needed;
|
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);
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
@ -471,7 +426,6 @@ gst_va_vp8_dec_class_init (gpointer g_class, gpointer class_data)
|
||||||
GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
|
GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
|
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
|
||||||
GstVp8DecoderClass *vp8decoder_class = GST_VP8_DECODER_CLASS (g_class);
|
GstVp8DecoderClass *vp8decoder_class = GST_VP8_DECODER_CLASS (g_class);
|
||||||
GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (g_class);
|
|
||||||
struct CData *cdata = class_data;
|
struct CData *cdata = class_data;
|
||||||
gchar *long_name;
|
gchar *long_name;
|
||||||
|
|
||||||
|
@ -504,8 +458,6 @@ gst_va_vp8_dec_class_init (gpointer g_class, gpointer class_data)
|
||||||
|
|
||||||
gobject_class->dispose = gst_va_vp8_dec_dispose;
|
gobject_class->dispose = gst_va_vp8_dec_dispose;
|
||||||
|
|
||||||
decoder_class->negotiate = GST_DEBUG_FUNCPTR (gst_va_vp8_dec_negotiate);
|
|
||||||
|
|
||||||
vp8decoder_class->new_sequence =
|
vp8decoder_class->new_sequence =
|
||||||
GST_DEBUG_FUNCPTR (gst_va_vp8_dec_new_sequence);
|
GST_DEBUG_FUNCPTR (gst_va_vp8_dec_new_sequence);
|
||||||
vp8decoder_class->new_picture =
|
vp8decoder_class->new_picture =
|
||||||
|
|
Loading…
Reference in a new issue