1c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// found in the LICENSE file. 4c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 5c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/renderer/media/webrtc/video_destination_handler.h" 6c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 7c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include <string> 8c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 9c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/base64.h" 10c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/logging.h" 11c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/rand_util.h" 12c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/strings/utf_string_conversions.h" 13c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/renderer/media/media_stream.h" 14c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/renderer/media/media_stream_registry_interface.h" 15c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/renderer/media/media_stream_video_track.h" 16c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/renderer/pepper/ppb_image_data_impl.h" 17c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/renderer/render_thread_impl.h" 18c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "media/video/capture/video_capture_types.h" 19c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" 20c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "third_party/WebKit/public/platform/WebURL.h" 21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "third_party/WebKit/public/web/WebMediaStreamRegistry.h" 22c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "third_party/libyuv/include/libyuv/convert.h" 23c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "url/gurl.h" 24c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochnamespace content { 26c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 27010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class PpFrameWriter::FrameWriterDelegate 28010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : public base::RefCountedThreadSafe<FrameWriterDelegate> { 29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) public: 30010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) FrameWriterDelegate( 31010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy, 32010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const VideoCaptureDeliverFrameCB& new_frame_callback); 33010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 34010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) void DeliverFrame(const scoped_refptr<media::VideoFrame>& frame, 35010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const media::VideoCaptureFormat& format); 36010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) private: 37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) friend class base::RefCountedThreadSafe<FrameWriterDelegate>; 38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) virtual ~FrameWriterDelegate(); 39010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 40010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) void DeliverFrameOnIO(const scoped_refptr<media::VideoFrame>& frame, 41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const media::VideoCaptureFormat& format); 42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) scoped_refptr<base::MessageLoopProxy> io_message_loop_; 44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VideoCaptureDeliverFrameCB new_frame_callback_; 45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}; 46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)PpFrameWriter::FrameWriterDelegate::FrameWriterDelegate( 48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy, 49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const VideoCaptureDeliverFrameCB& new_frame_callback) 50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) : io_message_loop_(io_message_loop_proxy), 51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) new_frame_callback_(new_frame_callback) { 52010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)PpFrameWriter::FrameWriterDelegate::~FrameWriterDelegate() { 55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void PpFrameWriter::FrameWriterDelegate::DeliverFrame( 58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const scoped_refptr<media::VideoFrame>& frame, 59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const media::VideoCaptureFormat& format) { 60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) io_message_loop_->PostTask( 61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) FROM_HERE, 62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Bind(&FrameWriterDelegate::DeliverFrameOnIO, 63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) this, frame, format)); 64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void PpFrameWriter::FrameWriterDelegate::DeliverFrameOnIO( 67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const scoped_refptr<media::VideoFrame>& frame, 68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const media::VideoCaptureFormat& format) { 69010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) DCHECK(io_message_loop_->BelongsToCurrentThread()); 7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // The local time when this frame is generated is unknown so give a null 7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // value to |estimated_capture_time|. 7246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) new_frame_callback_.Run(frame, format, base::TimeTicks()); 73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} 74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)PpFrameWriter::PpFrameWriter() { 76c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DVLOG(3) << "PpFrameWriter ctor"; 77c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 78c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 79c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochPpFrameWriter::~PpFrameWriter() { 80c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DVLOG(3) << "PpFrameWriter dtor"; 81c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 82c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void PpFrameWriter::GetCurrentSupportedFormats( 84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int max_requested_width, 85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int max_requested_height, 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) double max_requested_frame_rate, 87010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const VideoCaptureDeviceFormatsCB& callback) { 88c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(CalledOnValidThread()); 89c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DVLOG(3) << "PpFrameWriter::GetCurrentSupportedFormats()"; 90010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Since the input is free to change the resolution at any point in time 91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // the supported formats are unknown. 92010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) media::VideoCaptureFormats formats; 93010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) callback.Run(formats); 94c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 95c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 96c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid PpFrameWriter::StartSourceImpl( 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const media::VideoCaptureFormat& format, 98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const VideoCaptureDeliverFrameCB& frame_callback) { 99c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(CalledOnValidThread()); 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!delegate_.get()); 101c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DVLOG(3) << "PpFrameWriter::StartSourceImpl()"; 102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) delegate_ = new FrameWriterDelegate(io_message_loop(), frame_callback); 1036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) OnStartDone(MEDIA_DEVICE_OK); 104c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 105c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 106c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid PpFrameWriter::StopSourceImpl() { 107c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(CalledOnValidThread()); 108c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 109c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 110c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid PpFrameWriter::PutFrame(PPB_ImageData_Impl* image_data, 111c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int64 time_stamp_ns) { 112c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(CalledOnValidThread()); 113c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DVLOG(3) << "PpFrameWriter::PutFrame()"; 114c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 115c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!image_data) { 116c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch LOG(ERROR) << "PpFrameWriter::PutFrame - Called with NULL image_data."; 117c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 118c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 119c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ImageDataAutoMapper mapper(image_data); 120c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!mapper.is_valid()) { 121c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch LOG(ERROR) << "PpFrameWriter::PutFrame - " 122c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch << "The image could not be mapped and is unusable."; 123c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 124c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 125c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const SkBitmap* bitmap = image_data->GetMappedBitmap(); 126c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!bitmap) { 127c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch LOG(ERROR) << "PpFrameWriter::PutFrame - " 128c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch << "The image_data's mapped bitmap is NULL."; 129c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 132c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const gfx::Size frame_size(bitmap->width(), bitmap->height()); 133c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 134c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (state() != MediaStreamVideoSource::STARTED) 135c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 136c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1370529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const base::TimeDelta timestamp = base::TimeDelta::FromMicroseconds( 1380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch time_stamp_ns / base::Time::kNanosecondsPerMicrosecond); 139c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 140c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // TODO(perkj): It would be more efficient to use I420 here. Using YV12 will 141c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // force a copy into a tightly packed I420 frame in 142c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // WebRtcVideoCapturerAdapter before the frame is delivered to libJingle. 143c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // crbug/359587. 144c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch scoped_refptr<media::VideoFrame> new_frame = 145c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch frame_pool_.CreateFrame(media::VideoFrame::YV12, frame_size, 146c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch gfx::Rect(frame_size), frame_size, timestamp); 147010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) media::VideoCaptureFormat format( 148010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) frame_size, 1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MediaStreamVideoSource::kUnknownFrameRate, 150010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) media::PIXEL_FORMAT_YV12); 151c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 152c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch libyuv::BGRAToI420(reinterpret_cast<uint8*>(bitmap->getPixels()), 153c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bitmap->rowBytes(), 154c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch new_frame->data(media::VideoFrame::kYPlane), 155c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch new_frame->stride(media::VideoFrame::kYPlane), 156c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch new_frame->data(media::VideoFrame::kUPlane), 157c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch new_frame->stride(media::VideoFrame::kUPlane), 158c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch new_frame->data(media::VideoFrame::kVPlane), 159c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch new_frame->stride(media::VideoFrame::kVPlane), 160c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch frame_size.width(), frame_size.height()); 161c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 162010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) delegate_->DeliverFrame(new_frame, format); 163c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 164c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 165c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// PpFrameWriterProxy is a helper class to make sure the user won't use 166c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// PpFrameWriter after it is released (IOW its owner - WebMediaStreamSource - 167c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// is released). 168c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochclass PpFrameWriterProxy : public FrameWriterInterface { 169c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch public: 170c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch explicit PpFrameWriterProxy(const base::WeakPtr<PpFrameWriter>& writer) 171c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch : writer_(writer) { 172c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(writer_ != NULL); 173c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 174c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 175c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch virtual ~PpFrameWriterProxy() {} 176c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 177c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch virtual void PutFrame(PPB_ImageData_Impl* image_data, 178c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch int64 time_stamp_ns) OVERRIDE { 179c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch writer_->PutFrame(image_data, time_stamp_ns); 180c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 181c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 182c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch private: 183c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::WeakPtr<PpFrameWriter> writer_; 184c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 185c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DISALLOW_COPY_AND_ASSIGN(PpFrameWriterProxy); 186c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}; 187c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 188c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochbool VideoDestinationHandler::Open( 189c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch MediaStreamRegistryInterface* registry, 190c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const std::string& url, 191c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch FrameWriterInterface** frame_writer) { 192c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DVLOG(3) << "VideoDestinationHandler::Open"; 193c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch blink::WebMediaStream stream; 194c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (registry) { 195c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch stream = registry->GetMediaStream(url); 196c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } else { 197c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch stream = 198c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch blink::WebMediaStreamRegistry::lookupMediaStreamDescriptor(GURL(url)); 199c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 200c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (stream.isNull()) { 201c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch LOG(ERROR) << "VideoDestinationHandler::Open - invalid url: " << url; 202c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return false; 203c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 204c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 205c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Create a new native video track and add it to |stream|. 206c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch std::string track_id; 207c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // According to spec, a media stream source's id should be unique per 208c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // application. There's no easy way to strictly achieve that. The id 209c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // generated with this method should be unique for most of the cases but 210c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // theoretically it's possible we can get an id that's duplicated with the 211c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // existing sources. 212c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::Base64Encode(base::RandBytesAsString(64), &track_id); 213010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 2140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch PpFrameWriter* writer = new PpFrameWriter(); 215c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 216c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Create a new webkit video track. 217c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch blink::WebMediaStreamSource webkit_source; 218c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch blink::WebMediaStreamSource::Type type = 219c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch blink::WebMediaStreamSource::TypeVideo; 220c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch blink::WebString webkit_track_id = base::UTF8ToUTF16(track_id); 221c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch webkit_source.initialize(webkit_track_id, type, webkit_track_id); 222c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch webkit_source.setExtraData(writer); 223c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 224c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch blink::WebMediaConstraints constraints; 225c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch constraints.initialize(); 226c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch bool track_enabled = true; 227c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 228c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch stream.addTrack(MediaStreamVideoTrack::CreateVideoTrack( 229c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch writer, constraints, MediaStreamVideoSource::ConstraintsCallback(), 2300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch track_enabled)); 231c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 232c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch *frame_writer = new PpFrameWriterProxy(writer->AsWeakPtr()); 233c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return true; 234c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 235c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 236c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} // namespace content 237