Changeset 275514 in webkit


Ignore:
Timestamp:
Apr 6, 2021 6:53:24 AM (3 years ago)
Author:
commit-queue@webkit.org
Message:

[GStreamer][WebRTC] Audio is not played from an audio element when the srcObject object has unstarted video tracks
https://bugs.webkit.org/show_bug.cgi?id=209163

Patch by Philippe Normand <pnormand@igalia.com> on 2021-04-06
Reviewed by Xabier Rodriguez-Calvar.

Source/WebCore:

Ensure no MediaStream (active) video tracks can be added in a pipeline representing an <audio> element.

  • platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:

(WebCore::MediaPlayerPrivateGStreamer::sourceSetup):
(WebCore::MediaPlayerPrivateGStreamer::hasFirstSampleReachedSink const):
(WebCore::MediaPlayerPrivateGStreamer::videoSinkCapsChanged):
(WebCore::MediaPlayerPrivateGStreamer::playbackPosition const):
(WebCore::MediaPlayerPrivateGStreamer::updateTracks):

  • platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
  • platform/mediastream/gstreamer/GStreamerMediaStreamSource.cpp:

(webkitMediaStreamSrcPostStreamCollection):
(webkitMediaStreamSrcSetStream):

  • platform/mediastream/gstreamer/GStreamerMediaStreamSource.h:

LayoutTests:

  • platform/glib/TestExpectations: Unflag now-passing test.
Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r275508 r275514  
     12021-04-06  Philippe Normand  <pnormand@igalia.com>
     2
     3        [GStreamer][WebRTC] Audio is not played from an audio element when the srcObject object has unstarted video tracks
     4        https://bugs.webkit.org/show_bug.cgi?id=209163
     5
     6        Reviewed by Xabier Rodriguez-Calvar.
     7
     8        * platform/glib/TestExpectations: Unflag now-passing test.
     9
    1102021-04-06  Keith Miller  <keith_miller@apple.com>
    211
  • trunk/LayoutTests/platform/glib/TestExpectations

    r275507 r275514  
    10701070
    10711071webkit.org/b/208125 webrtc/peerconnection-new-candidate-page-cache.html [ Failure Timeout ]
    1072 
    1073 webkit.org/b/209163 webrtc/audio-video-element-playing.html [ Crash Failure Pass ]
    10741072
    10751073webkit.org/b/216538 webrtc/captureCanvas-webrtc-software-h264-baseline.html [ Slow Failure ]
  • trunk/Source/WebCore/ChangeLog

    r275512 r275514  
     12021-04-06  Philippe Normand  <pnormand@igalia.com>
     2
     3        [GStreamer][WebRTC] Audio is not played from an audio element when the srcObject object has unstarted video tracks
     4        https://bugs.webkit.org/show_bug.cgi?id=209163
     5
     6        Reviewed by Xabier Rodriguez-Calvar.
     7
     8        Ensure no MediaStream (active) video tracks can be added in a pipeline representing an <audio> element.
     9
     10        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp:
     11        (WebCore::MediaPlayerPrivateGStreamer::sourceSetup):
     12        (WebCore::MediaPlayerPrivateGStreamer::hasFirstSampleReachedSink const):
     13        (WebCore::MediaPlayerPrivateGStreamer::videoSinkCapsChanged):
     14        (WebCore::MediaPlayerPrivateGStreamer::playbackPosition const):
     15        (WebCore::MediaPlayerPrivateGStreamer::updateTracks):
     16        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h:
     17        * platform/mediastream/gstreamer/GStreamerMediaStreamSource.cpp:
     18        (webkitMediaStreamSrcPostStreamCollection):
     19        (webkitMediaStreamSrcSetStream):
     20        * platform/mediastream/gstreamer/GStreamerMediaStreamSource.h:
     21
    1222021-04-06  Philippe Normand  <pnormand@igalia.com>
    223
  • trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.cpp

    r275412 r275514  
    873873        auto stream = m_streamPrivate.get();
    874874        ASSERT(stream);
    875         webkitMediaStreamSrcSetStream(WEBKIT_MEDIA_STREAM_SRC(sourceElement), stream);
     875        webkitMediaStreamSrcSetStream(WEBKIT_MEDIA_STREAM_SRC(sourceElement), stream, m_player->isVideoPlayer());
    876876#endif
    877877    }
     
    10341034    m_player->mediaEngineUpdated();
    10351035}
     1036bool MediaPlayerPrivateGStreamer::hasFirstVideoSampleReachedSink() const
     1037{
     1038    auto sampleLocker = holdLock(m_sampleMutex);
     1039    return !!m_sample;
     1040}
    10361041
    10371042void MediaPlayerPrivateGStreamer::videoSinkCapsChanged(GstPad* videoSinkPad)
     
    10461051    GST_DEBUG_OBJECT(videoSinkPad, "Received new caps: %" GST_PTR_FORMAT, caps.get());
    10471052
    1048     bool hasFirstSampleReachedSink;
    1049     // This actually lacks contention since both notify::caps and triggerRepaint() are both run in the same streaming thread.
    1050     {
    1051         auto sampleLocker = holdLock(m_sampleMutex);
    1052         hasFirstSampleReachedSink = !!m_sample;
    1053     }
    1054 
    1055     if (!hasFirstSampleReachedSink) {
     1053    if (!hasFirstVideoSampleReachedSink()) {
    10561054        // We want to wait for the sink to receive the first buffer before emitting dimensions, since only by then we
    10571055        // are guaranteed that any potential tag event with a rotation has been handled.
     
    13421340{
    13431341    GST_TRACE_OBJECT(pipeline(), "isEndReached: %s, seeking: %s, seekTime: %s", boolForPrinting(m_isEndReached), boolForPrinting(m_isSeeking), m_seekTime.toString().utf8().data());
     1342
     1343#if ENABLE(MEDIA_STREAM)
     1344    if (m_streamPrivate && m_player->isVideoPlayer() && !hasFirstVideoSampleReachedSink())
     1345        return MediaTime::zeroTime();
     1346#endif
     1347
    13441348    if (m_isSeeking)
    13451349        return m_seekTime;
     
    14851489
    14861490#define CREATE_TRACK(type, Type) G_STMT_START {                         \
    1487         m_has##Type = true;                                             \
    14881491        if (!useMediaSource) {                                          \
    14891492            RefPtr<Type##TrackPrivateGStreamer> track = Type##TrackPrivateGStreamer::create(makeWeakPtr(*this), type##TrackIndex, stream); \
     
    15091512        if (type & GST_STREAM_TYPE_AUDIO)
    15101513            CREATE_TRACK(audio, Audio);
    1511         else if (type & GST_STREAM_TYPE_VIDEO)
     1514        else if (type & GST_STREAM_TYPE_VIDEO && m_player->isVideoPlayer())
    15121515            CREATE_TRACK(video, Video);
    15131516        else if (type & GST_STREAM_TYPE_TEXT && !useMediaSource) {
     
    15191522    }
    15201523
     1524    m_hasAudio = !m_audioTracks.isEmpty();
     1525    m_hasVideo = !m_videoTracks.isEmpty();
     1526
    15211527    if (oldHasVideo != m_hasVideo || oldHasAudio != m_hasAudio)
    15221528        m_player->characteristicChanged();
    15231529
    1524     if (m_hasVideo)
     1530    if (!oldHasVideo && m_hasVideo)
    15251531        m_player->sizeChanged();
    15261532
  • trunk/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamer.h

    r275412 r275514  
    449449    void videoSinkCapsChanged(GstPad*);
    450450    void updateVideoSizeAndOrientationFromCaps(const GstCaps*);
     451    bool hasFirstVideoSampleReachedSink() const;
    451452
    452453#if ENABLE(ENCRYPTED_MEDIA)
  • trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerMediaStreamSource.cpp

    r274150 r275514  
    575575
    576576    GST_OBJECT_LOCK(self);
    577     String upstreamId;
    578     if (priv->stream)
    579         upstreamId = priv->stream->id();
    580     else
    581         upstreamId = createCanonicalUUIDString();
    582 
     577    if (priv->stream && (!priv->stream->active() || !priv->stream->hasTracks())) {
     578        GST_OBJECT_UNLOCK(self);
     579        return;
     580    }
     581
     582    auto upstreamId = priv->stream ? priv->stream->id() : createCanonicalUUIDString();
    583583    priv->streamCollection = adoptGRef(gst_stream_collection_new(upstreamId.ascii().data()));
    584     for (auto& track : priv->tracks)
     584    for (auto& track : priv->tracks) {
     585        if (!track->isActive())
     586            continue;
    585587        gst_stream_collection_add_stream(priv->streamCollection.get(), webkitMediaStreamNew(track.get()));
     588    }
    586589
    587590    GST_OBJECT_UNLOCK(self);
     
    616619}
    617620
    618 void webkitMediaStreamSrcSetStream(WebKitMediaStreamSrc* self, MediaStreamPrivate* stream)
     621void webkitMediaStreamSrcSetStream(WebKitMediaStreamSrc* self, MediaStreamPrivate* stream, bool isVideoPlayer)
    619622{
    620623    ASSERT(WEBKIT_IS_MEDIA_STREAM_SRC(self));
     
    625628    auto tracks = stream->tracks();
    626629    bool onlyTrack = tracks.size() == 1;
    627     for (auto& track : tracks)
     630    for (auto& track : tracks) {
     631        if (!isVideoPlayer && track->type() == RealtimeMediaSource::Type::Video)
     632            continue;
    628633        webkitMediaStreamSrcAddTrack(self, track.get(), onlyTrack);
    629 
     634    }
    630635    webkitMediaStreamSrcPostStreamCollection(self);
    631636    gst_element_no_more_pads(GST_ELEMENT_CAST(self));
  • trunk/Source/WebCore/platform/mediastream/gstreamer/GStreamerMediaStreamSource.h

    r263836 r275514  
    5555};
    5656
    57 void webkitMediaStreamSrcSetStream(WebKitMediaStreamSrc*, WebCore::MediaStreamPrivate*);
     57void webkitMediaStreamSrcSetStream(WebKitMediaStreamSrc*, WebCore::MediaStreamPrivate*, bool isVideoPlayer);
    5858void webkitMediaStreamSrcAddTrack(WebKitMediaStreamSrc*, WebCore::MediaStreamTrackPrivate*, bool onlyTrack);
    5959GstElement* webkitMediaStreamSrcNew();
Note: See TracChangeset for help on using the changeset viewer.