| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/rtc_video_decoder.h" | 5 #include "content/renderer/media/rtc_video_decoder.h" |
| 6 | 6 |
| 7 #include <deque> | 7 #include <deque> |
| 8 | 8 |
| 9 #include "base/task.h" | 9 #include "base/task.h" |
| 10 #include "media/base/callback.h" | 10 #include "media/base/callback.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 using media::kNoTimestamp; | 24 using media::kNoTimestamp; |
| 25 using media::Limits; | 25 using media::Limits; |
| 26 using media::PIPELINE_OK; | 26 using media::PIPELINE_OK; |
| 27 using media::StatisticsCallback; | 27 using media::StatisticsCallback; |
| 28 using media::VideoDecoder; | 28 using media::VideoDecoder; |
| 29 using media::VideoFrame; | 29 using media::VideoFrame; |
| 30 | 30 |
| 31 RTCVideoDecoder::RTCVideoDecoder(MessageLoop* message_loop, | 31 RTCVideoDecoder::RTCVideoDecoder(MessageLoop* message_loop, |
| 32 const std::string& url) | 32 const std::string& url) |
| 33 : message_loop_(message_loop), | 33 : message_loop_(message_loop), |
| 34 width_(176), | 34 visible_size_(176, 144), |
| 35 height_(144), | |
| 36 url_(url), | 35 url_(url), |
| 37 state_(kUnInitialized) { | 36 state_(kUnInitialized) { |
| 38 } | 37 } |
| 39 | 38 |
| 40 RTCVideoDecoder::~RTCVideoDecoder() {} | 39 RTCVideoDecoder::~RTCVideoDecoder() {} |
| 41 | 40 |
| 42 void RTCVideoDecoder::Initialize(DemuxerStream* demuxer_stream, | 41 void RTCVideoDecoder::Initialize(DemuxerStream* demuxer_stream, |
| 43 FilterCallback* filter_callback, | 42 FilterCallback* filter_callback, |
| 44 StatisticsCallback* stat_callback) { | 43 StatisticsCallback* stat_callback) { |
| 45 if (MessageLoop::current() != message_loop_) { | 44 if (MessageLoop::current() != message_loop_) { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 message_loop_->PostTask(FROM_HERE, | 117 message_loop_->PostTask(FROM_HERE, |
| 119 NewRunnableMethod(this, &RTCVideoDecoder::Seek, | 118 NewRunnableMethod(this, &RTCVideoDecoder::Seek, |
| 120 time, cb)); | 119 time, cb)); |
| 121 return; | 120 return; |
| 122 } | 121 } |
| 123 | 122 |
| 124 DCHECK_EQ(MessageLoop::current(), message_loop_); | 123 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 125 | 124 |
| 126 state_ = kSeeking; | 125 state_ = kSeeking; |
| 127 // Create output buffer pool and pass the frames to renderer | 126 // Create output buffer pool and pass the frames to renderer |
| 128 // so that the renderer can complete the seeking | 127 // so that the renderer can complete the seeking. |
| 129 for (size_t i = 0; i < Limits::kMaxVideoFrames; ++i) { | 128 for (size_t i = 0; i < Limits::kMaxVideoFrames; ++i) { |
| 130 VideoFrameReady(VideoFrame::CreateBlackFrame(width_, height_)); | 129 VideoFrameReady(VideoFrame::CreateBlackFrame( |
| 130 visible_size_.width(), visible_size_.height())); |
| 131 } | 131 } |
| 132 | 132 |
| 133 state_ = kNormal; | 133 state_ = kNormal; |
| 134 | 134 |
| 135 cb.Run(PIPELINE_OK); | 135 cb.Run(PIPELINE_OK); |
| 136 } | 136 } |
| 137 | 137 |
| 138 void RTCVideoDecoder::ProduceVideoFrame( | 138 void RTCVideoDecoder::ProduceVideoFrame( |
| 139 scoped_refptr<VideoFrame> video_frame) { | 139 scoped_refptr<VideoFrame> video_frame) { |
| 140 if (MessageLoop::current() != message_loop_) { | 140 if (MessageLoop::current() != message_loop_) { |
| 141 message_loop_->PostTask( | 141 message_loop_->PostTask( |
| 142 FROM_HERE, | 142 FROM_HERE, |
| 143 NewRunnableMethod(this, | 143 NewRunnableMethod(this, |
| 144 &RTCVideoDecoder::ProduceVideoFrame, video_frame)); | 144 &RTCVideoDecoder::ProduceVideoFrame, video_frame)); |
| 145 return; | 145 return; |
| 146 } | 146 } |
| 147 DCHECK_EQ(MessageLoop::current(), message_loop_); | 147 DCHECK_EQ(MessageLoop::current(), message_loop_); |
| 148 base::AutoLock auto_lock(lock_); | 148 base::AutoLock auto_lock(lock_); |
| 149 frame_queue_available_.push_back(video_frame); | 149 frame_queue_available_.push_back(video_frame); |
| 150 } | 150 } |
| 151 | 151 |
| 152 int RTCVideoDecoder::width() { | 152 gfx::Size RTCVideoDecoder::natural_size() { |
| 153 return width_; | 153 // TODO(vrk): Return natural size when aspect ratio support is implemented. |
| 154 } | 154 return visible_size_; |
| 155 | |
| 156 int RTCVideoDecoder::height() { | |
| 157 return height_; | |
| 158 } | 155 } |
| 159 | 156 |
| 160 bool RTCVideoDecoder::SetSize(int width, int height, int reserved) { | 157 bool RTCVideoDecoder::SetSize(int width, int height, int reserved) { |
| 161 width_ = width; | 158 visible_size_.SetSize(width, height); |
| 162 height_ = height; | |
| 163 | 159 |
| 164 host()->SetVideoSize(width_, height_); | 160 // TODO(vrk): Provide natural size when aspect ratio support is implemented. |
| 161 host()->SetNaturalVideoSize(visible_size_); |
| 165 return true; | 162 return true; |
| 166 } | 163 } |
| 167 | 164 |
| 168 bool RTCVideoDecoder::RenderFrame(const cricket::VideoFrame* frame) { | 165 bool RTCVideoDecoder::RenderFrame(const cricket::VideoFrame* frame) { |
| 169 DCHECK(frame); | 166 DCHECK(frame); |
| 170 | 167 |
| 171 if (state_ != kNormal) | 168 if (state_ != kNormal) |
| 172 return true; | 169 return true; |
| 173 | 170 |
| 174 // This is called from another thread | 171 // This is called from another thread. |
| 175 scoped_refptr<VideoFrame> video_frame; | 172 scoped_refptr<VideoFrame> video_frame; |
| 176 { | 173 { |
| 177 base::AutoLock auto_lock(lock_); | 174 base::AutoLock auto_lock(lock_); |
| 178 if (frame_queue_available_.size() == 0) { | 175 if (frame_queue_available_.size() == 0) { |
| 179 return true; | 176 return true; |
| 180 } | 177 } |
| 181 video_frame = frame_queue_available_.front(); | 178 video_frame = frame_queue_available_.front(); |
| 182 frame_queue_available_.pop_front(); | 179 frame_queue_available_.pop_front(); |
| 183 } | 180 } |
| 184 | 181 |
| 185 // Check if there's a size change | 182 // Check if there's a size change. |
| 186 if (video_frame->width() != width_ || video_frame->height() != height_) { | 183 // TODO(vrk): Remove casts when media::VideoFrame is updated with gfx::Sizes |
| 187 // Allocate new buffer based on the new size | 184 // for width/height. |
| 185 if (video_frame->width() != static_cast<size_t>(visible_size_.width()) || |
| 186 video_frame->height() != static_cast<size_t>(visible_size_.height())) { |
| 187 // Allocate new buffer based on the new size. |
| 188 video_frame = VideoFrame::CreateFrame(VideoFrame::YV12, | 188 video_frame = VideoFrame::CreateFrame(VideoFrame::YV12, |
| 189 width_, | 189 visible_size_.width(), |
| 190 height_, | 190 visible_size_.height(), |
| 191 kNoTimestamp, | 191 kNoTimestamp, |
| 192 kNoTimestamp); | 192 kNoTimestamp); |
| 193 } | 193 } |
| 194 | 194 |
| 195 // Only YV12 frames are supported. |
| 196 DCHECK(video_frame->format() == VideoFrame::YV12); |
| 197 // Aspect ratio unsupported; DCHECK when there are non-square pixels. |
| 198 DCHECK(frame->GetPixelWidth() == 1); |
| 199 DCHECK(frame->GetPixelHeight() == 1); |
| 195 video_frame->SetTimestamp(host()->GetTime()); | 200 video_frame->SetTimestamp(host()->GetTime()); |
| 196 video_frame->SetDuration(base::TimeDelta::FromMilliseconds(30)); | 201 video_frame->SetDuration(base::TimeDelta::FromMilliseconds(30)); |
| 197 | 202 |
| 198 int y_rows = frame->GetHeight(); | 203 int y_rows = frame->GetHeight(); |
| 199 int uv_rows = frame->GetHeight() / 2; // YV12 format. | 204 int uv_rows = frame->GetHeight() / 2; // YV12 format. |
| 200 CopyYPlane(frame->GetYPlane(), frame->GetYPitch(), y_rows, video_frame); | 205 CopyYPlane(frame->GetYPlane(), frame->GetYPitch(), y_rows, video_frame); |
| 201 CopyUPlane(frame->GetUPlane(), frame->GetUPitch(), uv_rows, video_frame); | 206 CopyUPlane(frame->GetUPlane(), frame->GetUPitch(), uv_rows, video_frame); |
| 202 CopyVPlane(frame->GetVPlane(), frame->GetVPitch(), uv_rows, video_frame); | 207 CopyVPlane(frame->GetVPlane(), frame->GetVPitch(), uv_rows, video_frame); |
| 203 | 208 |
| 204 if (MessageLoop::current() != message_loop_) { | 209 if (MessageLoop::current() != message_loop_) { |
| 205 message_loop_->PostTask( | 210 message_loop_->PostTask( |
| 206 FROM_HERE, | 211 FROM_HERE, |
| 207 NewRunnableMethod(this, | 212 NewRunnableMethod(this, |
| 208 &RTCVideoDecoder::VideoFrameReady, | 213 &RTCVideoDecoder::VideoFrameReady, |
| 209 video_frame)); | 214 video_frame)); |
| 210 } else { | 215 } else { |
| 211 VideoFrameReady(video_frame); | 216 VideoFrameReady(video_frame); |
| 212 } | 217 } |
| 213 | 218 |
| 214 return true; | 219 return true; |
| 215 } | 220 } |
| OLD | NEW |