plugins: preserve framerate when updating src caps video format.

In the current implementation, gst_video_info_set_format() would reset
the whole GstVideoInfo structure first, prior to setting video format
and size. So, coleteral information like framerate or pixel-aspect-
ratio are lost.

Provide and use a unique gst_video_info_change_format() for overcome
this issue, i.e. only have it change the format and video size, and
copy over the rest of the fields.

https://bugzilla.gnome.org/show_bug.cgi?id=734665
This commit is contained in:
Gwenole Beauchesne 2014-11-18 14:57:02 +01:00
parent 0ddf6b21b9
commit a4d88db0fd
4 changed files with 28 additions and 25 deletions

View file

@ -129,25 +129,6 @@ gst_vaapidecode_update_sink_caps(GstVaapiDecode *decode, GstCaps *caps)
return TRUE; return TRUE;
} }
#if GST_CHECK_VERSION(1,1,0)
static void
gst_vaapidecode_video_info_change_format(GstVideoInfo *info,
GstVideoFormat format, guint width, guint height)
{
GstVideoInfo vi = *info;
gst_video_info_set_format (info, format, width, height);
info->interlace_mode = vi.interlace_mode;
info->flags = vi.flags;
info->views = vi.views;
info->par_n = vi.par_n;
info->par_d = vi.par_d;
info->fps_n = vi.fps_n;
info->fps_d = vi.fps_d;
}
#endif
static gboolean static gboolean
gst_vaapidecode_update_src_caps(GstVaapiDecode *decode, gst_vaapidecode_update_src_caps(GstVaapiDecode *decode,
const GstVideoCodecState *ref_state) const GstVideoCodecState *ref_state)
@ -188,7 +169,7 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode,
vis = *vi; vis = *vi;
switch (feature) { switch (feature) {
case GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META: case GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META:
gst_vaapidecode_video_info_change_format(&vis, GST_VIDEO_FORMAT_RGBA, gst_video_info_change_format(&vis, GST_VIDEO_FORMAT_RGBA,
GST_VIDEO_INFO_WIDTH(vi), GST_VIDEO_INFO_HEIGHT(vi)); GST_VIDEO_INFO_WIDTH(vi), GST_VIDEO_INFO_HEIGHT(vi));
features = gst_caps_features_new( features = gst_caps_features_new(
GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, NULL); GST_CAPS_FEATURE_META_GST_VIDEO_GL_TEXTURE_UPLOAD_META, NULL);
@ -199,7 +180,7 @@ gst_vaapidecode_update_src_caps(GstVaapiDecode *decode,
format=ENCODED + memory:VASurface caps feature are provided. format=ENCODED + memory:VASurface caps feature are provided.
Meanwhile, providing a random format here works but this is Meanwhile, providing a random format here works but this is
a terribly wrong thing per se. */ a terribly wrong thing per se. */
gst_vaapidecode_video_info_change_format(&vis, out_format, gst_video_info_change_format(&vis, out_format,
GST_VIDEO_INFO_WIDTH(vi), GST_VIDEO_INFO_HEIGHT(vi)); GST_VIDEO_INFO_WIDTH(vi), GST_VIDEO_INFO_HEIGHT(vi));
#if GST_CHECK_VERSION(1,5,0) #if GST_CHECK_VERSION(1,5,0)
if (feature == GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE) if (feature == GST_VAAPI_CAPS_FEATURE_VAAPI_SURFACE)
@ -544,7 +525,7 @@ gst_vaapidecode_decide_allocation(GstVideoDecoder *vdec, GstQuery *query)
state = gst_video_decoder_get_output_state(vdec); state = gst_video_decoder_get_output_state(vdec);
if (!gst_caps_is_always_compatible(caps, state->caps)) { if (!gst_caps_is_always_compatible(caps, state->caps)) {
if (decode->has_texture_upload_meta) if (decode->has_texture_upload_meta)
gst_video_info_set_format(&state->info, GST_VIDEO_FORMAT_RGBA, gst_video_info_change_format(&state->info, GST_VIDEO_FORMAT_RGBA,
GST_VIDEO_INFO_WIDTH(&state->info), GST_VIDEO_INFO_WIDTH(&state->info),
GST_VIDEO_INFO_HEIGHT(&state->info)); GST_VIDEO_INFO_HEIGHT(&state->info));
gst_vaapidecode_update_src_caps(decode, state); gst_vaapidecode_update_src_caps(decode, state);

View file

@ -681,3 +681,20 @@ gst_caps_has_vaapi_surface (GstCaps * caps)
#endif #endif
return found_caps; return found_caps;
} }
void
gst_video_info_change_format (GstVideoInfo * vip, GstVideoFormat format,
guint width, guint height)
{
GstVideoInfo vi = *vip;
gst_video_info_set_format (vip, format, width, height);
vip->interlace_mode = vi.interlace_mode;
vip->flags = vi.flags;
vip->views = vi.views;
vip->par_n = vi.par_n;
vip->par_d = vi.par_d;
vip->fps_n = vi.fps_n;
vip->fps_d = vi.fps_d;
}

View file

@ -117,4 +117,9 @@ G_GNUC_INTERNAL
gboolean gboolean
gst_caps_has_vaapi_surface (GstCaps * caps); gst_caps_has_vaapi_surface (GstCaps * caps);
G_GNUC_INTERNAL
void
gst_video_info_change_format (GstVideoInfo * vip, GstVideoFormat format,
guint width, guint height);
#endif /* GST_VAAPI_PLUGIN_UTIL_H */ #endif /* GST_VAAPI_PLUGIN_UTIL_H */

View file

@ -1153,7 +1153,7 @@ gst_vaapipostproc_transform_caps_impl(GstBaseTransform *trans,
out_format = GST_VIDEO_FORMAT_ENCODED; out_format = GST_VIDEO_FORMAT_ENCODED;
#endif #endif
find_best_size(postproc, &vi, &width, &height); find_best_size(postproc, &vi, &width, &height);
gst_video_info_set_format(&vi, out_format, width, height); gst_video_info_change_format(&vi, out_format, width, height);
#if GST_CHECK_VERSION(1,1,0) #if GST_CHECK_VERSION(1,1,0)
out_caps = gst_video_info_to_caps(&vi); out_caps = gst_video_info_to_caps(&vi);
@ -1177,7 +1177,7 @@ gst_vaapipostproc_transform_caps_impl(GstBaseTransform *trans,
if (feature == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META) if (feature == GST_VAAPI_CAPS_FEATURE_GL_TEXTURE_UPLOAD_META)
format = GST_VIDEO_FORMAT_RGBA; format = GST_VIDEO_FORMAT_RGBA;
gst_video_info_set_format(&vi, format, width, height); gst_video_info_change_format(&vi, format, width, height);
sink_caps = gst_video_info_to_caps(&vi); sink_caps = gst_video_info_to_caps(&vi);
if (sink_caps) { if (sink_caps) {
if (feature_str) if (feature_str)
@ -1318,7 +1318,7 @@ ensure_srcpad_buffer_pool(GstVaapiPostproc *postproc, GstCaps *caps)
gst_video_info_init(&vi); gst_video_info_init(&vi);
gst_video_info_from_caps(&vi, caps); gst_video_info_from_caps(&vi, caps);
gst_video_info_set_format(&vi, postproc->format, gst_video_info_change_format(&vi, postproc->format,
GST_VIDEO_INFO_WIDTH(&vi), GST_VIDEO_INFO_HEIGHT(&vi)); GST_VIDEO_INFO_WIDTH(&vi), GST_VIDEO_INFO_HEIGHT(&vi));
if (postproc->filter_pool && !video_info_changed(&vi, &postproc->filter_pool_info)) if (postproc->filter_pool && !video_info_changed(&vi, &postproc->filter_pool_info))