Diff
Modified: trunk/Source/WebCore/ChangeLog (281740 => 281741)
--- trunk/Source/WebCore/ChangeLog 2021-08-29 09:27:02 UTC (rev 281740)
+++ trunk/Source/WebCore/ChangeLog 2021-08-29 09:50:28 UTC (rev 281741)
@@ -1,3 +1,47 @@
+2021-08-29 Philippe Normand <[email protected]>
+
+ [GStreamer] Track handling refactoring
+ https://bugs.webkit.org/show_bug.cgi?id=229497
+
+ Reviewed by Xabier Rodriguez-Calvar.
+
+ The TrackPrivateBaseGStreamer class now factors most of the common code used by its
+ sub-classes. The code style was modernised, some MSE-related dead code was removed from the
+ player. More could be done in the MSE AppendPipeline by making it rely on parsebin, but
+ that's another quest. The tracks created by the AppendPipeline were triggering track ID
+ mismatches between the player and those tracks, so a new flag was added in the constructor
+ of those to prevent stream-start event handling. Ideally that code should rely on GstStream,
+ that would remove the need of that flag.
+
+ No new tests, existing media tests cover this change.
+
+ * platform/graphics/gstreamer/AudioTrackPrivateGStreamer.cpp:
+ (WebCore::AudioTrackPrivateGStreamer::AudioTrackPrivateGStreamer):
+ * platform/graphics/gstreamer/AudioTrackPrivateGStreamer.h:
+ * platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp:
+ (WebCore::InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer):
+ * platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h:
+ (WebCore::InbandTextTrackPrivateGStreamer::create):
+ * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
+ (WebCore::MediaPlayerPrivateGStreamer::notifyPlayerOfTrack):
+ (WebCore::MediaPlayerPrivateGStreamer::handleTextSample):
+ (WebCore::MediaPlayerPrivateGStreamer::updateTracks):
+ * platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp:
+ (WebCore::TrackPrivateBaseGStreamer::generateUniquePlaybin2StreamID):
+ (WebCore::TrackPrivateBaseGStreamer::TrackPrivateBaseGStreamer):
+ (WebCore::TrackPrivateBaseGStreamer::setPad):
+ (WebCore::TrackPrivateBaseGStreamer::tagsChanged):
+ (WebCore::TrackPrivateBaseGStreamer::notifyTrackOfStreamChanged):
+ (WebCore::TrackPrivateBaseGStreamer::streamChanged):
+ * platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h:
+ (WebCore::TrackPrivateBaseGStreamer::setIndex):
+ (WebCore::TrackPrivateBaseGStreamer::stream):
+ * platform/graphics/gstreamer/VideoTrackPrivateGStreamer.cpp:
+ (WebCore::VideoTrackPrivateGStreamer::VideoTrackPrivateGStreamer):
+ * platform/graphics/gstreamer/VideoTrackPrivateGStreamer.h:
+ * platform/graphics/gstreamer/mse/AppendPipeline.cpp:
+ (WebCore::AppendPipeline::makeWebKitTrack):
+
2021-08-29 Joonghun Park <[email protected]>
Unreviewed. Remove the build warning below since r280958.
Modified: trunk/Source/WebCore/platform/graphics/gstreamer/AudioTrackPrivateGStreamer.cpp (281740 => 281741)
--- trunk/Source/WebCore/platform/graphics/gstreamer/AudioTrackPrivateGStreamer.cpp 2021-08-29 09:27:02 UTC (rev 281740)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/AudioTrackPrivateGStreamer.cpp 2021-08-29 09:50:28 UTC (rev 281741)
@@ -30,31 +30,26 @@
#include "AudioTrackPrivateGStreamer.h"
#include "MediaPlayerPrivateGStreamer.h"
-#include <glib-object.h>
namespace WebCore {
-AudioTrackPrivateGStreamer::AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstPad> pad)
- : TrackPrivateBaseGStreamer(this, index, pad)
+AudioTrackPrivateGStreamer::AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, unsigned index, GRefPtr<GstPad>&& pad, bool shouldHandleStreamStartEvent)
+ : TrackPrivateBaseGStreamer(TrackPrivateBaseGStreamer::TrackType::Audio, this, index, WTFMove(pad), shouldHandleStreamStartEvent)
, m_player(player)
{
- // FIXME: Get a real ID from the tkhd atom.
- m_id = "A" + String::number(index);
}
-AudioTrackPrivateGStreamer::AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstStream> stream)
- : TrackPrivateBaseGStreamer(this, index, stream)
+AudioTrackPrivateGStreamer::AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, unsigned index, GRefPtr<GstStream>&& stream)
+ : TrackPrivateBaseGStreamer(TrackPrivateBaseGStreamer::TrackType::Audio, this, index, WTFMove(stream))
, m_player(player)
{
- gint kind;
+ int kind;
auto tags = adoptGRef(gst_stream_get_tags(m_stream.get()));
- if (tags && gst_tag_list_get_int(tags.get(), "webkit-media-stream-kind", &kind) && kind == static_cast<int>(VideoTrackPrivate::Kind::Main)) {
- GstStreamFlags streamFlags = gst_stream_get_stream_flags(stream.get());
- gst_stream_set_stream_flags(stream.get(), static_cast<GstStreamFlags>(streamFlags | GST_STREAM_FLAG_SELECT));
+ if (tags && gst_tag_list_get_int(tags.get(), "webkit-media-stream-kind", &kind) && kind == static_cast<int>(AudioTrackPrivate::Kind::Main)) {
+ auto streamFlags = gst_stream_get_stream_flags(m_stream.get());
+ gst_stream_set_stream_flags(m_stream.get(), static_cast<GstStreamFlags>(streamFlags | GST_STREAM_FLAG_SELECT));
}
-
- m_id = gst_stream_get_stream_id(stream.get());
}
AudioTrackPrivate::Kind AudioTrackPrivateGStreamer::kind() const
Modified: trunk/Source/WebCore/platform/graphics/gstreamer/AudioTrackPrivateGStreamer.h (281740 => 281741)
--- trunk/Source/WebCore/platform/graphics/gstreamer/AudioTrackPrivateGStreamer.h 2021-08-29 09:27:02 UTC (rev 281740)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/AudioTrackPrivateGStreamer.h 2021-08-29 09:50:28 UTC (rev 281741)
@@ -28,9 +28,8 @@
#if ENABLE(VIDEO) && USE(GSTREAMER)
#include "AudioTrackPrivate.h"
-#include "GStreamerCommon.h"
#include "TrackPrivateBaseGStreamer.h"
-#include <gst/gst.h>
+
#include <wtf/WeakPtr.h>
namespace WebCore {
@@ -38,34 +37,33 @@
class AudioTrackPrivateGStreamer final : public AudioTrackPrivate, public TrackPrivateBaseGStreamer {
public:
- static Ref<AudioTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstPad> pad)
+ static Ref<AudioTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, unsigned index, GRefPtr<GstPad>&& pad, bool shouldHandleStreamStartEvent = true)
{
- return adoptRef(*new AudioTrackPrivateGStreamer(player, index, pad));
+ return adoptRef(*new AudioTrackPrivateGStreamer(player, index, WTFMove(pad), shouldHandleStreamStartEvent));
}
- static Ref<AudioTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstStream> stream)
+ static Ref<AudioTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, unsigned index, GRefPtr<GstStream>&& stream)
{
- return adoptRef(*new AudioTrackPrivateGStreamer(player, index, stream));
+ return adoptRef(*new AudioTrackPrivateGStreamer(player, index, WTFMove(stream)));
}
Kind kind() const final;
- void disconnect() override;
+ void disconnect() final;
- void setEnabled(bool) override;
- void setActive(bool enabled) override { setEnabled(enabled); }
+ void setEnabled(bool) final;
+ void setActive(bool enabled) final { setEnabled(enabled); }
- int trackIndex() const override { return m_index; }
+ int trackIndex() const final { return m_index; }
- AtomString id() const override { return m_id; }
- AtomString label() const override { return m_label; }
- AtomString language() const override { return m_language; }
+ AtomString id() const final { return m_id; }
+ AtomString label() const final { return m_label; }
+ AtomString language() const final { return m_language; }
private:
- AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, gint index, GRefPtr<GstPad>);
- AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, gint index, GRefPtr<GstStream>);
+ AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, unsigned index, GRefPtr<GstPad>&&, bool shouldHandleStreamStartEvent);
+ AudioTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, unsigned index, GRefPtr<GstStream>&&);
- AtomString m_id;
WeakPtr<MediaPlayerPrivateGStreamer> m_player;
};
Modified: trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp (281740 => 281741)
--- trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp 2021-08-29 09:27:02 UTC (rev 281740)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.cpp 2021-08-29 09:50:28 UTC (rev 281741)
@@ -29,10 +29,7 @@
#include "InbandTextTrackPrivateGStreamer.h"
-#include "GStreamerCommon.h"
-#include "Logging.h"
-#include <glib-object.h>
-#include <gst/gst.h>
+#include <wtf/Lock.h>
GST_DEBUG_CATEGORY_EXTERN(webkit_media_player_debug);
#define GST_CAT_DEFAULT webkit_media_player_debug
@@ -39,48 +36,26 @@
namespace WebCore {
-InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer(gint index, GRefPtr<GstPad> pad)
+InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer(unsigned index, GRefPtr<GstPad>&& pad, bool shouldHandleStreamStartEvent)
: InbandTextTrackPrivate(CueFormat::WebVTT)
- , TrackPrivateBaseGStreamer(this, index, pad)
+ , TrackPrivateBaseGStreamer(TrackPrivateBaseGStreamer::TrackType::Text, this, index, WTFMove(pad), shouldHandleStreamStartEvent)
, m_kind(Kind::Subtitles)
{
- m_id = "T" + String::number(index);
- m_eventProbe = gst_pad_add_probe(m_pad.get(), GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, [] (GstPad*, GstPadProbeInfo* info, gpointer userData) -> GstPadProbeReturn {
- auto* track = static_cast<InbandTextTrackPrivateGStreamer*>(userData);
- switch (GST_EVENT_TYPE(gst_pad_probe_info_get_event(info))) {
- case GST_EVENT_STREAM_START:
- track->streamChanged();
- break;
- default:
- break;
- }
- return GST_PAD_PROBE_OK;
- }, this, nullptr);
-
- notifyTrackOfStreamChanged();
}
-InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer(gint index, GRefPtr<GstStream> stream)
+InbandTextTrackPrivateGStreamer::InbandTextTrackPrivateGStreamer(unsigned index, GRefPtr<GstStream>&& stream)
: InbandTextTrackPrivate(CueFormat::WebVTT)
- , TrackPrivateBaseGStreamer(this, index, stream)
+ , TrackPrivateBaseGStreamer(TrackPrivateBaseGStreamer::TrackType::Text, this, index, WTFMove(stream))
{
- m_streamId = gst_stream_get_stream_id(stream.get());
- GST_INFO("Track %d got stream start for stream %s.", m_index, m_streamId.utf8().data());
+ m_id = gst_stream_get_stream_id(m_stream.get());
+ GST_INFO("Track %d got stream start for stream %s.", m_index, m_id.string().utf8().data());
- GST_DEBUG("Stream %" GST_PTR_FORMAT, stream.get());
- auto caps = adoptGRef(gst_stream_get_caps(stream.get()));
+ GST_DEBUG("Stream %" GST_PTR_FORMAT, m_stream.get());
+ auto caps = adoptGRef(gst_stream_get_caps(m_stream.get()));
const char* mediaType = capsMediaType(caps.get());
m_kind = g_str_has_prefix(mediaType, "closedcaption/") ? Kind::Captions : Kind::Subtitles;
}
-void InbandTextTrackPrivateGStreamer::disconnect()
-{
- if (m_pad)
- gst_pad_remove_probe(m_pad.get(), m_eventProbe);
-
- TrackPrivateBaseGStreamer::disconnect();
-}
-
void InbandTextTrackPrivateGStreamer::handleSample(GRefPtr<GstSample> sample)
{
{
@@ -94,14 +69,6 @@
});
}
-void InbandTextTrackPrivateGStreamer::streamChanged()
-{
- RefPtr<InbandTextTrackPrivateGStreamer> protectedThis(this);
- m_notifier->notify(MainThreadNotification::StreamChanged, [protectedThis] {
- protectedThis->notifyTrackOfStreamChanged();
- });
-}
-
void InbandTextTrackPrivateGStreamer::notifyTrackOfSample()
{
Vector<GRefPtr<GstSample> > samples;
@@ -130,19 +97,6 @@
}
}
-void InbandTextTrackPrivateGStreamer::notifyTrackOfStreamChanged()
-{
- GRefPtr<GstEvent> event = adoptGRef(gst_pad_get_sticky_event(m_pad.get(),
- GST_EVENT_STREAM_START, 0));
- if (!event)
- return;
-
- const gchar* streamId;
- gst_event_parse_stream_start(event.get(), &streamId);
- GST_INFO("Track %d got stream start for stream %s.", m_index, streamId);
- m_streamId = streamId;
-}
-
} // namespace WebCore
#endif // ENABLE(VIDEO) && USE(GSTREAMER)
Modified: trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h (281740 => 281741)
--- trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h 2021-08-29 09:27:02 UTC (rev 281740)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h 2021-08-29 09:50:28 UTC (rev 281741)
@@ -27,11 +27,9 @@
#if ENABLE(VIDEO) && USE(GSTREAMER)
-#include "GStreamerCommon.h"
#include "InbandTextTrackPrivate.h"
#include "TrackPrivateBaseGStreamer.h"
-#include <gst/gst.h>
-#include <wtf/Lock.h>
+#include <wtf/Forward.h>
namespace WebCore {
@@ -39,49 +37,38 @@
class InbandTextTrackPrivateGStreamer : public InbandTextTrackPrivate, public TrackPrivateBaseGStreamer {
public:
- static Ref<InbandTextTrackPrivateGStreamer> create(gint index, GRefPtr<GstPad> pad)
+ static Ref<InbandTextTrackPrivateGStreamer> create(unsigned index, GRefPtr<GstPad>&& pad, bool shouldHandleStreamStartEvent = true)
{
- return adoptRef(*new InbandTextTrackPrivateGStreamer(index, pad));
+ return adoptRef(*new InbandTextTrackPrivateGStreamer(index, WTFMove(pad), shouldHandleStreamStartEvent));
}
- static Ref<InbandTextTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer>, gint index, GRefPtr<GstPad> pad)
+ static Ref<InbandTextTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer>, unsigned index, GRefPtr<GstPad> pad)
{
- return create(index, pad);
+ return create(index, WTFMove(pad));
}
- static Ref<InbandTextTrackPrivateGStreamer> create(gint index, GRefPtr<GstStream> stream)
+ static Ref<InbandTextTrackPrivateGStreamer> create(unsigned index, GRefPtr<GstStream>&& stream)
{
- return adoptRef(*new InbandTextTrackPrivateGStreamer(index, stream));
+ return adoptRef(*new InbandTextTrackPrivateGStreamer(index, WTFMove(stream)));
}
- void disconnect() override;
+ Kind kind() const final { return m_kind; }
+ AtomString id() const final { return m_id; }
+ AtomString label() const final { return m_label; }
+ AtomString language() const final { return m_language; }
+ int trackIndex() const final { return m_index; }
- Kind kind() const override { return m_kind; }
-
- AtomString id() const override { return m_id; }
- AtomString label() const override { return m_label; }
- AtomString language() const override { return m_language; }
-
- int trackIndex() const override { return m_index; }
- String streamId() const { return m_streamId; }
-
void handleSample(GRefPtr<GstSample>);
private:
- InbandTextTrackPrivateGStreamer(gint index, GRefPtr<GstPad>);
- InbandTextTrackPrivateGStreamer(gint index, GRefPtr<GstStream>);
+ InbandTextTrackPrivateGStreamer(unsigned index, GRefPtr<GstPad>&&, bool shouldHandleStreamStartEvent);
+ InbandTextTrackPrivateGStreamer(unsigned index, GRefPtr<GstStream>&&);
- void streamChanged();
-
void notifyTrackOfSample();
- void notifyTrackOfStreamChanged();
- gulong m_eventProbe;
Vector<GRefPtr<GstSample>> m_pendingSamples WTF_GUARDED_BY_LOCK(m_sampleMutex);
- String m_streamId;
Kind m_kind;
Lock m_sampleMutex;
- AtomString m_id;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp (281740 => 281741)
--- trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp 2021-08-29 09:27:02 UTC (rev 281740)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp 2021-08-29 09:50:28 UTC (rev 281741)
@@ -990,25 +990,25 @@
if (UNLIKELY(!m_pipeline || !m_source))
return;
- ASSERT(m_isLegacyPlaybin || isMediaSource());
+ ASSERT(m_isLegacyPlaybin);
- enum TrackType { Audio = 0, Video = 1, Text = 2 };
+ using TrackType = TrackPrivateBaseGStreamer::TrackType;
Variant<HashMap<AtomString, RefPtr<AudioTrackPrivateGStreamer>>*, HashMap<AtomString, RefPtr<VideoTrackPrivateGStreamer>>*, HashMap<AtomString, RefPtr<InbandTextTrackPrivateGStreamer>>*> variantTracks = static_cast<HashMap<AtomString, RefPtr<TrackPrivateType>>*>(0);
auto type(static_cast<TrackType>(variantTracks.index()));
const char* typeName;
bool* hasType;
switch (type) {
- case Audio:
+ case TrackType::Audio:
typeName = "audio";
hasType = &m_hasAudio;
variantTracks = &m_audioTracks;
break;
- case Video:
+ case TrackType::Video:
typeName = "video";
hasType = &m_hasVideo;
variantTracks = &m_videoTracks;
break;
- case Text:
+ case TrackType::Text:
typeName = "text";
hasType = nullptr;
variantTracks = &m_textTracks;
@@ -1019,18 +1019,14 @@
HashMap<AtomString, RefPtr<TrackPrivateType>>& tracks = *get<HashMap<AtomString, RefPtr<TrackPrivateType>>*>(variantTracks);
// Ignore notifications after a EOS. We don't want the tracks to disappear when the video is finished.
- if (m_isEndReached && (type == Audio || type == Video))
+ if (m_isEndReached && (type == TrackType::Audio || type == TrackType::Video))
return;
unsigned numberOfTracks = 0;
- bool useMediaSource = isMediaSource();
-
StringPrintStream numberOfTracksProperty;
numberOfTracksProperty.printf("n-%s", typeName);
+ g_object_get(m_pipeline.get(), numberOfTracksProperty.toCString().data(), &numberOfTracks, nullptr);
- GstElement* element = useMediaSource ? m_source.get() : m_pipeline.get();
- g_object_get(element, numberOfTracksProperty.toCString().data(), &numberOfTracks, nullptr);
-
GST_INFO_OBJECT(pipeline(), "Media has %d %s tracks", numberOfTracks, typeName);
if (hasType) {
@@ -1039,17 +1035,11 @@
if (oldHasType != *hasType)
m_player->characteristicChanged();
- if (*hasType && type == Video)
+ if (*hasType && type == TrackType::Video)
m_player->sizeChanged();
}
- if (useMediaSource) {
- GST_DEBUG_OBJECT(pipeline(), "Tracks managed by source element. Bailing out now.");
- m_player->mediaEngineUpdated();
- return;
- }
-
- Vector<String> validStreams;
+ Vector<AtomString> validStreams;
StringPrintStream getPadProperty;
getPadProperty.printf("get-%s-pad", typeName);
@@ -1058,7 +1048,9 @@
g_signal_emit_by_name(m_pipeline.get(), getPadProperty.toCString().data(), i, &pad.outPtr(), nullptr);
ASSERT(pad);
- String streamId = String(typeName).substring(0, 1).convertToASCIIUppercase() + String::number(i);
+ // The pad might not have a sticky stream-start event yet, so we can't use
+ // gst_pad_get_stream_id() here.
+ auto streamId = TrackPrivateBaseGStreamer::generateUniquePlaybin2StreamID(type, i);
validStreams.append(streamId);
if (i < tracks.size()) {
@@ -1073,8 +1065,8 @@
}
}
- auto track = TrackPrivateType::create(makeWeakPtr(*this), i, pad);
- if (!track->trackIndex() && (type == Audio || type == Video))
+ auto track = TrackPrivateType::create(makeWeakPtr(*this), i, WTFMove(pad));
+ if (!track->trackIndex() && (type == TrackType::Audio || type == TrackType::Video))
track->setActive(true);
ASSERT(streamId == track->id());
tracks.add(streamId, track.copyRef());
@@ -1081,9 +1073,15 @@
Variant<AudioTrackPrivate&, VideoTrackPrivate&, InbandTextTrackPrivate&> variantTrack(track.get());
switch (variantTrack.index()) {
- case Audio: m_player->addAudioTrack(get<AudioTrackPrivate&>(variantTrack)); break;
- case Video: m_player->addVideoTrack(get<VideoTrackPrivate&>(variantTrack)); break;
- case Text: m_player->addTextTrack(get<InbandTextTrackPrivate&>(variantTrack)); break;
+ case TrackType::Audio:
+ m_player->addAudioTrack(get<AudioTrackPrivate&>(variantTrack));
+ break;
+ case TrackType::Video:
+ m_player->addVideoTrack(get<VideoTrackPrivate&>(variantTrack));
+ break;
+ case TrackType::Text:
+ m_player->addTextTrack(get<InbandTextTrackPrivate&>(variantTrack));
+ break;
}
}
@@ -1143,7 +1141,7 @@
void MediaPlayerPrivateGStreamer::handleTextSample(GstSample* sample, const char* streamId)
{
for (auto& track : m_textTracks.values()) {
- if (!strcmp(track->streamId().utf8().data(), streamId)) {
+ if (!strcmp(track->id().string().utf8().data(), streamId)) {
track->handleSample(sample);
return;
}
@@ -1449,8 +1447,8 @@
unsigned videoTrackIndex = 0;
unsigned textTrackIndex = 0;
-#define CREATE_TRACK(type, Type) G_STMT_START { \
- RefPtr<Type##TrackPrivateGStreamer> track = Type##TrackPrivateGStreamer::create(makeWeakPtr(*this), type##TrackIndex, stream); \
+#define CREATE_TRACK(type, Type) G_STMT_START { \
+ RefPtr<Type##TrackPrivateGStreamer> track = Type##TrackPrivateGStreamer::create(makeWeakPtr(*this), type##TrackIndex, WTFMove(stream)); \
auto trackId = track->id(); \
if (!type##TrackIndex) { \
m_wanted##Type##StreamId = trackId; \
@@ -1463,11 +1461,11 @@
} G_STMT_END
for (unsigned i = 0; i < length; i++) {
- auto* stream = gst_stream_collection_get_stream(streamCollection.get(), i);
- String streamId(gst_stream_get_stream_id(stream));
- auto type = gst_stream_get_stream_type(stream);
+ GRefPtr<GstStream> stream = gst_stream_collection_get_stream(streamCollection.get(), i);
+ const char* streamId = gst_stream_get_stream_id(stream.get());
+ auto type = gst_stream_get_stream_type(stream.get());
- GST_DEBUG_OBJECT(pipeline(), "Inspecting %s track with ID %s", gst_stream_type_get_name(type), streamId.utf8().data());
+ GST_DEBUG_OBJECT(pipeline(), "Inspecting %s track with ID %s", gst_stream_type_get_name(type), streamId);
if (type & GST_STREAM_TYPE_AUDIO) {
CREATE_TRACK(audio, Audio);
@@ -1475,11 +1473,11 @@
} else if (type & GST_STREAM_TYPE_VIDEO && m_player->isVideoPlayer())
CREATE_TRACK(video, Video);
else if (type & GST_STREAM_TYPE_TEXT && !useMediaSource) {
- auto track = InbandTextTrackPrivateGStreamer::create(textTrackIndex++, stream);
+ auto track = InbandTextTrackPrivateGStreamer::create(textTrackIndex++, WTFMove(stream));
m_textTracks.add(streamId, track.copyRef());
m_player->addTextTrack(track.get());
} else
- GST_WARNING("Unknown track type found for stream %s", streamId.utf8().data());
+ GST_WARNING("Unknown track type found for stream %s", streamId);
}
m_hasAudio = !m_audioTracks.isEmpty();
Modified: trunk/Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp (281740 => 281741)
--- trunk/Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp 2021-08-29 09:27:02 UTC (rev 281740)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.cpp 2021-08-29 09:50:28 UTC (rev 281741)
@@ -30,12 +30,8 @@
#include "TrackPrivateBaseGStreamer.h"
#include "GStreamerCommon.h"
-#include "Logging.h"
#include "TrackPrivateBase.h"
-#include <glib-object.h>
-#include <gst/gst.h>
#include <gst/tag/tag.h>
-#include <wtf/glib/GUniquePtr.h>
#include <wtf/text/CString.h>
GST_DEBUG_CATEGORY_EXTERN(webkit_media_player_debug);
@@ -43,6 +39,25 @@
namespace WebCore {
+AtomString TrackPrivateBaseGStreamer::generateUniquePlaybin2StreamID(TrackType trackType, unsigned index)
+{
+ auto prefix = [trackType]() -> char {
+ switch (trackType) {
+ case TrackPrivateBaseGStreamer::TrackType::Audio:
+ return 'A';
+ case TrackPrivateBaseGStreamer::TrackType::Video:
+ return 'V';
+ case TrackPrivateBaseGStreamer::TrackType::Text:
+ return 'T';
+ default:
+ ASSERT_NOT_REACHED();
+ return 'U';
+ }
+ }();
+
+ return makeString(prefix, index);
+}
+
static GRefPtr<GstPad> findBestUpstreamPad(GRefPtr<GstPad> pad)
{
GRefPtr<GstPad> sinkPad = pad;
@@ -56,11 +71,12 @@
return sinkPad;
}
-TrackPrivateBaseGStreamer::TrackPrivateBaseGStreamer(TrackPrivateBase* owner, gint index, GRefPtr<GstPad> pad)
+TrackPrivateBaseGStreamer::TrackPrivateBaseGStreamer(TrackType type, TrackPrivateBase* owner, unsigned index, GRefPtr<GstPad>&& pad, bool shouldHandleStreamStartEvent)
: m_notifier(MainThreadNotifier<MainThreadNotification>::create())
, m_index(index)
- , m_eventProbe(0)
+ , m_type(type)
, m_owner(owner)
+ , m_shouldHandleStreamStartEvent(shouldHandleStreamStartEvent)
{
setPad(WTFMove(pad));
ASSERT(m_pad);
@@ -69,14 +85,15 @@
tagsChanged();
}
-TrackPrivateBaseGStreamer::TrackPrivateBaseGStreamer(TrackPrivateBase* owner, gint index, GRefPtr<GstStream> stream)
+TrackPrivateBaseGStreamer::TrackPrivateBaseGStreamer(TrackType type, TrackPrivateBase* owner, unsigned index, GRefPtr<GstStream>&& stream)
: m_notifier(MainThreadNotifier<MainThreadNotification>::create())
, m_index(index)
- , m_stream(stream)
- , m_eventProbe(0)
+ , m_stream(WTFMove(stream))
+ , m_type(type)
, m_owner(owner)
{
ASSERT(m_stream);
+ m_id = gst_stream_get_stream_id(m_stream.get());
// We can't call notifyTrackOfTagsChanged() directly, because we need tagsChanged() to setup m_tags.
tagsChanged();
@@ -89,6 +106,8 @@
m_pad = WTFMove(pad);
m_bestUpstreamPad = findBestUpstreamPad(m_pad);
+ m_id = generateUniquePlaybin2StreamID(m_type, m_index);
+
m_eventProbe = gst_pad_add_probe(m_bestUpstreamPad.get(), GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, [] (GstPad*, GstPadProbeInfo* info, gpointer userData) -> GstPadProbeReturn {
auto* track = static_cast<TrackPrivateBaseGStreamer*>(userData);
switch (GST_EVENT_TYPE(gst_pad_probe_info_get_event(info))) {
@@ -95,6 +114,10 @@
case GST_EVENT_TAG:
tagsChangedCallback(track);
break;
+ case GST_EVENT_STREAM_START:
+ if (track->m_shouldHandleStreamStartEvent)
+ track->streamChanged();
+ break;
default:
break;
}
@@ -163,7 +186,9 @@
m_tags.swap(tags);
}
- m_notifier->notify(MainThreadNotification::TagsChanged, [this] { notifyTrackOfTagsChanged(); });
+ m_notifier->notify(MainThreadNotification::TagsChanged, [this] {
+ notifyTrackOfTagsChanged();
+ });
}
bool TrackPrivateBaseGStreamer::getLanguageCode(GstTagList* tags, AtomString& value)
@@ -220,6 +245,23 @@
client->languageChanged(m_language);
}
+void TrackPrivateBaseGStreamer::notifyTrackOfStreamChanged()
+{
+ GUniquePtr<char> streamId(gst_pad_get_stream_id(m_pad.get()));
+ if (!streamId)
+ return;
+
+ GST_INFO("Track %d got stream start for stream %s.", m_index, streamId.get());
+ m_id = streamId.get();
+}
+
+void TrackPrivateBaseGStreamer::streamChanged()
+{
+ m_notifier->notify(MainThreadNotification::StreamChanged, [this] {
+ notifyTrackOfStreamChanged();
+ });
+}
+
} // namespace WebCore
#endif // ENABLE(VIDEO) && USE(GSTREAMER)
Modified: trunk/Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h (281740 => 281741)
--- trunk/Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h 2021-08-29 09:27:02 UTC (rev 281740)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/TrackPrivateBaseGStreamer.h 2021-08-29 09:50:28 UTC (rev 281741)
@@ -48,6 +48,8 @@
Unknown
};
+ WEBCORE_EXPORT static AtomString generateUniquePlaybin2StreamID(TrackType, unsigned index);
+
GstPad* pad() const { return m_pad.get(); }
void setPad(GRefPtr<GstPad>&&);
@@ -55,12 +57,9 @@
virtual void setActive(bool) { }
- void setIndex(int index) { m_index = index; }
+ void setIndex(unsigned index) { m_index = index; }
- GstStream* stream()
- {
- return m_stream.get();
- }
+ GstStream* stream() { return m_stream.get(); }
// Used for MSE, where the initial caps of the pad are relevant for initializing the matching pad in the
// playback pipeline.
@@ -68,10 +67,11 @@
const GRefPtr<GstCaps>& initialCaps() { return m_initialCaps; }
protected:
- TrackPrivateBaseGStreamer(TrackPrivateBase* owner, gint index, GRefPtr<GstPad>);
- TrackPrivateBaseGStreamer(TrackPrivateBase* owner, gint index, GRefPtr<GstStream>);
+ TrackPrivateBaseGStreamer(TrackType, TrackPrivateBase*, unsigned index, GRefPtr<GstPad>&&, bool shouldHandleStreamStartEvent);
+ TrackPrivateBaseGStreamer(TrackType, TrackPrivateBase*, unsigned index, GRefPtr<GstStream>&&);
void notifyTrackOfTagsChanged();
+ void notifyTrackOfStreamChanged();
enum MainThreadNotification {
TagsChanged = 1 << 1,
@@ -80,13 +80,14 @@
};
Ref<MainThreadNotifier<MainThreadNotification>> m_notifier;
- gint m_index;
+ unsigned m_index;
AtomString m_label;
AtomString m_language;
+ AtomString m_id;
GRefPtr<GstPad> m_pad;
GRefPtr<GstPad> m_bestUpstreamPad;
GRefPtr<GstStream> m_stream;
- gulong m_eventProbe;
+ unsigned long m_eventProbe { 0 };
GRefPtr<GstCaps> m_initialCaps;
private:
@@ -95,14 +96,18 @@
template<class StringType>
bool getTag(GstTagList* tags, const gchar* tagName, StringType& value);
+ void streamChanged();
+
static void activeChangedCallback(TrackPrivateBaseGStreamer*);
static void tagsChangedCallback(TrackPrivateBaseGStreamer*);
void tagsChanged();
+ TrackType m_type;
TrackPrivateBase* m_owner;
Lock m_tagMutex;
GRefPtr<GstTagList> m_tags;
+ bool m_shouldHandleStreamStartEvent { true };
};
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/gstreamer/VideoTrackPrivateGStreamer.cpp (281740 => 281741)
--- trunk/Source/WebCore/platform/graphics/gstreamer/VideoTrackPrivateGStreamer.cpp 2021-08-29 09:27:02 UTC (rev 281740)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/VideoTrackPrivateGStreamer.cpp 2021-08-29 09:50:28 UTC (rev 281741)
@@ -30,31 +30,26 @@
#include "VideoTrackPrivateGStreamer.h"
#include "MediaPlayerPrivateGStreamer.h"
-#include <glib-object.h>
namespace WebCore {
-VideoTrackPrivateGStreamer::VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstPad> pad)
- : TrackPrivateBaseGStreamer(this, index, pad)
+VideoTrackPrivateGStreamer::VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, unsigned index, GRefPtr<GstPad>&& pad, bool shouldHandleStreamStartEvent)
+ : TrackPrivateBaseGStreamer(TrackPrivateBaseGStreamer::TrackType::Video, this, index, WTFMove(pad), shouldHandleStreamStartEvent)
, m_player(player)
{
- // FIXME: Get a real ID from the tkhd atom.
- m_id = "V" + String::number(index);
}
-VideoTrackPrivateGStreamer::VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstStream> stream)
- : TrackPrivateBaseGStreamer(this, index, stream)
+VideoTrackPrivateGStreamer::VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer> player, unsigned index, GRefPtr<GstStream>&& stream)
+ : TrackPrivateBaseGStreamer(TrackPrivateBaseGStreamer::TrackType::Video, this, index, WTFMove(stream))
, m_player(player)
{
- gint kind;
+ int kind;
auto tags = adoptGRef(gst_stream_get_tags(m_stream.get()));
if (tags && gst_tag_list_get_int(tags.get(), "webkit-media-stream-kind", &kind) && kind == static_cast<int>(VideoTrackPrivate::Kind::Main)) {
- GstStreamFlags streamFlags = gst_stream_get_stream_flags(stream.get());
- gst_stream_set_stream_flags(stream.get(), static_cast<GstStreamFlags>(streamFlags | GST_STREAM_FLAG_SELECT));
+ auto streamFlags = gst_stream_get_stream_flags(m_stream.get());
+ gst_stream_set_stream_flags(m_stream.get(), static_cast<GstStreamFlags>(streamFlags | GST_STREAM_FLAG_SELECT));
}
-
- m_id = gst_stream_get_stream_id(stream.get());
}
VideoTrackPrivate::Kind VideoTrackPrivateGStreamer::kind() const
Modified: trunk/Source/WebCore/platform/graphics/gstreamer/VideoTrackPrivateGStreamer.h (281740 => 281741)
--- trunk/Source/WebCore/platform/graphics/gstreamer/VideoTrackPrivateGStreamer.h 2021-08-29 09:27:02 UTC (rev 281740)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/VideoTrackPrivateGStreamer.h 2021-08-29 09:50:28 UTC (rev 281741)
@@ -31,7 +31,6 @@
#include "TrackPrivateBaseGStreamer.h"
#include "VideoTrackPrivate.h"
-#include <gst/gst.h>
#include <wtf/WeakPtr.h>
namespace WebCore {
@@ -39,34 +38,33 @@
class VideoTrackPrivateGStreamer final : public VideoTrackPrivate, public TrackPrivateBaseGStreamer {
public:
- static Ref<VideoTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstPad> pad)
+ static Ref<VideoTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, unsigned index, GRefPtr<GstPad>&& pad, bool shouldHandleStreamStartEvent = true)
{
- return adoptRef(*new VideoTrackPrivateGStreamer(player, index, pad));
+ return adoptRef(*new VideoTrackPrivateGStreamer(player, index, WTFMove(pad), shouldHandleStreamStartEvent));
}
- static Ref<VideoTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, gint index, GRefPtr<GstStream> stream)
+ static Ref<VideoTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer> player, unsigned index, GRefPtr<GstStream>&& stream)
{
- return adoptRef(*new VideoTrackPrivateGStreamer(player, index, stream));
+ return adoptRef(*new VideoTrackPrivateGStreamer(player, index, WTFMove(stream)));
}
Kind kind() const final;
- void disconnect() override;
+ void disconnect() final;
- void setSelected(bool) override;
- void setActive(bool enabled) override { setSelected(enabled); }
+ void setSelected(bool) final;
+ void setActive(bool enabled) final { setSelected(enabled); }
- int trackIndex() const override { return m_index; }
+ int trackIndex() const final { return m_index; }
- AtomString id() const override { return m_id; }
- AtomString label() const override { return m_label; }
- AtomString language() const override { return m_language; }
+ AtomString id() const final { return m_id; }
+ AtomString label() const final { return m_label; }
+ AtomString language() const final { return m_language; }
private:
- VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, gint index, GRefPtr<GstPad>);
- VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, gint index, GRefPtr<GstStream>);
+ VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, unsigned index, GRefPtr<GstPad>&&, bool shouldHandleStreamStartEvent);
+ VideoTrackPrivateGStreamer(WeakPtr<MediaPlayerPrivateGStreamer>, unsigned index, GRefPtr<GstStream>&&);
- AtomString m_id;
WeakPtr<MediaPlayerPrivateGStreamer> m_player;
};
Modified: trunk/Source/WebCore/platform/graphics/gstreamer/mse/AppendPipeline.cpp (281740 => 281741)
--- trunk/Source/WebCore/platform/graphics/gstreamer/mse/AppendPipeline.cpp 2021-08-29 09:27:02 UTC (rev 281740)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/mse/AppendPipeline.cpp 2021-08-29 09:50:28 UTC (rev 281741)
@@ -753,21 +753,22 @@
RefPtr<WebCore::TrackPrivateBase> track;
TrackPrivateBaseGStreamer* gstreamerTrack = nullptr;
// FIXME: AudioTrackPrivateGStreamer etc. should probably use pads of the playback pipeline rather than the append pipeline.
+ GRefPtr<GstPad> pad(appendPipelineTrack.appsinkPad);
switch (appendPipelineTrack.streamType) {
case StreamType::Audio: {
- auto specificTrack = AudioTrackPrivateGStreamer::create(makeWeakPtr(m_playerPrivate), trackIndex, appendPipelineTrack.appsinkPad);
+ auto specificTrack = AudioTrackPrivateGStreamer::create(makeWeakPtr(m_playerPrivate), trackIndex, WTFMove(pad), false);
gstreamerTrack = specificTrack.ptr();
track = makeRefPtr(static_cast<TrackPrivateBase*>(specificTrack.ptr()));
break;
}
case StreamType::Video: {
- auto specificTrack = VideoTrackPrivateGStreamer::create(makeWeakPtr(m_playerPrivate), trackIndex, appendPipelineTrack.appsinkPad);
+ auto specificTrack = VideoTrackPrivateGStreamer::create(makeWeakPtr(m_playerPrivate), trackIndex, WTFMove(pad), false);
gstreamerTrack = specificTrack.ptr();
track = makeRefPtr(static_cast<TrackPrivateBase*>(specificTrack.ptr()));
break;
}
case StreamType::Text: {
- auto specificTrack = InbandTextTrackPrivateGStreamer::create(trackIndex, appendPipelineTrack.appsinkPad);
+ auto specificTrack = InbandTextTrackPrivateGStreamer::create(trackIndex, WTFMove(pad), false);
gstreamerTrack = specificTrack.ptr();
track = makeRefPtr(static_cast<TrackPrivateBase*>(specificTrack.ptr()));
break;