| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/common/gpu/media/android_video_encode_accelerator.h" | 5 #include "content/common/gpu/media/android_video_encode_accelerator.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 // encoder? Sure would be. Too bad it doesn't. So we hard-code some | 105 // encoder? Sure would be. Too bad it doesn't. So we hard-code some |
| 106 // reasonable defaults. | 106 // reasonable defaults. |
| 107 profile.max_resolution.SetSize(1920, 1088); | 107 profile.max_resolution.SetSize(1920, 1088); |
| 108 profile.max_framerate.numerator = 30; | 108 profile.max_framerate.numerator = 30; |
| 109 profile.max_framerate.denominator = 1; | 109 profile.max_framerate.denominator = 1; |
| 110 profiles.push_back(profile); | 110 profiles.push_back(profile); |
| 111 } | 111 } |
| 112 return profiles; | 112 return profiles; |
| 113 } | 113 } |
| 114 | 114 |
| 115 void AndroidVideoEncodeAccelerator::Initialize( | 115 bool AndroidVideoEncodeAccelerator::Initialize( |
| 116 VideoFrame::Format format, | 116 VideoFrame::Format format, |
| 117 const gfx::Size& input_visible_size, | 117 const gfx::Size& input_visible_size, |
| 118 media::VideoCodecProfile output_profile, | 118 media::VideoCodecProfile output_profile, |
| 119 uint32 initial_bitrate, | 119 uint32 initial_bitrate, |
| 120 Client* client) { | 120 Client* client) { |
| 121 DVLOG(3) << __PRETTY_FUNCTION__ << " format: " << format | 121 DVLOG(3) << __PRETTY_FUNCTION__ << " format: " << format |
| 122 << ", input_visible_size: " << input_visible_size.ToString() | 122 << ", input_visible_size: " << input_visible_size.ToString() |
| 123 << ", output_profile: " << output_profile | 123 << ", output_profile: " << output_profile |
| 124 << ", initial_bitrate: " << initial_bitrate; | 124 << ", initial_bitrate: " << initial_bitrate; |
| 125 DCHECK(!media_codec_); | 125 DCHECK(!media_codec_); |
| 126 DCHECK(thread_checker_.CalledOnValidThread()); | 126 DCHECK(thread_checker_.CalledOnValidThread()); |
| 127 | 127 |
| 128 client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client)); | 128 client_ptr_factory_.reset(new base::WeakPtrFactory<Client>(client)); |
| 129 | 129 |
| 130 RETURN_ON_FAILURE(media::MediaCodecBridge::SupportsSetParameters() && | 130 if (!(media::MediaCodecBridge::SupportsSetParameters() && |
| 131 format == VideoFrame::I420 && | 131 format == VideoFrame::I420 && |
| 132 output_profile == media::VP8PROFILE_MAIN, | 132 output_profile == media::VP8PROFILE_MAIN)) { |
| 133 "Unexpected combo: " << format << ", " << output_profile, | 133 DLOG(ERROR) << "Unexpected combo: " << format << ", " << output_profile; |
| 134 kInvalidArgumentError); | 134 return false; |
| 135 } |
| 135 | 136 |
| 136 last_set_bitrate_ = initial_bitrate; | 137 last_set_bitrate_ = initial_bitrate; |
| 137 | 138 |
| 138 // Only consider using MediaCodec if it's likely backed by hardware. | 139 // Only consider using MediaCodec if it's likely backed by hardware. |
| 139 RETURN_ON_FAILURE(!media::VideoCodecBridge::IsKnownUnaccelerated( | 140 if (media::VideoCodecBridge::IsKnownUnaccelerated( |
| 140 media::kCodecVP8, media::MEDIA_CODEC_ENCODER), | 141 media::kCodecVP8, media::MEDIA_CODEC_ENCODER)) { |
| 141 "No HW support", | 142 DLOG(ERROR) << "No HW support"; |
| 142 kPlatformFailureError); | 143 return false; |
| 144 } |
| 143 | 145 |
| 144 // TODO(fischman): when there is more HW out there with different color-space | 146 // TODO(fischman): when there is more HW out there with different color-space |
| 145 // support, this should turn into a negotiation with the codec for supported | 147 // support, this should turn into a negotiation with the codec for supported |
| 146 // formats. For now we use the only format supported by the only available | 148 // formats. For now we use the only format supported by the only available |
| 147 // HW. | 149 // HW. |
| 148 media_codec_.reset( | 150 media_codec_.reset( |
| 149 media::VideoCodecBridge::CreateEncoder(media::kCodecVP8, | 151 media::VideoCodecBridge::CreateEncoder(media::kCodecVP8, |
| 150 input_visible_size, | 152 input_visible_size, |
| 151 initial_bitrate, | 153 initial_bitrate, |
| 152 INITIAL_FRAMERATE, | 154 INITIAL_FRAMERATE, |
| 153 IFRAME_INTERVAL, | 155 IFRAME_INTERVAL, |
| 154 COLOR_FORMAT_YUV420_SEMIPLANAR)); | 156 COLOR_FORMAT_YUV420_SEMIPLANAR)); |
| 155 | 157 |
| 156 RETURN_ON_FAILURE( | 158 if (!media_codec_) { |
| 157 media_codec_, | 159 DLOG(ERROR) << "Failed to create/start the codec: " |
| 158 "Failed to create/start the codec: " << input_visible_size.ToString(), | 160 << input_visible_size.ToString(); |
| 159 kPlatformFailureError); | 161 return false; |
| 160 | 162 } |
| 161 base::MessageLoop::current()->PostTask( | |
| 162 FROM_HERE, | |
| 163 base::Bind(&VideoEncodeAccelerator::Client::NotifyInitializeDone, | |
| 164 client_ptr_factory_->GetWeakPtr())); | |
| 165 | 163 |
| 166 num_output_buffers_ = media_codec_->GetOutputBuffersCount(); | 164 num_output_buffers_ = media_codec_->GetOutputBuffersCount(); |
| 167 output_buffers_capacity_ = media_codec_->GetOutputBuffersCapacity(); | 165 output_buffers_capacity_ = media_codec_->GetOutputBuffersCapacity(); |
| 168 base::MessageLoop::current()->PostTask( | 166 base::MessageLoop::current()->PostTask( |
| 169 FROM_HERE, | 167 FROM_HERE, |
| 170 base::Bind(&VideoEncodeAccelerator::Client::RequireBitstreamBuffers, | 168 base::Bind(&VideoEncodeAccelerator::Client::RequireBitstreamBuffers, |
| 171 client_ptr_factory_->GetWeakPtr(), | 169 client_ptr_factory_->GetWeakPtr(), |
| 172 num_output_buffers_, | 170 num_output_buffers_, |
| 173 input_visible_size, | 171 input_visible_size, |
| 174 output_buffers_capacity_)); | 172 output_buffers_capacity_)); |
| 173 return true; |
| 175 } | 174 } |
| 176 | 175 |
| 177 void AndroidVideoEncodeAccelerator::MaybeStartIOTimer() { | 176 void AndroidVideoEncodeAccelerator::MaybeStartIOTimer() { |
| 178 if (!io_timer_.IsRunning() && | 177 if (!io_timer_.IsRunning() && |
| 179 (num_buffers_at_codec_ > 0 || !pending_frames_.empty())) { | 178 (num_buffers_at_codec_ > 0 || !pending_frames_.empty())) { |
| 180 io_timer_.Start(FROM_HERE, | 179 io_timer_.Start(FROM_HERE, |
| 181 EncodePollDelay(), | 180 EncodePollDelay(), |
| 182 this, | 181 this, |
| 183 &AndroidVideoEncodeAccelerator::DoIOTask); | 182 &AndroidVideoEncodeAccelerator::DoIOTask); |
| 184 } | 183 } |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 base::MessageLoop::current()->PostTask( | 404 base::MessageLoop::current()->PostTask( |
| 406 FROM_HERE, | 405 FROM_HERE, |
| 407 base::Bind(&VideoEncodeAccelerator::Client::BitstreamBufferReady, | 406 base::Bind(&VideoEncodeAccelerator::Client::BitstreamBufferReady, |
| 408 client_ptr_factory_->GetWeakPtr(), | 407 client_ptr_factory_->GetWeakPtr(), |
| 409 bitstream_buffer.id(), | 408 bitstream_buffer.id(), |
| 410 size, | 409 size, |
| 411 key_frame)); | 410 key_frame)); |
| 412 } | 411 } |
| 413 | 412 |
| 414 } // namespace content | 413 } // namespace content |
| OLD | NEW |