Changeset 278981 in webkit
- Timestamp:
- Jun 17, 2021, 5:00:47 AM (4 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r278979 r278981 1 2021-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 1 28 2021-06-17 Commit Queue <commit-queue@webkit.org> 2 29 -
trunk/Source/WebCore/platform/graphics/gstreamer/InbandTextTrackPrivateGStreamer.h
r278979 r278981 45 45 } 46 46 47 static Ref<InbandTextTrackPrivateGStreamer> create(WeakPtr<MediaPlayerPrivateGStreamer>, gint index, GRefPtr<GstPad> pad) 48 { 49 return create(index, pad); 50 } 51 47 52 static Ref<InbandTextTrackPrivateGStreamer> create(gint index, GRefPtr<GstStream> stream) 48 53 { -
trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp
r278979 r278981 963 963 } 964 964 965 void MediaPlayerPrivateGStreamer::notifyPlayerOfVideo() 965 template <typename TrackPrivateType> 966 void MediaPlayerPrivateGStreamer::notifyPlayerOfTrack() 966 967 { 967 968 if (UNLIKELY(!m_pipeline || !m_source)) … … 969 970 970 971 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); 971 999 972 1000 // 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 num Tracks = 0;1001 if (m_isEndReached && (type == Audio || type == Video)) 1002 return; 1003 1004 unsigned numberOfTracks = 0; 977 1005 bool useMediaSource = isMediaSource(); 1006 1007 StringPrintStream numberOfTracksProperty; 1008 numberOfTracksProperty.printf("n-%s", typeName); 1009 978 1010 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 } 990 1024 991 1025 if (useMediaSource) { … … 995 1029 } 996 1030 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) { 999 1036 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); 1001 1038 ASSERT(pad); 1002 1039 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); 1007 1045 if (existingTrack) { 1008 1046 existingTrack->setIndex(i); … … 1015 1053 } 1016 1054 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)) 1019 1057 track->setActive(true); 1020 1058 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 }); 1026 1073 1027 1074 m_player->mediaEngineUpdated(); 1028 1075 } 1076 1029 1077 bool MediaPlayerPrivateGStreamer::hasFirstVideoSampleReachedSink() const 1030 1078 { … … 1061 1109 { 1062 1110 player->m_notifier->notify(MainThreadNotification::AudioChanged, [player] { 1063 player->notifyPlayerOf Audio();1111 player->notifyPlayerOfTrack<AudioTrackPrivateGStreamer>(); 1064 1112 }); 1065 1113 } 1066 1114 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 need1108 // 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 1128 1115 void MediaPlayerPrivateGStreamer::textChangedCallback(MediaPlayerPrivateGStreamer* player) 1129 1116 { 1130 1117 player->m_notifier->notify(MainThreadNotification::TextChanged, [player] { 1131 player->notifyPlayerOfT ext();1118 player->notifyPlayerOfTrack<InbandTextTrackPrivateGStreamer>(); 1132 1119 }); 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 in1161 // InbandTextTrackPrivateGStreamer because it might be emitted after the1162 // track was created. So fallback to a dummy stream ID like in the Audio1163 // 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);1182 1120 } 1183 1121 … … 1539 1477 { 1540 1478 player->m_notifier->notify(MainThreadNotification::VideoChanged, [player] { 1541 player->notifyPlayerOf Video();1479 player->notifyPlayerOfTrack<VideoTrackPrivateGStreamer>(); 1542 1480 }); 1543 1481 } … … 2154 2092 } 2155 2093 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 2177 2094 void MediaPlayerPrivateGStreamer::uriDecodeBinElementAddedCallback(GstBin* bin, GstElement* element, MediaPlayerPrivateGStreamer* player) 2178 2095 { -
trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h
r278979 r278981 299 299 void readyTimerFired(); 300 300 301 void notifyPlayerOfVideo(); 302 void notifyPlayerOfAudio(); 303 void notifyPlayerOfText(); 301 template <typename TrackPrivateType> void notifyPlayerOfTrack(); 304 302 305 303 void ensureAudioSourceProvider(); … … 460 458 void processTableOfContentsEntry(GstTocEntry*); 461 459 462 void purgeInvalidAudioTracks(Vector<String> validTrackIds);463 void purgeInvalidVideoTracks(Vector<String> validTrackIds);464 void purgeInvalidTextTracks(Vector<String> validTrackIds);465 466 460 String engineDescription() const override { return "GStreamer"; } 467 461 bool didPassCORSAccessCheck() const override;
Note:
See TracChangeset
for help on using the changeset viewer.