Bug 190642 - MediaRecorder should fire a stop event when all tracks are ended
Summary: MediaRecorder should fire a stop event when all tracks are ended
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebRTC (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Wendy
URL:
Keywords: InRadar
Depends on:
Blocks: 85851
  Show dependency treegraph
 
Reported: 2018-10-16 15:07 PDT by Wendy
Modified: 2019-03-29 12:54 PDT (History)
4 users (show)

See Also:


Attachments
Patch (19.18 KB, patch)
2018-10-17 14:31 PDT, Wendy
no flags Details | Formatted Diff | Diff
Patch (20.86 KB, patch)
2018-10-17 14:38 PDT, Wendy
no flags Details | Formatted Diff | Diff
Patch (21.50 KB, patch)
2018-10-17 15:42 PDT, Wendy
no flags Details | Formatted Diff | Diff
Patch (21.24 KB, patch)
2018-10-18 14:06 PDT, Wendy
no flags Details | Formatted Diff | Diff
Patch (20.85 KB, patch)
2018-10-18 16:03 PDT, Wendy
no flags Details | Formatted Diff | Diff
Patch (20.09 KB, patch)
2018-10-18 16:10 PDT, Wendy
no flags Details | Formatted Diff | Diff
Patch (8.96 KB, patch)
2018-10-19 09:40 PDT, Wendy
no flags Details | Formatted Diff | Diff
Patch (9.00 KB, patch)
2018-10-19 16:53 PDT, Wendy
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Wendy 2018-10-16 15:07:20 PDT
MediaRecorder should and fire stop and data available events when all tracks are ended accordion to section 2.3 of https://w3c.github.io/mediacapture-record/#mediarecorder-api
Comment 1 Wendy 2018-10-17 14:31:21 PDT
Created attachment 352642 [details]
Patch
Comment 2 Wendy 2018-10-17 14:38:33 PDT
Created attachment 352644 [details]
Patch
Comment 3 Wendy 2018-10-17 15:42:46 PDT
Created attachment 352653 [details]
Patch
Comment 4 youenn fablet 2018-10-17 20:14:43 PDT
Comment on attachment 352653 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=352653&action=review

> Source/WebCore/Modules/mediarecorder/MediaRecorder.cpp:50
> +    return trackPrivates;

You can use WTF::map here, something like:
return WTF::map(tracks, [] (const auto& track) -> RefPtr<MediaStreamTrackPrivate> {
    return &track->privateTrack();
});
We probably want a Vector<Ref< MediaStreamTrackPrivate>> instead of Vector<RefPtr< MediaStreamTrackPrivate>>.
This might do the trick:
return WTF::map(tracks, [] (const auto& track) -> Ref<MediaStreamTrackPrivate> {
    return track->privateTrack();
});

> Source/WebCore/platform/mediarecorder/MediaRecorderPrivate.cpp:43
> +    }

With a MediaStreamTrackPrivateVector&&, you would do something like:
m_tracks = WTFMove(track)
for (auto& track : m_tracks)
    track->addObserver(*this);

> Source/WebCore/platform/mediarecorder/MediaRecorderPrivate.h:33
> +class MediaRecorderPrivate : public RefCounted<MediaRecorderPrivate>, private MediaStreamTrackPrivate::Observer {

Should probably be final.
I am not sure MediaRecorderPrivate needs to be RefCounted.
Instead MediaRecorder could take a std::unique_ptr<MediaRecorderPrivate>.

> Source/WebCore/platform/mediarecorder/MediaRecorderPrivate.h:44
> +    void removeObserver(Observer&);

No need for more than one observer.

> Source/WebCore/platform/mediarecorder/MediaRecorderPrivate.h:49
> +    MediaRecorderPrivate(const MediaStreamTrackPrivateVector&);

Should use explicit with a constructor with one parameter.
In that case, it should be a MediaStreamTrackPrivateVector&& and probably take another parameter (so no explicit anymore) for Owner (see below).

> Source/WebCore/platform/mediarecorder/MediaRecorderPrivate.h:52
> +    void trackEnded(MediaStreamTrackPrivate&) override;

s/override/final here and below.

> Source/WebCore/platform/mediarecorder/MediaRecorderPrivate.h:57
> +    Vector<Observer*> m_observers;

Let's have just one observer which will be MediaRecorder.
And maybe rename it to Owner.
Owner & m_owner;

> Source/WebCore/platform/mediastream/mac/RealtimeOutgoingVideoSourceCocoa.cpp:-33
> -#include "RealtimeVideoUtilities.h"

Is this change needed?
If not, let's not do it there.
Comment 5 Wendy 2018-10-18 14:06:04 PDT
Created attachment 352728 [details]
Patch
Comment 6 youenn fablet 2018-10-18 14:21:10 PDT
Comment on attachment 352728 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=352728&action=review

> Source/WebCore/Modules/mediarecorder/MediaRecorder.cpp:106
> +        auto event = Event::create(eventNames().stopEvent, Event::CanBubble::No, Event::IsCancelable::No);

Can you add a FIXME: add data available event?

> Source/WebCore/platform/mediarecorder/MediaRecorderPrivate.cpp:40
> +    m_owner = &owner;

m_owner should be a reference probably, not a pointer.
   m_owner(owner) should do the trick.
I would tend to pass owner first and tracks second.

> Source/WebCore/platform/mediarecorder/MediaRecorderPrivate.cpp:59
> +    }

You can probably use Vector::findMatching

> LayoutTests/imported/w3c/ChangeLog:9
> +        * web-platform-tests/mediacapture-record/MediaRecorder-stop.html: Added.

Please upload this test to WPT.
Comment 7 Wendy 2018-10-18 16:03:53 PDT
Created attachment 352743 [details]
Patch
Comment 8 Wendy 2018-10-18 16:04:43 PDT
Submitted web-platform-tests pull request: https://github.com/web-platform-tests/wpt/pull/13606
Comment 9 Wendy 2018-10-18 16:10:04 PDT
Created attachment 352744 [details]
Patch
Comment 10 youenn fablet 2018-10-19 08:35:08 PDT
I looked further at the specification and think that we may better be served by changing the model a bit:
1. Make MediaRecorder an observer of all track private.
2. Handle "all ended tracks" in MediaRecorder

When implementing dataavailable event, we will then introduce a MediaRecorderPrivate method to get the available data. We might pass a function or completion handler to MediaRecorderPrivate if we need to get the data asynchronously.

The impact on this patch is to remove MediaRecorderPrivate from this patch and move part of MediaRecorderPrivate implementation of this patch in MediaRecorder.
We will then introduce MediaRecorderPrivate as part of dataavailable event implementation.
Comment 11 youenn fablet 2018-10-19 08:36:07 PDT
Ms2Jer put some comments in https://github.com/web-platform-tests/wpt/pull/13606.
It might be good to update the tests accordingly.
Comment 12 Wendy 2018-10-19 09:40:02 PDT
Created attachment 352789 [details]
Patch
Comment 13 youenn fablet 2018-10-19 14:54:29 PDT
Comment on attachment 352789 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=352789&action=review

> LayoutTests/imported/w3c/web-platform-tests/mediacapture-record/MediaRecorder-stop.html:10
> +<canvas id="canvas">

Apparently, Firefox does not like capturing canvas without size.
Can you test it on Firefox and try adding width/height to see whether that would make it work if not already?
Comment 14 Wendy 2018-10-19 16:53:52 PDT
Created attachment 352834 [details]
Patch
Comment 15 Wendy 2018-10-19 19:53:26 PDT
(In reply to youenn fablet from comment #13)
> Comment on attachment 352789 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=352789&action=review
> 
> > LayoutTests/imported/w3c/web-platform-tests/mediacapture-record/MediaRecorder-stop.html:10
> > +<canvas id="canvas">
> 
> Apparently, Firefox does not like capturing canvas without size.
> Can you test it on Firefox and try adding width/height to see whether that
> would make it work if not already?

I did the test on FireFox, in addition to the width and height, we might also need getContext to initialize the canvas, otherwise we will get an exception. I have fixed it in the latest patch.
Comment 16 youenn fablet 2018-10-20 05:52:08 PDT
I am surprised getContex is needed, maybe this is a bug on Firefox side.
I guess we should reuse some of the WPT routines used to create a/v tracks
Comment 17 WebKit Commit Bot 2018-10-20 06:15:33 PDT
Comment on attachment 352834 [details]
Patch

Clearing flags on attachment: 352834

Committed r237311: <https://trac.webkit.org/changeset/237311>
Comment 18 WebKit Commit Bot 2018-10-20 06:15:35 PDT
All reviewed patches have been landed.  Closing bug.
Comment 19 Radar WebKit Bug Importer 2018-10-20 06:16:23 PDT
<rdar://problem/45430564>
Comment 20 Truitt Savell 2018-11-14 11:15:08 PST
Looks like the test imported/w3c/web-platform-tests/mediacapture-record/MediaRecorder-stop.html

added in https://trac.webkit.org/changeset/237311/webkit

is a flakey failure. It is highly intermittent and seems to be having a harness timeout. 

History:
https://webkit-test-results.webkit.org/dashboards/flakiness_dashboard.html#showAllRuns=true&tests=imported%2Fw3c%2Fweb-platform-tests%2Fmediacapture-record%2FMediaRecorder-stop.html

Diff:
--- /Volumes/Data/slave/sierra-release-tests-wk1/build/layout-test-results/imported/w3c/web-platform-tests/mediacapture-record/MediaRecorder-stop-expected.txt
+++ /Volumes/Data/slave/sierra-release-tests-wk1/build/layout-test-results/imported/w3c/web-platform-tests/mediacapture-record/MediaRecorder-stop-actual.txt
@@ -1,4 +1,6 @@
+
+Harness Error (TIMEOUT), message = null
 
 PASS MediaRecorder will stop recording and fire a stop event when all tracks are ended 
-PASS MediaRecorder will stop recording and fire a stop event when stop() is called 
+TIMEOUT MediaRecorder will stop recording and fire a stop event when stop() is called Test timed out