matroskamux: Implement rotation tag support
Similar to qtmux, but for mkv and webm containers. Tested against other Gst elements and MPV. Note that the later apparently does not show correct results for flipped values. In particular the Yaw value seems to get ignored by many clients. Can be tested with: ``` gst-launch-1.0 \ videotestsrc num-buffers=90 ! \ taginject tags="image-orientation=rotate-270" ! \ capsfilter caps=video/x-raw,width=640,height=480,max-framerate=30/1 ! \ videoconvert ! \ queue ! \ vp8enc ! \ queue ! \ webmmux ! \ filesink location=./test.webm ``` Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8319>
This commit is contained in:
parent
b2702b6f10
commit
a7c2899990
@ -2693,9 +2693,81 @@ gst_matroska_mux_write_colour (GstMatroskaMux * mux,
|
||||
}
|
||||
|
||||
static void
|
||||
gst_matroska_mux_track_header (GstMatroskaMux * mux,
|
||||
GstMatroskaTrackContext * context)
|
||||
gst_matroska_mux_write_projection (GstMatroskaMux * mux,
|
||||
GstMatroskaMuxPad * pad)
|
||||
{
|
||||
GstEbmlWrite *ebml = mux->ebml_write;
|
||||
gchar *orientation;
|
||||
guint64 master;
|
||||
float yaw, roll;
|
||||
|
||||
if (!pad->tags ||
|
||||
!gst_tag_list_get_string (pad->tags, GST_TAG_IMAGE_ORIENTATION,
|
||||
&orientation)) {
|
||||
const GstTagList *global_tags;
|
||||
|
||||
global_tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (mux));
|
||||
if (!global_tags ||
|
||||
!gst_tag_list_get_string (global_tags, GST_TAG_IMAGE_ORIENTATION,
|
||||
&orientation))
|
||||
return;
|
||||
}
|
||||
|
||||
if (!g_strcmp0 ("rotate-0", orientation)) {
|
||||
yaw = 0.0;
|
||||
roll = 0.0;
|
||||
} else if (!g_strcmp0 ("rotate-90", orientation)) {
|
||||
yaw = 0.0;
|
||||
roll = -90.0;
|
||||
} else if (!g_strcmp0 ("rotate-180", orientation)) {
|
||||
yaw = 0.0;
|
||||
roll = 180.0;
|
||||
} else if (!g_strcmp0 ("rotate-270", orientation)) {
|
||||
yaw = 0.0;
|
||||
roll = 90.0;
|
||||
} else if (!g_strcmp0 ("flip-rotate-0", orientation)) {
|
||||
yaw = 180.0;
|
||||
roll = 0.0;
|
||||
} else if (!g_strcmp0 ("flip-rotate-90", orientation)) {
|
||||
yaw = 180.0;
|
||||
roll = -90.0;
|
||||
} else if (!g_strcmp0 ("flip-rotate-180", orientation)) {
|
||||
yaw = 180.0;
|
||||
roll = 180.0;
|
||||
} else if (!g_strcmp0 ("flip-rotate-270", orientation)) {
|
||||
yaw = 180.0;
|
||||
roll = 90.0;
|
||||
} else {
|
||||
GST_FIXME_OBJECT (mux, "Unsupported orientation %s", orientation);
|
||||
yaw = 0.0;
|
||||
roll = 0.0;
|
||||
}
|
||||
|
||||
/* Default projection, skip writing */
|
||||
if (yaw == 0.0 && roll == 0.0) {
|
||||
g_free (orientation);
|
||||
return;
|
||||
}
|
||||
|
||||
master = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_VIDEOPROJECTION);
|
||||
|
||||
gst_ebml_write_uint (ebml, GST_MATROSKA_ID_VIDEOPROJECTIONTYPE, 0);
|
||||
gst_ebml_write_float (ebml, GST_MATROSKA_ID_VIDEOPROJECTIONPOSEYAW, yaw);
|
||||
gst_ebml_write_float (ebml, GST_MATROSKA_ID_VIDEOPROJECTIONPOSEPITCH, 0.0);
|
||||
gst_ebml_write_float (ebml, GST_MATROSKA_ID_VIDEOPROJECTIONPOSEROLL, roll);
|
||||
|
||||
gst_ebml_write_master_finish (ebml, master);
|
||||
|
||||
GST_INFO_OBJECT (mux,
|
||||
"Wrote projection type: 0 yaw: %f pitch: 0.0 row: %f from tag: %s", yaw,
|
||||
roll, orientation);
|
||||
g_free (orientation);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_matroska_mux_track_header (GstMatroskaMux * mux, GstMatroskaMuxPad * pad)
|
||||
{
|
||||
GstMatroskaTrackContext *context = pad->track;
|
||||
GstEbmlWrite *ebml = mux->ebml_write;
|
||||
guint64 master;
|
||||
|
||||
@ -2757,7 +2829,10 @@ gst_matroska_mux_track_header (GstMatroskaMux * mux,
|
||||
gst_ebml_write_binary (ebml, GST_MATROSKA_ID_VIDEOCOLOURSPACE,
|
||||
(gpointer) & fcc_le, 4);
|
||||
}
|
||||
|
||||
gst_matroska_mux_write_colour (mux, videocontext);
|
||||
gst_matroska_mux_write_projection (mux, pad);
|
||||
|
||||
if (videocontext->multiview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
|
||||
guint64 stereo_mode = 0;
|
||||
|
||||
@ -3236,7 +3311,7 @@ gst_matroska_mux_start_file (GstMatroskaMux * mux)
|
||||
|
||||
pad->track->num = tracknum++;
|
||||
child = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_TRACKENTRY);
|
||||
gst_matroska_mux_track_header (mux, pad->track);
|
||||
gst_matroska_mux_track_header (mux, pad);
|
||||
gst_ebml_write_master_finish (ebml, child);
|
||||
/* some remaining pad/track setup */
|
||||
pad->default_duration_scaled =
|
||||
|
Loading…
x
Reference in New Issue
Block a user