Skip to content

Commit

Permalink
[GStreamer] Implement "id" property for in-band audio, text and video…
Browse files Browse the repository at this point in the history
… tracks

https://bugs.webkit.org/show_bug.cgi?id=123901

Reviewed by Xabier Rodriguez-Calvar.

Support for container-specific-track-id GStreamer tag was implemented in:
https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6041

Which is scheduled to ship in GStreamer 1.24. The demuxers supported initially are DASH, qtdemux and
matroskademux, so we have coverage for the most common formats.

* LayoutTests/platform/glib/TestExpectations:
* Source/WebCore/platform/graphics/gstreamer/AudioTrackPrivateGStreamer.cpp:
(WebCore::AudioTrackPrivateGStreamer::updateConfigurationFromTags):
* Source/WebCore/platform/graphics/gstreamer/AudioTrackPrivateGStreamer.h:
* Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp:
(WebCore::ensureTextTrackDebugCategoryInitialized):
(WebCore::InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer):
(WebCore::InbandTextTrackPrivateGStreamer::tagsChanged):
* Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h:
* Source/WebCore/platform/graphics/gstreamer/VideoTrackPrivateGStreamer.cpp:
(WebCore::VideoTrackPrivateGStreamer::updateConfigurationFromTags):
* Source/WebCore/platform/graphics/gstreamer/VideoTrackPrivateGStreamer.h:

Canonical link: https://commits.webkit.org/274623@main
  • Loading branch information
philn committed Feb 14, 2024
1 parent b85b96c commit cb24c51
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 7 deletions.
2 changes: 1 addition & 1 deletion LayoutTests/platform/glib/TestExpectations
Original file line number Diff line number Diff line change
Expand Up @@ -1052,7 +1052,7 @@ webkit.org/b/213699 http/wpt/mediarecorder/MediaRecorder-AV-audio-video-dataavai
webkit.org/b/218317 media/media-source/media-source-trackid-change.html [ Failure ]
webkit.org/b/238201 media/media-source/media-mp4-hevc-bframes.html [ Failure ]

# GStreamer doesn't set the track's id to the container's value.
# GStreamer (< 1.24) doesn't set the track's id to the container's value.
webkit.org/b/265919 media/track/media-audio-track.html [ Failure ]
webkit.org/b/265919 media/track/media-source-audio-track.html [ Failure ]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "MediaPlayerPrivateGStreamer.h"
#include <gst/pbutils/pbutils.h>
#include <wtf/Scope.h>
#include <wtf/text/StringToIntegerConversion.h>

namespace WebCore {

Expand Down Expand Up @@ -94,6 +95,16 @@ void AudioTrackPrivateGStreamer::updateConfigurationFromTags(GRefPtr<GstTagList>
if (!tags)
return;

GUniqueOutPtr<char> trackIDString;
if (gst_tag_list_get_string(tags.get(), "container-specific-track-id", &trackIDString.outPtr())) {
if (auto trackID = WTF::parseInteger<TrackID>(StringView { trackIDString.get(), static_cast<unsigned>(strlen(trackIDString.get())) })) {
m_trackID = *trackID;
GST_DEBUG_OBJECT(objectForLogging(), "Audio track ID set from container-specific-track-id tag %" G_GUINT64_FORMAT, *m_trackID);
m_stringId = AtomString::number(static_cast<unsigned long long>(*m_trackID));
client()->idChanged(*m_trackID);
}
}

unsigned bitrate;
if (!gst_tag_list_get_uint(tags.get(), GST_TAG_BITRATE, &bitrate))
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class AudioTrackPrivateGStreamer final : public AudioTrackPrivate, public TrackP

int trackIndex() const final { return m_index; }

TrackID id() const final { return m_index; }
TrackID id() const final { return m_trackID.value_or(m_index); }
std::optional<AtomString> trackUID() const final { return m_stringId; }
AtomString label() const final { return m_label; }
AtomString language() const final { return m_language; }
Expand All @@ -74,6 +74,7 @@ class AudioTrackPrivateGStreamer final : public AudioTrackPrivate, public TrackP
AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, unsigned index, GstStream*);

WeakPtr<MediaPlayerPrivateGStreamer> m_player;
std::optional<TrackID> m_trackID;
};

} // namespace WebCore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,37 @@
#include "InbandTextTrackPrivateGStreamer.h"

#include <wtf/Lock.h>

GST_DEBUG_CATEGORY_EXTERN(webkit_media_player_debug);
#define GST_CAT_DEFAULT webkit_media_player_debug
#include <wtf/text/StringToIntegerConversion.h>

namespace WebCore {

GST_DEBUG_CATEGORY(webkit_text_track_debug);
#define GST_CAT_DEFAULT webkit_text_track_debug

static void ensureTextTrackDebugCategoryInitialized()
{
static std::once_flag debugRegisteredFlag;
std::call_once(debugRegisteredFlag, [] {
GST_DEBUG_CATEGORY_INIT(webkit_text_track_debug, "webkittexttrack", 0, "WebKit Text Track");
});
}

InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer(unsigned index, GRefPtr<GstPad>&& pad, bool shouldHandleStreamStartEvent)
: InbandTextTrackPrivate(CueFormat::WebVTT)
, TrackPrivateBaseGStreamer(TrackPrivateBaseGStreamer::TrackType::Text, this, index, WTFMove(pad), shouldHandleStreamStartEvent)
, m_kind(Kind::Subtitles)
{
ensureTextTrackDebugCategoryInitialized();
installUpdateConfigurationHandlers();
}

InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer(unsigned index, GstStream* stream)
: InbandTextTrackPrivate(CueFormat::WebVTT)
, TrackPrivateBaseGStreamer(TrackPrivateBaseGStreamer::TrackType::Text, this, index, stream)
{
ensureTextTrackDebugCategoryInitialized();
installUpdateConfigurationHandlers();

GST_INFO("Track %d got stream start for stream %s.", m_index, m_stringId.string().utf8().data());

GST_DEBUG("Stream %" GST_PTR_FORMAT, m_stream.get());
Expand All @@ -55,6 +69,22 @@ InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer(unsigned index,
m_kind = g_str_has_prefix(mediaType, "closedcaption/") ? Kind::Captions : Kind::Subtitles;
}

void InbandTextTrackPrivateGStreamer::tagsChanged(GRefPtr<GstTagList>&& tags)
{
if (!tags)
return;

GUniqueOutPtr<char> trackIDString;
if (gst_tag_list_get_string(tags.get(), "container-specific-track-id", &trackIDString.outPtr())) {
if (auto trackID = WTF::parseInteger<TrackID>(StringView { trackIDString.get(), static_cast<unsigned>(strlen(trackIDString.get())) })) {
m_trackID = *trackID;
GST_DEBUG_OBJECT(objectForLogging(), "Text track ID set from container-specific-track-id tag %" G_GUINT64_FORMAT, *m_trackID);
m_stringId = AtomString::number(static_cast<unsigned long long>(*m_trackID));
client()->idChanged(*m_trackID);
}
}
}

void InbandTextTrackPrivateGStreamer::handleSample(GRefPtr<GstSample> sample)
{
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,17 @@ class InbandTextTrackPrivateGStreamer : public InbandTextTrackPrivate, public Tr
}

Kind kind() const final { return m_kind; }
TrackID id() const final { return m_index; }
TrackID id() const final { return m_trackID.value_or(m_index); }
std::optional<AtomString> trackUID() const final { return m_stringId; }
AtomString label() const final { return m_label; }
AtomString language() const final { return m_language; }
int trackIndex() const final { return m_index; }

void handleSample(GRefPtr<GstSample>);

protected:
void tagsChanged(GRefPtr<GstTagList>&&) final;

private:
InbandTextTrackPrivateGStreamer(unsigned index, GRefPtr<GstPad>&&, bool shouldHandleStreamStartEvent);
InbandTextTrackPrivateGStreamer(unsigned index, GstStream*);
Expand All @@ -70,6 +73,7 @@ class InbandTextTrackPrivateGStreamer : public InbandTextTrackPrivate, public Tr
Vector<GRefPtr<GstSample>> m_pendingSamples WTF_GUARDED_BY_LOCK(m_sampleMutex);
Kind m_kind;
Lock m_sampleMutex;
std::optional<TrackID> m_trackID;
};

} // namespace WebCore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "VP9Utilities.h"
#include <gst/pbutils/pbutils.h>
#include <wtf/Scope.h>
#include <wtf/text/StringToIntegerConversion.h>

namespace WebCore {

Expand Down Expand Up @@ -95,6 +96,16 @@ void VideoTrackPrivateGStreamer::updateConfigurationFromTags(GRefPtr<GstTagList>
if (!tags)
return;

GUniqueOutPtr<char> trackIDString;
if (gst_tag_list_get_string(tags.get(), "container-specific-track-id", &trackIDString.outPtr())) {
if (auto trackID = WTF::parseInteger<TrackID>(StringView { trackIDString.get(), static_cast<unsigned>(strlen(trackIDString.get())) })) {
m_trackID = *trackID;
GST_DEBUG_OBJECT(objectForLogging(), "Video track ID set from container-specific-track-id tag %" G_GUINT64_FORMAT, *m_trackID);
m_stringId = AtomString::number(static_cast<unsigned long long>(*m_trackID));
client()->idChanged(*m_trackID);
}
}

unsigned bitrate;
if (!gst_tag_list_get_uint(tags.get(), GST_TAG_BITRATE, &bitrate))
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class VideoTrackPrivateGStreamer final : public VideoTrackPrivate, public TrackP

int trackIndex() const final { return m_index; }

TrackID id() const final { return m_index; }
TrackID id() const final { return m_trackID.value_or(m_index); }
std::optional<AtomString> trackUID() const final { return m_stringId; }
AtomString label() const final { return m_label; }
AtomString language() const final { return m_language; }
Expand All @@ -75,6 +75,7 @@ class VideoTrackPrivateGStreamer final : public VideoTrackPrivate, public TrackP
VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, unsigned index, GstStream*);

WeakPtr<MediaPlayerPrivateGStreamer> m_player;
std::optional<TrackID> m_trackID;
};

} // namespace WebCore
Expand Down

0 comments on commit cb24c51

Please sign in to comment.