durationchange event is not fired during some MSE calls (e.g. appendBuffer())
Reported by
ddy...@vewd.com,
Oct 20 2017
|
|||
Issue descriptionUserAgent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36 Example URL: https://yt-dash-mse-test.commondatastorage.googleapis.com/unit-tests/2018.html?test_type=conformance-test&command=run&tests=31 Steps to reproduce the problem: Version using attached simplified TC 1. Host attached test case on any web server (it's stripped down version of 2018's QUAL MSE-conformance, mainly test `31. DurationAfterAppendOpusAudio`) 2. Run in Chrome/Chromium link: http://localhost/path/to/attached/qual/test/2018.html?test_type=conformance-test&command=run&tests=31 3. Observe printed logs 3.1. There are some extra logs added which will print fired events (they start with `###`) 4. Note that there is only one `durationchange` event which is sent after log `Remove() complete` which is when JS code directly assigns new duration value to `MediaSource.duration` in js/lib/mse/2018/msutil-20171005191104.js` in `SetDuration()` function. Version with plan QUAL 2018 (MSE-conformance test) using built-in DevTools: 1. Run: https://yt-dash-mse-test.commondatastorage.googleapis.com/unit-tests/2018.html?test_type=conformance-test&command=run&tests=31 2. Open DevTools -> Sources tab 3. Open file from unit-tests/js/tests/2018/conformanceTest-$ver$.js 4. Find `createDurationAfterAppendTest()` function 5. Add some extra logs in there on `media` variable for `durationchange` event. What is the expected behavior? According to MSE specification (https://www.w3.org/TR/media-source/), when JS code executes `appendBuffer()` method on SourceBuffer object (https://www.w3.org/TR/media-source/#dom-sourcebuffer-appendbuffer) and asynchronous append buffer algorithm (https://www.w3.org/TR/media-source/#sourcebuffer-buffer-append) is run, browser should: 1. Run the segment parser loop algorithm. ... 4. Queue a task to fire a simple event named update at this SourceBuffer object. 5. Queue a task to fire a simple event named updateend at this SourceBuffer object. If you inspect segment parser loop algorithm (https://www.w3.org/TR/media-source/#sourcebuffer-segment-parser-loop) then there are two cases: (a) for initialization segments, initialization segment received algorithm (https://www.w3.org/TR/media-source/#sourcebuffer-init-segment-received) mandates in first step, that duration should be updated (either to known value or positive infinity) and *duration change algorithm* should be run. (b) for media segments, coded frame processing algorithm (https://www.w3.org/TR/media-source/#sourcebuffer-coded-frame-processing) mandates in step 5 that duration can be updated if frames are beyond current duration. Again - *duration change algorithm* should be run. Now, the duration change algorithm (https://www.w3.org/TR/media-source/#duration-change-algorithm) mandates in step 6 that we should run HTMLMediaElement duration change algorithm (unless some corner cases like the same duration or error states). This algorithm (https://www.w3.org/TR/html51/semantics-embedded-content.html#durationChange) issues that the browser should send `durationchange` event. Only exception is specified as: "The event is not fired when the duration is reset as part of loading a new media resource" but I don't believe that this is the case here, as below that there is: "Similarly, if the user agent initially estimated the media resource’s duration instead of determining it precisely, and later revises the estimate based on new information, then the duration would change and the durationchange event would be fired." This is exactly the case when ChunkDemuxer finds duration in initialization segments, but then data exceeds this duration and has to be updated. What went wrong? Chrome (/Chromium) will send `durationchange` events only for direct assignment of MediaSource's `duration` field (a) or when ready state is at least HAVE_METADATA. In some corner cases when using MSE, ready state is still in HAVE_NOTHING state and `durationchange` events are not fired. Did this work before? N/A Is it a problem with Flash or HTML5? HTML5 Does this work in other browsers? N/A Chrome version: 62.0.3202.62 Channel: stable OS Version: Flash Version: Contents of chrome://gpu: Note: To properly save this page, select the "Webpage, Complete" option in the Save File dialog. Graphics Feature Status Canvas: Software only, hardware acceleration unavailable CheckerImaging: Disabled Flash: Software only, hardware acceleration unavailable Flash Stage3D: Software only, hardware acceleration unavailable Flash Stage3D Baseline profile: Software only, hardware acceleration unavailable Compositing: Software only, hardware acceleration unavailable Multiple Raster Threads: Enabled Native GpuMemoryBuffers: Software only. Hardware acceleration disabled Rasterization: Software only, hardware acceleration unavailable Video Decode: Software only, hardware acceleration unavailable Video Encode: Software only, hardware acceleration unavailable WebGL: Hardware accelerated but at reduced performance WebGL2: Unavailable Problems Detected ATI/AMD cards with older drivers in Linux are crash-prone: 71381, 76428, 73910, 101225, 136240, 357314 Disabled Features: flash_stage3d, gpu_compositing, panel_fitting, flash3d, gpu_rasterization, accelerated_2d_canvas, accelerated_video_decode, webgl2, accelerated_webgl, flash_stage3d_baseline, accelerated_video_encode Accelerated video decode is unavailable on Linux: 137247 Disabled Features: accelerated_video_decode Accelerated video encode is unavailable on Linux Disabled Features: accelerated_video_encode Native GpuMemoryBuffers have been disabled, either via about:flags or command line. Disabled Features: native_gpu_memory_buffers Checker-imaging has been disabled via finch trial or the command line. Disabled Features: checker_imaging Version Information Data exported 10/20/2017, 1:23:30 PM Chrome version Chrome/62.0.3202.62 Operating system Linux 4.10.0-37-generic Software rendering list version 13.12 Driver bug list version 10.30 ANGLE commit id e8ef2bc4bd01 2D graphics backend Skia/62 e74b41c6c84638d5a9ee6d254a715bcd9e17c603- Command Line /usr/bin/google-chrome-stable --enable-blink-features=MediaSourceNewAbortAndDuration --flag-switches-begin --flag-switches-end Driver Information Initialization time 0 In-process GPU true Passthrough Command Decoder false Supports overlays false Sandboxed false GPU0 VENDOR = 0x1002, DEVICE= 0x6610 Optimus false Optimus false AMD switchable false Driver vendor Google Inc. Driver version 3.3.0.2 Driver date 2017/04/07 Pixel shader version 3.0 Vertex shader version 3.0 Max. MSAA samples 4 Machine model name Machine model version GL_VENDOR Google Inc. GL_RENDERER Google SwiftShader GL_VERSION OpenGL ES 2.0 SwiftShader GL_EXTENSIONS Disabled Extensions Window system binding vendor Window system binding version Window system binding extensions Window manager Compiz XDG_CURRENT_DESKTOP Unity GDMSESSION ubuntu Compositing manager Yes Direct rendering Yes Reset notification strategy 0x0000 GPU process crash count 0 System visual ID 0 RGBA visual ID 0 Compositor Information Tile Update Mode One-copy Partial Raster Enabled GpuMemoryBuffers Status ATC Software only ATCIA Software only DXT1 Software only DXT5 Software only ETC1 Software only R_8 Software only R_16 Software only RG_88 Software only BGR_565 Software only RGBA_4444 Software only RGBX_8888 Software only RGBA_8888 Software only BGRX_8888 Software only BGRA_8888 Software only RGBA_F16 Software only YVU_420 Software only YUV_420_BIPLANAR Software only UYVY_422 Software only Note that this makes Chrome/Chromium behavior inconsistent, as it will fire `durationchange` event from MSE if MediaSource.duration is asasigned directly (even in HAVE_NOTHING ready state, but won't fire it from other "sources"). This is due to the fact that MediaSource.duration assignment is done in `MediaSource::setDuration(double, ExceptionState&)` (https://cs.chromium.org/chromium/src/third_party/WebKit/Source/modules/mediasource/MediaSource.cpp?sq=package:chromium&l=485) and this goes directly to `HTMLMediaElement::DurationChanged(double, bool)`, but other ways goes from `ChunkDemuxer::UpdateDuration(TimeDelta)` (https://cs.chromium.org/chromium/src/media/filters/chunk_demuxer.cc?dr=CSs&l=1313) through `WebMediaPlayerImpl::OnDurationChange()` (https://cs.chromium.org/chromium/src/media/blink/webmediaplayer_impl.cc?dr=CSs&l=1622) which has something like this: ``` if (ready_state_ == WebMediaPlayer::kReadyStateHaveNothing) return; ``` This will quietly kill any duration-changed notifications.
,
Oct 26 2017
The issue seems to be out of TE-scope as it is related to unit test. Hence, adding TE-NeedsTriageHelp for further investigation from dev team. Thanks...!!
,
Nov 1 2017
this is source API related. give to matt to start investigating. |
|||
►
Sign in to add a comment |
|||
Comment 1 by manoranj...@chromium.org
, Oct 20 2017