Issue metadata
Sign in to add a comment
|
getUserMedia + video:width:ideal not according to spec anymore (it scales down video size) |
||||||||||||||||||||||
Issue descriptionReproducible using example at https://jsfiddle.net/Lc6p3y0j/. 1. Launch chrome (chrome-unstable or developer build) using: chrome -use-fake-device-for-media-stream=device-count=2 --use-fake-ui-for-media-stream 2. go to https://jsfiddle.net/Lc6p3y0j/ 3. Press start button, 4. Press stop button 5. Check the video size in console Constraint should provide closest available width (640 for fake device) instead of scaling down to the ideal width. navigator.getUserMedia( { video: { width: {ideal:629}, }, audio: false, }, 1. if using developer build (master branch, commit 9b0611279ba80484dfe17163519cabbd5939c935 Mon Apr 10 08:54:51 2017 -0700) the track getSettings and video.videoWidth/videoHeight show scaled values.629x472 ObjectdeviceId: "8f05888c8d92033eb8d4cc801d8c0bb362d2911dc278be863c16e00c25f0ffee"frameRate: 20height: 472width: 629__proto__: Object fiddle.jshell.net/:107 video.videoWidth:629, video.videoHeight:472 2. if using chrome-unstable (Google Chrome 59.0.3053.3) or if using "--enable-features=MediaStreamOldVideoConstraints" with the build from 1): values are 640x480 (as defined by fake device). ObjectdeviceId: "8f05888c8d92033eb8d4cc801d8c0bb362d2911dc278be863c16e00c25f0ffee"frameRate: 20height: 480width: 640__proto__: Object (index):107 video.videoWidth:640, video.videoHeight:480 Same is reproducible with real cameras. The issue is related to: crrev.com/2793053002: Enable spec-compliant algorithm for MediaStream video constraints by default as mentioned, if starting chrome with "--enable-features=MediaStreamOldVideoConstraints" the issue is not reproducible. Building with the latest master to check...
,
Apr 13 2017
,
Apr 13 2017
Note that the old algorithm is giving you 640x480 when you specify 629 simply because 640x480 is the default resolution. It will give you the same if you specify ideal to any arbitrary value, as the ideal value is ignored.
,
Apr 13 2017
> The old algorithm, enabled with --enable-features=MediaStreamOldVideoConstraints, completely ignores ideal, so it can't support ideal according to spec. You are right. So, "can support" means that all downscaled resolutions are supported, too. Thanks. I was (mis)using the width to select depth camera (width = 628) instead of infrared camera (width = 640) in a prototype. That works fine, with old algorithm and with the new. Clear now.
,
Apr 13 2017
This might be another issue (or not) but the new functionality is introducing some problems:
Earlier, we would get the the default settings (also for frameCount) but could use ideal to select the device based on available settings.
Now, consider this code used to select the depth device:
try {
let constraints = {
audio: false,
video:{
// SR300 depth camera enables capture at 110 frames per second.
frameRate: {ideal:110},
// R200 related hack: prefer depth (width = 628) to IR (width = 641)
// stream.
width: {ideal:628, max:640},
}
}
let stream = await navigator.mediaDevices.getUserMedia(constraints);
let track = stream.getVideoTracks()[0];
console.log(track.getSettings()); // (*)
if (track.getSettings) {
// If getSettings() is available, use the deviceId to select the stream
// with default resolution and frameRate.
constraints = {
audio: false,
video: {
deviceId: {exact: track.getSettings().deviceId},
frameRate: {ideal:60},
height: {ideal:480},
}
}
stream = await navigator.mediaDevices.getUserMedia(constraints);
track = stream.getVideoTracks()[0];
console.log(track.getSettings()); // (**)
}
Unfortunately, after second navigator.mediaDevices.getUserMedia(constraints) we don't get frameCount 60 nor 640x480, but still 110 now with 24Ox640
output related to console.logs above.
(*) frameRate: 110 height:236 width:628
(**) frameRate: 110 height:240 width:640
(**) Shouldn't it be frameRate 60, width 640, height 480 (the mode that was default previously)?
The device used has this modes:
astojilj@astojilj-DESK:~/chromium/src$ v4l2-ctl --device=/dev/video2 --list-formats-extioctl: VIDIOC_ENUM_FMT
Index : 1
Type : Video Capture
Pixel Format: 'INVZ'
Name : Depth 16-bit (INVZ)
Size: Discrete 640x480
Interval: Discrete 0.017s (60.000 fps)
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.100s (10.000 fps)
Size: Discrete 640x240
Interval: Discrete 0.009s (110.000 fps)
Interval: Discrete 0.017s (60.000 fps)
Interval: Discrete 0.033s (30.000 fps)
Interval: Discrete 0.100s (10.000 fps)
I'll reopen - please close as wont fix if this is still according to spec. Thanks.
,
Apr 13 2017
Let me start by making it clear that the old algorithm does not use ideal in any way. Specifying it is the same as not specifying it. You cannot use it for available settings or anything at all. Now, regarding your code. The first getUserMedia call requests a device that ideally supports a frame rate of 110Hz and a width of no more than 640, ideally 628. getUserMedia opened the camera in 640x240@110Hz and gives you a track with the resolution scaled down to the ideal value 628. You get 628x236 because the algorithm tries to preserve the native aspect ratio. This is all clearly according to the spec. If I understand correctly, the camera is still open in 640x240@110Hz and you issue a second gUM call requesting an ideal height of 480 and an ideal frame rate of 60. Note that since the camera is already opened at 640x240@110Hz, that is the only native format available and that is what will be used, provided constraints are not violated. The only mandatory constrained you specified was the device ID, which is satisfied. The other constraints are ideal height at 480. You cannot get 480 because the camera is available only at 240 at most. Chromium cannot scale up, so you get 240 which is the currently supported value that is closest to 480. With regards to frame rate, the camera is already opened at 110, but since you specified an ideal frame rate of 60, Chromium will adjust the frame rate and actually deliver (close to) 60 frames per second. There might be an issue in getSettings that makes it report the native frame rate instead of the adjusted one. Note also that even if there is no frame-rate adjustment, 110 Hz would still be a valid result according to spec. So, the result you are getting is according to spec. Now, can you run the same experiment but specifying exact 60Hz instead of 110Hz to see what you are getting.
,
Apr 13 2017
I meant exact 60Hz instead of ideal 60Hz in the last line of #7. The track will be the same as with ideal, but I am interested in the result returned by getSettings, which might be a bug since it seems to be returning the native settings of the underlying source, but not the settings for the track.
,
Apr 13 2017
Note also that if you make the second gUM call after closing the camera, all formats will be available again and it will choose 640x480@60Hz.
,
Apr 13 2017
Found the problem with getSettings. It is indeed returning the frame rate of the source. Filed issue 711273 .
,
Apr 13 2017
>Let me start by making it clear that the old algorithm does not use ideal in any way. Specifying it is the same as not specifying it. You cannot use it for available settings or anything at all.
Old algorithm:
video: true; => returns default color camera.
video: frameRate: {ideal:110} => returns depth camera in default (60fps, 640x480) as only depth camera has 110fps mode.
That's what I meant by "uses for selecting based on available settings".
> camera is still open in 640x240@110Hz and you issue a second gUM call requesting an ideal height of 480 and an ideal frame rate of 60.
Correct. There is no change if using exact frame rate instead of ideal, e.g:
constraints = {
audio: false,
video: {
deviceId: {exact: track.getSettings().deviceId},
frameRate: {exact:60},
}
It is still frameRate 110.
I'll try to find the way to close the camera before second gUM (and to use the same deviceId...).
,
Apr 13 2017
I'll explain what is going on.
Up until M57, video: {frameRate: {ideal:110}} would have been the same as video: true.
By M58 we had implemented the new algorithm, but did not integrate it with the whole stack on time, so we used it only to select the device, but not its settings. Settings were still selected based on the old algorithm, which ignores ideal. This is the reason, ideal allowed you to select the correct camera, but the rest of the settings were chosen in a nonspec compliant way. It just chose the settings closest to the default, which is 640x480@60Hz.
While not fully spec compliant, this is more spec compliant than M57.
In M59 we completed the integration and now it continues to select the correct device, but now it also uses settings that are closest to what constraints say.
,
Apr 13 2017
To close the camera, you should just stop the first track. See https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamTrack/stop Note again that the reason your example works with M58 is that the nonspec compliant settings that the old algorithm uses to open the camera with the first call coincide with the constraints you specify in the second call.
,
Apr 13 2017
>Note also that if you make the second gUM call after closing the camera,
If calling track.stop() like this:
let stream = await navigator.mediaDevices.getUserMedia(constraints);
let track = stream.getVideoTracks()[0];
console.log(track.getSettings());
track.stop();
there is a crash:
[30635:30668:0413/160535.641136:ERROR:service_manager.cc(477)] InterfaceProviderSpec prevented connection from: content_utility to: content_browser
Received signal 11 SEGV_MAPERR 0000000000c4
#0 0x7f365f98dd77 base::debug::StackTrace::StackTrace()
#1 0x7f365f98d8ef base::debug::(anonymous namespace)::StackDumpSignalHandler()
#2 0x7f365f6ba390 <unknown>
#3 0x7f365d806e6a content::MediaStreamVideoSource::GetCurrentFormat()
#4 0x7f365d809bd3 content::MediaStreamVideoTrack::GetSettings()
#5 0x7f365189c9e9 blink::MediaStreamTrack::getSettings()
#6 0x7f3651653594 blink::V8MediaStreamTrack::getSettingsMethodCallback()
#7 0x7f365a6583b0 v8::internal::FunctionCallbackArguments::Call()
#8 0x7f365a6fc448 v8::internal::(anonymous namespace)::HandleApiCallHelper<>()
#9 0x7f365a6fb9af v8::internal::Builtin_Impl_HandleApiCall()
#10 0x2f1bc17043fd <unknown>
There is no crash if using chrome-unstable (Google Chrome 59.0.3053.3). Let me report this and check how it behaves with the fix.
,
Apr 13 2017
A bug that produced a similar crash was recently fixed. Try using a more recent 59.
,
Apr 13 2017
Thanks. Closing this one as it is invalid. |
|||||||||||||||||||||||
►
Sign in to add a comment |
|||||||||||||||||||||||
Comment 1 by guidou@chromium.org
, Apr 13 2017