Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(671)

Side by Side Diff: content/renderer/media/media_recorder_handler.cc

Issue 1534553003: MediaRecorder: correct MIME type parsing (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: updated content_unittests, updated vp9 handling Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/renderer/media/media_recorder_handler.h" 5 #include "content/renderer/media/media_recorder_handler.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/location.h" 8 #include "base/location.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/strings/string_tokenizer.h" 10 #include "base/strings/string_tokenizer.h"
11 #include "base/strings/string_util.h" 11 #include "base/strings/string_util.h"
12 #include "content/renderer/media/audio_track_recorder.h" 12 #include "content/renderer/media/audio_track_recorder.h"
13 #include "content/renderer/media/media_stream_track.h" 13 #include "content/renderer/media/media_stream_track.h"
14 #include "content/renderer/media/video_track_recorder.h" 14 #include "content/renderer/media/video_track_recorder.h"
15 #include "content/renderer/media/webrtc_uma_histograms.h" 15 #include "content/renderer/media/webrtc_uma_histograms.h"
16 #include "media/audio/audio_parameters.h" 16 #include "media/audio/audio_parameters.h"
17 #include "media/base/audio_bus.h" 17 #include "media/base/audio_bus.h"
18 #include "media/base/bind_to_current_loop.h" 18 #include "media/base/bind_to_current_loop.h"
19 #include "media/base/mime_util.h"
19 #include "media/base/video_frame.h" 20 #include "media/base/video_frame.h"
20 #include "media/capture/webm_muxer.h" 21 #include "media/capture/webm_muxer.h"
21 #include "third_party/WebKit/public/platform/WebMediaRecorderHandlerClient.h" 22 #include "third_party/WebKit/public/platform/WebMediaRecorderHandlerClient.h"
22 #include "third_party/WebKit/public/platform/WebString.h" 23 #include "third_party/WebKit/public/platform/WebString.h"
23 24
24 using base::TimeDelta; 25 using base::TimeDelta;
25 using base::TimeTicks; 26 using base::TimeTicks;
26 27
27 namespace content { 28 namespace content {
28 29
29 MediaRecorderHandler::MediaRecorderHandler() 30 MediaRecorderHandler::MediaRecorderHandler()
30 : use_vp9_(false), 31 : use_vp9_(false),
31 recording_(false), 32 recording_(false),
32 client_(nullptr), 33 client_(nullptr),
33 weak_factory_(this) {} 34 weak_factory_(this) {}
34 35
35 MediaRecorderHandler::~MediaRecorderHandler() { 36 MediaRecorderHandler::~MediaRecorderHandler() {
36 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 37 DCHECK(main_render_thread_checker_.CalledOnValidThread());
37 // Send a |last_in_slice| to our |client_|. 38 // Send a |last_in_slice| to our |client_|.
38 if (client_) 39 if (client_)
39 client_->writeData(nullptr, 0u, true); 40 client_->writeData(nullptr, 0u, true);
40 } 41 }
41 42
42 bool MediaRecorderHandler::canSupportMimeType( 43 bool MediaRecorderHandler::canSupportMimeType(
43 const blink::WebString& mimeType) { 44 const blink::WebString& type, const blink::WebString& codecs) {
44 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 45 DCHECK(main_render_thread_checker_.CalledOnValidThread());
45 // Ensure we can support each passed MIME type. 46 if (type.utf8().empty())
tommi (sloooow) - chröme 2015/12/18 10:06:30 utf8() creates a new std::string every time you ca
mcasas 2015/12/18 21:27:44 Done.
46 const std::string input = mimeType.utf8(); // Must outlive tokenizer! 47 return true;
tommi (sloooow) - chröme 2015/12/18 10:06:29 Is it right to say we can support an empty mime ty
mcasas 2015/12/18 21:27:44 There is a bit of confusion in the spec about it,
philipj_slow 2016/01/26 04:30:28 See discussion in https://github.com/w3c/mediacapt
47 base::StringTokenizer tokenizer(input, ","); 48 // Supported |type|s are {video,audio}/webm. Both support empty |codecs|,
48 while (tokenizer.GetNext()) { 49 // |type| == "video" supports vp8, vp9 or opus; "audio", supports only opus.
49 // Strip whitespace. 50 // http://www.webmproject.org/docs/container/, "HTML5 Video Type Parameters"
50 const std::string token(base::CollapseWhitespaceASCII( 51 if ((base::EqualsCaseInsensitiveASCII(type.utf8(), "video/webm") ||
51 tokenizer.token(), true /* trim sequences with line breaks*/)); 52 base::EqualsCaseInsensitiveASCII(type.utf8(), "audio/webm")) &&
52 if (!token.empty() && 53 codecs.utf8().empty()) {
tommi (sloooow) - chröme 2015/12/18 10:06:29 codecs.isEmpty() Looks like this will then be the
mcasas 2015/12/18 21:27:44 Refactored.
53 !base::EqualsCaseInsensitiveASCII(token, "video/vp8") && 54 return true;
54 !base::EqualsCaseInsensitiveASCII(token, "video/vp9") &&
55 !base::EqualsCaseInsensitiveASCII(token, "audio/opus") &&
56 !base::EqualsCaseInsensitiveASCII(token, "video/webm") &&
57 !base::EqualsCaseInsensitiveASCII(token, "audio/webm")) {
58 return false;
59 }
60 } 55 }
61 56
62 return true; 57 std::vector<std::string> codecs_list;
58 media::ParseCodecString(codecs.utf8(), &codecs_list, true /* strip */);
59 if (base::EqualsCaseInsensitiveASCII(type.utf8(), "video/webm")) {
tommi (sloooow) - chröme 2015/12/18 10:06:30 this check has already been done before
mcasas 2015/12/18 21:27:45 Refactored.
60 for (const auto& codec : codecs_list) {
61 if (!base::EqualsCaseInsensitiveASCII(codec, "vp8") &&
62 !base::EqualsCaseInsensitiveASCII(codec, "vp9") &&
63 !base::EqualsCaseInsensitiveASCII(codec, "opus")) {
64 return false;
65 }
66 }
67 return true;
68 }
69 if (base::EqualsCaseInsensitiveASCII(type.utf8(), "audio/webm")) {
tommi (sloooow) - chröme 2015/12/18 10:06:30 this check might have been done before
mcasas 2015/12/18 21:27:45 Refactored.
70 for (const auto& codec : codecs_list) {
71 if (!base::EqualsCaseInsensitiveASCII(codec, "opus"))
72 return false;
73 }
74 return true;
75 }
76 return false;
tommi (sloooow) - chröme 2015/12/18 10:06:30 Here's an alternate implementation proposal that h
mcasas 2015/12/18 21:27:45 Gosh, almost right first time! Done.
63 } 77 }
64 78
65 bool MediaRecorderHandler::initialize( 79 bool MediaRecorderHandler::initialize(
66 blink::WebMediaRecorderHandlerClient* client, 80 blink::WebMediaRecorderHandlerClient* client,
67 const blink::WebMediaStream& media_stream, 81 const blink::WebMediaStream& media_stream,
68 const blink::WebString& mimeType) { 82 const blink::WebString& type,
83 const blink::WebString& codecs) {
69 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 84 DCHECK(main_render_thread_checker_.CalledOnValidThread());
70 // Save histogram data so we can see how much MediaStream Recorder is used. 85 // Save histogram data so we can see how much MediaStream Recorder is used.
71 // The histogram counts the number of calls to the JS API. 86 // The histogram counts the number of calls to the JS API.
72 UpdateWebRTCMethodCount(WEBKIT_MEDIA_STREAM_RECORDER); 87 UpdateWebRTCMethodCount(WEBKIT_MEDIA_STREAM_RECORDER);
73 88
74 if (!canSupportMimeType(mimeType)) { 89 if (!canSupportMimeType(type, codecs)) {
75 DLOG(ERROR) << "Can't support type " << mimeType.utf8(); 90 DLOG(ERROR) << "Can't support " << type.utf8()
91 << ";codecs=" << codecs.utf8();
76 return false; 92 return false;
77 } 93 }
78 use_vp9_ = mimeType.utf8().compare("video/vp9") == 0; 94 use_vp9_ = codecs.utf8().find("vp9") != std::string::npos;
tommi (sloooow) - chröme 2015/12/18 10:06:29 this isn't case sensitive like the code in canSupp
mcasas 2015/12/18 21:27:45 Done.
79 media_stream_ = media_stream; 95 media_stream_ = media_stream;
80 DCHECK(client); 96 DCHECK(client);
81 client_ = client; 97 client_ = client;
82 98
83 return true; 99 return true;
84 } 100 }
85 101
86 bool MediaRecorderHandler::start() { 102 bool MediaRecorderHandler::start() {
87 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 103 DCHECK(main_render_thread_checker_.CalledOnValidThread());
88 DCHECK(!recording_); 104 DCHECK(!recording_);
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 recorder->OnData(audio_bus, timestamp); 255 recorder->OnData(audio_bus, timestamp);
240 } 256 }
241 257
242 void MediaRecorderHandler::SetAudioFormatForTesting( 258 void MediaRecorderHandler::SetAudioFormatForTesting(
243 const media::AudioParameters& params) { 259 const media::AudioParameters& params) {
244 for (auto* recorder : audio_recorders_) 260 for (auto* recorder : audio_recorders_)
245 recorder->OnSetFormat(params); 261 recorder->OnSetFormat(params);
246 } 262 }
247 263
248 } // namespace content 264 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698