mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-27 02:30:35 +00:00
smartencoder: Fix renegotiating when reencoding parts of the stream with vpx
In the encoded streams we might not have all the information about the raw video stream, but when reencoding they end up being specified, even if those are default values. As vp8 decoders always output frames in some YUV color space we can ensure that when upstream doesn't specify any value in its caps we use the default one which is what we end up doing when decoding/reencoding anyway, so this way downstream (matroskamux in that case) doesn't need to be able to renegotiate (which it doesn't). Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1062>
This commit is contained in:
parent
d9b1e1e99f
commit
32d36d0e89
1 changed files with 63 additions and 1 deletions
|
@ -23,6 +23,7 @@
|
|||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <gst/video/video.h>
|
||||
#include "gstsmartencoder.h"
|
||||
|
||||
GST_DEBUG_CATEGORY_STATIC (smart_encoder_debug);
|
||||
|
@ -497,6 +498,66 @@ beach:
|
|||
return res;
|
||||
}
|
||||
|
||||
static GstCaps *
|
||||
smart_encoder_get_caps (GstSmartEncoder * self, GstCaps * original_caps)
|
||||
{
|
||||
gint i;
|
||||
GstCaps *caps, *outcaps;
|
||||
GstStructure *original_struct = gst_caps_get_structure (original_caps, 0);
|
||||
GstStructure *out_struct, *_struct;
|
||||
GstVideoInfo info;
|
||||
static const gchar *default_fields[] = {
|
||||
"pixel-aspect-ratio",
|
||||
"framerate",
|
||||
"interlace-mode",
|
||||
"colorimetry",
|
||||
"chroma-site",
|
||||
"multiview-mode",
|
||||
"multiview-flags",
|
||||
};
|
||||
|
||||
if (!gst_structure_has_name (original_struct, "video/x-vp8")) {
|
||||
|
||||
return gst_caps_ref (original_caps);
|
||||
}
|
||||
|
||||
/* VP8 is always decoded into YUV colorspaces and we support VP9 profiles
|
||||
* where only YUV is supported (0 and 2) so we ensure that all the
|
||||
* default fields for video/x-raw are set on the caps if none provided by
|
||||
* upstream. This allows us to allow renegotiating new caps downstream when
|
||||
* switching from no reencoding to reencoding making sure all the fields are
|
||||
* defined all the time
|
||||
*/
|
||||
caps = gst_caps_copy (original_caps);
|
||||
_struct = gst_caps_get_structure (caps, 0);
|
||||
gst_structure_set_name (_struct, "video/x-raw");
|
||||
gst_structure_set (_struct,
|
||||
"format", G_TYPE_STRING, "I420",
|
||||
"multiview-mode", G_TYPE_STRING, "mono",
|
||||
"multiview-flags", GST_TYPE_VIDEO_MULTIVIEW_FLAGSET,
|
||||
GST_VIDEO_MULTIVIEW_FLAGS_NONE, GST_FLAG_SET_MASK_EXACT, NULL);
|
||||
|
||||
gst_video_info_from_caps (&info, caps);
|
||||
gst_caps_unref (caps);
|
||||
caps = gst_video_info_to_caps (&info);
|
||||
_struct = gst_caps_get_structure (caps, 0);
|
||||
|
||||
outcaps = gst_caps_copy (original_caps);
|
||||
out_struct = gst_caps_get_structure (outcaps, 0);
|
||||
for (i = 0; i < G_N_ELEMENTS (default_fields); i++) {
|
||||
const gchar *field = default_fields[i];
|
||||
|
||||
if (!gst_structure_has_field (original_struct, field)) {
|
||||
const GValue *v = gst_structure_get_value (_struct, field);
|
||||
g_assert (v);
|
||||
gst_structure_set_value (out_struct, field, v);
|
||||
}
|
||||
}
|
||||
gst_caps_unref (caps);
|
||||
|
||||
return outcaps;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
smart_encoder_sink_event (GstPad * pad, GstObject * ghostpad, GstEvent * event)
|
||||
{
|
||||
|
@ -515,7 +576,8 @@ smart_encoder_sink_event (GstPad * pad, GstObject * ghostpad, GstEvent * event)
|
|||
if (self->original_caps)
|
||||
gst_caps_unref (self->original_caps);
|
||||
|
||||
self->original_caps = gst_caps_ref (caps);
|
||||
|
||||
self->original_caps = smart_encoder_get_caps (self, caps);
|
||||
self->push_original_caps = TRUE;
|
||||
gst_clear_event (&event);
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue