Changeset 278981 in webkit


Ignore:
Timestamp:
Jun 17, 2021, 5:00:47 AM (4 years ago)
Author:
eocanha@igalia.com
Message:

[GStreamer] Refactor MediaPlayerPrivateGStreamer::notifyPlayerOf*
https://bugs.webkit.org/show_bug.cgi?id=204686

Reviewed by Philippe Normand.

Refactored the notifyPlayerOf{Audio,Video,Text} family of methods into a single notifyPlayerOfTrack() one.
Some Variant variables are needed in order to make several incompatible types work together and to auto-detect the type of track as an enum.

Covered by existing tests.

  • platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h:

(WebCore::InbandTextTrackPrivateGStreamer::create): Added method with a signature similar to the ones used by {Audio,Video}TrackPrivateGStreamer, so that it fits into the notifyPlayerOfTrack() template code.

  • platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:

(WebCore::MediaPlayerPrivateGStreamer::notifyPlayerOfTrack): Template method that unifies the old notifyPlayerOf{Audio,Video,Text}() implementations.
(WebCore::MediaPlayerPrivateGStreamer::notifyPlayerOfAudio): Deleted. Refactored into notifyPlayerOfTrack().
(WebCore::MediaPlayerPrivateGStreamer::notifyPlayerOfVideo): Ditto.
(WebCore::MediaPlayerPrivateGStreamer::notifyPlayerOfText): Ditto.
(WebCore::MediaPlayerPrivateGStreamer::audioChangedCallback): Call the new notifyPlayerOfTrack() refactored implementation.
(WebCore::MediaPlayerPrivateGStreamer::textChangedCallback): Ditto.
(WebCore::MediaPlayerPrivateGStreamer::videoChangedCallback): Ditto.
(WebCore::MediaPlayerPrivateGStreamer::purgeInvalidAudioTracks): Deleted. Now implemented directly inside notifyPlayerOfTrack().
(WebCore::MediaPlayerPrivateGStreamer::purgeInvalidVideoTracks): Ditto.
(WebCore::MediaPlayerPrivateGStreamer::purgeInvalidTextTracks): Ditto.

  • platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h: Deleted notifyPlayerOf{Audio,Video,Text}(), added notifyPlayerOfTrack(), deleted purgeInvalid{Audio,Video,Text}Tracks().
Location:
trunk/Source/WebCore
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r278979 r278981  
     12021-06-17  Enrique Ocaña González  <eocanha@igalia.com>
     2
     3        [GStreamer] Refactor MediaPlayerPrivateGStreamer::notifyPlayerOf*
     4        https://bugs.webkit.org/show_bug.cgi?id=204686
     5
     6        Reviewed by Philippe Normand.
     7
     8        Refactored the notifyPlayerOf{Audio,Video,Text} family of methods into a single notifyPlayerOfTrack() one.
     9        Some Variant variables are needed in order to make several incompatible types work together and to auto-detect the type of track as an enum.
     10
     11        Covered by existing tests.
     12
     13        * platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h:
     14        (WebCore::InbandTextTrackPrivateGStreamer::create): Added method with a signature similar to the ones used by {Audio,Video}TrackPrivateGStreamer, so that it fits into the notifyPlayerOfTrack() template code.
     15        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
     16        (WebCore::MediaPlayerPrivateGStreamer::notifyPlayerOfTrack): Template method that unifies the old notifyPlayerOf{Audio,Video,Text}() implementations.
     17        (WebCore::MediaPlayerPrivateGStreamer::notifyPlayerOfAudio): Deleted. Refactored into notifyPlayerOfTrack().
     18        (WebCore::MediaPlayerPrivateGStreamer::notifyPlayerOfVideo): Ditto.
     19        (WebCore::MediaPlayerPrivateGStreamer::notifyPlayerOfText): Ditto.
     20        (WebCore::MediaPlayerPrivateGStreamer::audioChangedCallback): Call the new notifyPlayerOfTrack() refactored implementation.
     21        (WebCore::MediaPlayerPrivateGStreamer::textChangedCallback): Ditto.
     22        (WebCore::MediaPlayerPrivateGStreamer::videoChangedCallback): Ditto.
     23        (WebCore::MediaPlayerPrivateGStreamer::purgeInvalidAudioTracks): Deleted. Now implemented directly inside notifyPlayerOfTrack().
     24        (WebCore::MediaPlayerPrivateGStreamer::purgeInvalidVideoTracks): Ditto.
     25        (WebCore::MediaPlayerPrivateGStreamer::purgeInvalidTextTracks): Ditto.
     26        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h: Deleted notifyPlayerOf{Audio,Video,Text}(), added notifyPlayerOfTrack(), deleted purgeInvalid{Audio,Video,Text}Tracks().
     27
    1282021-06-17  Commit Queue  <commit-queue@webkit.org>
    229
  • trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h

    r278979 r278981  
    4545    }
    4646
     47    static Ref<InbandTextTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer>, gint index, GRefPtr<GstPad> pad)
     48    {
     49        return create(index, pad);
     50    }
     51
    4752    static Ref<InbandTextTrackPrivateGStreamer> create(gint index, GRefPtr<GstStream> stream)
    4853    {
  • trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp

    r278979 r278981  
    963963}
    964964
    965 void MediaPlayerPrivateGStreamer::notifyPlayerOfVideo()
     965template <typename TrackPrivateType>
     966void MediaPlayerPrivateGStreamer::notifyPlayerOfTrack()
    966967{
    967968    if (UNLIKELY(!m_pipeline || !m_source))
     
    969970
    970971    ASSERT(m_isLegacyPlaybin || isMediaSource());
     972    ASSERT(typeName);
     973
     974    enum TrackType { Audio = 0, Video = 1, Text = 2 };
     975    Variant<HashMap<AtomString, RefPtr<AudioTrackPrivateGStreamer>>*, HashMap<AtomString, RefPtr<VideoTrackPrivateGStreamer>>*, HashMap<AtomString, RefPtr<InbandTextTrackPrivateGStreamer>>*> variantTracks = static_cast<HashMap<AtomString, RefPtr<TrackPrivateType>>*>(0);
     976    auto type(static_cast<TrackType>(variantTracks.index()));
     977    const char* typeName;
     978    bool* hasType;
     979    switch (type) {
     980    case Audio:
     981        typeName = "audio";
     982        hasType = &m_hasAudio;
     983        variantTracks = &m_audioTracks;
     984        break;
     985    case Video:
     986        typeName = "video";
     987        hasType = &m_hasVideo;
     988        variantTracks = &m_videoTracks;
     989        break;
     990    case Text:
     991        typeName = "text";
     992        hasType = nullptr;
     993        variantTracks = &m_textTracks;
     994        break;
     995    default:
     996        ASSERT_NOT_REACHED();
     997    }
     998    HashMap<AtomString, RefPtr<TrackPrivateType>>& tracks = *get<HashMap<AtomString, RefPtr<TrackPrivateType>>*>(variantTracks);
    971999
    9721000    // Ignore notifications after a EOS. We don't want the tracks to disappear when the video is finished.
    973     if (m_isEndReached)
    974         return;
    975 
    976     unsigned numTracks = 0;
     1001    if (m_isEndReached && (type == Audio || type == Video))
     1002        return;
     1003
     1004    unsigned numberOfTracks = 0;
    9771005    bool useMediaSource = isMediaSource();
     1006
     1007    StringPrintStream numberOfTracksProperty;
     1008    numberOfTracksProperty.printf("n-%s", typeName);
     1009
    9781010    GstElement* element = useMediaSource ? m_source.get() : m_pipeline.get();
    979     g_object_get(element, "n-video", &numTracks, nullptr);
    980 
    981     GST_INFO_OBJECT(pipeline(), "Media has %d video tracks", numTracks);
    982 
    983     bool oldHasVideo = m_hasVideo;
    984     m_hasVideo = numTracks > 0;
    985     if (oldHasVideo != m_hasVideo)
    986         m_player->characteristicChanged();
    987 
    988     if (m_hasVideo)
    989         m_player->sizeChanged();
     1011    g_object_get(element, numberOfTracksProperty.toCString().data(), &numberOfTracks, nullptr);
     1012
     1013    GST_INFO_OBJECT(pipeline(), "Media has %d %s tracks", numberOfTracks, typeName);
     1014
     1015    if (hasType) {
     1016        bool oldHasType = *hasType;
     1017        *hasType = numberOfTracks > 0;
     1018        if (oldHasType != *hasType)
     1019            m_player->characteristicChanged();
     1020
     1021        if (*hasType && type == Video)
     1022            m_player->sizeChanged();
     1023    }
    9901024
    9911025    if (useMediaSource) {
     
    9951029    }
    9961030
    997     Vector<String> validVideoStreams;
    998     for (unsigned i = 0; i < numTracks; ++i) {
     1031    Vector<String> validStreams;
     1032    StringPrintStream getPadProperty;
     1033    getPadProperty.printf("get-%s-pad", typeName);
     1034
     1035    for (unsigned i = 0; i < numberOfTracks; ++i) {
    9991036        GRefPtr<GstPad> pad;
    1000         g_signal_emit_by_name(m_pipeline.get(), "get-video-pad", i, &pad.outPtr(), nullptr);
     1037        g_signal_emit_by_name(m_pipeline.get(), getPadProperty.toCString().data(), i, &pad.outPtr(), nullptr);
    10011038        ASSERT(pad);
    10021039
    1003         String streamId = "V" + String::number(i);
    1004         validVideoStreams.append(streamId);
    1005         if (i < m_videoTracks.size()) {
    1006             RefPtr<VideoTrackPrivateGStreamer> existingTrack = m_videoTracks.get(streamId);
     1040        String streamId = String(typeName).substring(0, 1).convertToASCIIUppercase() + String::number(i);
     1041        validStreams.append(streamId);
     1042
     1043        if (i < tracks.size()) {
     1044            RefPtr<TrackPrivateType> existingTrack = tracks.get(streamId);
    10071045            if (existingTrack) {
    10081046                existingTrack->setIndex(i);
     
    10151053        }
    10161054
    1017         auto track = VideoTrackPrivateGStreamer::create(makeWeakPtr(*this), i, pad);
    1018         if (!track->trackIndex())
     1055        auto track = TrackPrivateType::create(makeWeakPtr(*this), i, pad);
     1056        if (!track->trackIndex() && (type == Audio || type == Video))
    10191057            track->setActive(true);
    10201058        ASSERT(streamId == track->id());
    1021         m_videoTracks.add(streamId, track.copyRef());
    1022         m_player->addVideoTrack(track.get());
    1023     }
    1024 
    1025     purgeInvalidVideoTracks(validVideoStreams);
     1059        tracks.add(streamId, track.copyRef());
     1060
     1061        Variant<AudioTrackPrivate&, VideoTrackPrivate&, InbandTextTrackPrivate&> variantTrack(track.get());
     1062        switch (variantTrack.index()) {
     1063        case Audio: m_player->addAudioTrack(get<AudioTrackPrivate&>(variantTrack)); break;
     1064        case Video: m_player->addVideoTrack(get<VideoTrackPrivate&>(variantTrack)); break;
     1065        case Text: m_player->addTextTrack(get<InbandTextTrackPrivate&>(variantTrack)); break;
     1066        }
     1067    }
     1068
     1069    // Purge invalid tracks
     1070    tracks.removeIf([validStreams](auto& keyAndValue) {
     1071        return !validStreams.contains(keyAndValue.key);
     1072    });
    10261073
    10271074    m_player->mediaEngineUpdated();
    10281075}
     1076
    10291077bool MediaPlayerPrivateGStreamer::hasFirstVideoSampleReachedSink() const
    10301078{
     
    10611109{
    10621110    player->m_notifier->notify(MainThreadNotification::AudioChanged, [player] {
    1063         player->notifyPlayerOfAudio();
     1111        player->notifyPlayerOfTrack<AudioTrackPrivateGStreamer>();
    10641112    });
    10651113}
    10661114
    1067 void MediaPlayerPrivateGStreamer::notifyPlayerOfAudio()
    1068 {
    1069     if (UNLIKELY(!m_pipeline || !m_source))
    1070         return;
    1071 
    1072     ASSERT(m_isLegacyPlaybin || isMediaSource());
    1073 
    1074     // Ignore notifications after a EOS. We don't want the tracks to disappear when the video is finished.
    1075     if (m_isEndReached)
    1076         return;
    1077 
    1078     unsigned numTracks = 0;
    1079     bool useMediaSource = isMediaSource();
    1080     GstElement* element = useMediaSource ? m_source.get() : m_pipeline.get();
    1081     g_object_get(element, "n-audio", &numTracks, nullptr);
    1082 
    1083     GST_INFO_OBJECT(pipeline(), "Media has %d audio tracks", numTracks);
    1084     bool oldHasAudio = m_hasAudio;
    1085     m_hasAudio = numTracks > 0;
    1086     if (oldHasAudio != m_hasAudio)
    1087         m_player->characteristicChanged();
    1088 
    1089     if (useMediaSource) {
    1090         GST_DEBUG_OBJECT(pipeline(), "Tracks managed by source element. Bailing out now.");
    1091         m_player->mediaEngineUpdated();
    1092         return;
    1093     }
    1094 
    1095     Vector<String> validAudioStreams;
    1096     for (unsigned i = 0; i < numTracks; ++i) {
    1097         GRefPtr<GstPad> pad;
    1098         g_signal_emit_by_name(m_pipeline.get(), "get-audio-pad", i, &pad.outPtr(), nullptr);
    1099         ASSERT(pad);
    1100 
    1101         String streamId = "A" + String::number(i);
    1102         validAudioStreams.append(streamId);
    1103         if (i < m_audioTracks.size()) {
    1104             RefPtr<AudioTrackPrivateGStreamer> existingTrack = m_audioTracks.get(streamId);
    1105             if (existingTrack) {
    1106                 existingTrack->setIndex(i);
    1107                 // If the video has been played twice, the track is still there, but we need
    1108                 // to update the pad pointer.
    1109                 if (existingTrack->pad() != pad)
    1110                     existingTrack->setPad(GRefPtr(pad));
    1111                 continue;
    1112             }
    1113         }
    1114 
    1115         auto track = AudioTrackPrivateGStreamer::create(makeWeakPtr(*this), i, pad);
    1116         if (!track->trackIndex())
    1117             track->setActive(true);
    1118         ASSERT(streamId == track->id());
    1119         m_audioTracks.add(streamId, track.copyRef());
    1120         m_player->addAudioTrack(track.get());
    1121     }
    1122 
    1123     purgeInvalidAudioTracks(validAudioStreams);
    1124 
    1125     m_player->mediaEngineUpdated();
    1126 }
    1127 
    11281115void MediaPlayerPrivateGStreamer::textChangedCallback(MediaPlayerPrivateGStreamer* player)
    11291116{
    11301117    player->m_notifier->notify(MainThreadNotification::TextChanged, [player] {
    1131         player->notifyPlayerOfText();
     1118        player->notifyPlayerOfTrack<InbandTextTrackPrivateGStreamer>();
    11321119    });
    1133 }
    1134 
    1135 void MediaPlayerPrivateGStreamer::notifyPlayerOfText()
    1136 {
    1137     if (UNLIKELY(!m_pipeline || !m_source))
    1138         return;
    1139 
    1140     ASSERT(m_isLegacyPlaybin || isMediaSource());
    1141 
    1142     unsigned numTracks = 0;
    1143     bool useMediaSource = isMediaSource();
    1144     GstElement* element = useMediaSource ? m_source.get() : m_pipeline.get();
    1145     g_object_get(element, "n-text", &numTracks, nullptr);
    1146 
    1147     GST_INFO_OBJECT(pipeline(), "Media has %d text tracks", numTracks);
    1148 
    1149     if (useMediaSource) {
    1150         GST_DEBUG_OBJECT(pipeline(), "Tracks managed by source element. Bailing out now.");
    1151         return;
    1152     }
    1153 
    1154     Vector<String> validTextStreams;
    1155     for (unsigned i = 0; i < numTracks; ++i) {
    1156         GRefPtr<GstPad> pad;
    1157         g_signal_emit_by_name(m_pipeline.get(), "get-text-pad", i, &pad.outPtr(), nullptr);
    1158         ASSERT(pad);
    1159 
    1160         // We can't assume the pad has a sticky event here like implemented in
    1161         // InbandTextTrackPrivateGStreamer because it might be emitted after the
    1162         // track was created. So fallback to a dummy stream ID like in the Audio
    1163         // and Video tracks.
    1164         String streamId = "T" + String::number(i);
    1165 
    1166         validTextStreams.append(streamId);
    1167         if (i < m_textTracks.size()) {
    1168             RefPtr<InbandTextTrackPrivateGStreamer> existingTrack = m_textTracks.get(streamId);
    1169             if (existingTrack) {
    1170                 existingTrack->setIndex(i);
    1171                 if (existingTrack->pad() == pad)
    1172                     continue;
    1173             }
    1174         }
    1175 
    1176         auto track = InbandTextTrackPrivateGStreamer::create(i, pad);
    1177         m_textTracks.add(streamId, track.copyRef());
    1178         m_player->addTextTrack(track.get());
    1179     }
    1180 
    1181     purgeInvalidTextTracks(validTextStreams);
    11821120}
    11831121
     
    15391477{
    15401478    player->m_notifier->notify(MainThreadNotification::VideoChanged, [player] {
    1541         player->notifyPlayerOfVideo();
     1479        player->notifyPlayerOfTrack<VideoTrackPrivateGStreamer>();
    15421480    });
    15431481}
     
    21542092}
    21552093
    2156 void MediaPlayerPrivateGStreamer::purgeInvalidAudioTracks(Vector<String> validTrackIds)
    2157 {
    2158     m_audioTracks.removeIf([validTrackIds](auto& keyAndValue) {
    2159         return !validTrackIds.contains(keyAndValue.key);
    2160     });
    2161 }
    2162 
    2163 void MediaPlayerPrivateGStreamer::purgeInvalidVideoTracks(Vector<String> validTrackIds)
    2164 {
    2165     m_videoTracks.removeIf([validTrackIds](auto& keyAndValue) {
    2166         return !validTrackIds.contains(keyAndValue.key);
    2167     });
    2168 }
    2169 
    2170 void MediaPlayerPrivateGStreamer::purgeInvalidTextTracks(Vector<String> validTrackIds)
    2171 {
    2172     m_textTracks.removeIf([validTrackIds](auto& keyAndValue) {
    2173         return !validTrackIds.contains(keyAndValue.key);
    2174     });
    2175 }
    2176 
    21772094void MediaPlayerPrivateGStreamer::uriDecodeBinElementAddedCallback(GstBin* bin, GstElement* element, MediaPlayerPrivateGStreamer* player)
    21782095{
  • trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h

    r278979 r278981  
    299299    void readyTimerFired();
    300300
    301     void notifyPlayerOfVideo();
    302     void notifyPlayerOfAudio();
    303     void notifyPlayerOfText();
     301    template <typename TrackPrivateType> void notifyPlayerOfTrack();
    304302
    305303    void ensureAudioSourceProvider();
     
    460458    void processTableOfContentsEntry(GstTocEntry*);
    461459
    462     void purgeInvalidAudioTracks(Vector<String> validTrackIds);
    463     void purgeInvalidVideoTracks(Vector<String> validTrackIds);
    464     void purgeInvalidTextTracks(Vector<String> validTrackIds);
    465 
    466460    String engineDescription() const override { return "GStreamer"; }
    467461    bool didPassCORSAccessCheck() const override;
Note: See TracChangeset for help on using the changeset viewer.