| 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::IsAvailable() && | 130 if (!(media::MediaCodecBridge::IsAvailable() && |
| 131 media::MediaCodecBridge::SupportsSetParameters() && | 131 media::MediaCodecBridge::SupportsSetParameters() && |
| 132 format == VideoFrame::I420 && | 132 format == VideoFrame::I420 && |
| 133 output_profile == media::VP8PROFILE_MAIN, | 133 output_profile == media::VP8PROFILE_MAIN)) { |
| 134 "Unexpected combo: " << format << ", " << output_profile, | 134 DLOG(ERROR) << "Unexpected combo: " << format << ", " << output_profile; |
| 135 kInvalidArgumentError); | 135 return false; |
| 136 } |
| 136 | 137 |
| 137 last_set_bitrate_ = initial_bitrate; | 138 last_set_bitrate_ = initial_bitrate; |
| 138 | 139 |
| 139 // Only consider using MediaCodec if it's likely backed by hardware. | 140 // Only consider using MediaCodec if it's likely backed by hardware. |
| 140 RETURN_ON_FAILURE(!media::VideoCodecBridge::IsKnownUnaccelerated( | 141 if (media::VideoCodecBridge::IsKnownUnaccelerated( |
| 141 media::kCodecVP8, media::MEDIA_CODEC_ENCODER), | 142 media::kCodecVP8, media::MEDIA_CODEC_ENCODER)) { |
| 142 "No HW support", | 143 DLOG(ERROR) << "No HW support"; |
| 143 kPlatformFailureError); | 144 return false; |
| 145 } |
| 144 | 146 |
| 145 // TODO(fischman): when there is more HW out there with different color-space | 147 // TODO(fischman): when there is more HW out there with different color-space |
| 146 // support, this should turn into a negotiation with the codec for supported | 148 // support, this should turn into a negotiation with the codec for supported |
| 147 // formats. For now we use the only format supported by the only available | 149 // formats. For now we use the only format supported by the only available |
| 148 // HW. | 150 // HW. |
| 149 media_codec_.reset( | 151 media_codec_.reset( |
| 150 media::VideoCodecBridge::CreateEncoder(media::kCodecVP8, | 152 media::VideoCodecBridge::CreateEncoder(media::kCodecVP8, |
| 151 input_visible_size, | 153 input_visible_size, |
| 152 initial_bitrate, | 154 initial_bitrate, |
| 153 INITIAL_FRAMERATE, | 155 INITIAL_FRAMERATE, |
| 154 IFRAME_INTERVAL, | 156 IFRAME_INTERVAL, |
| 155 COLOR_FORMAT_YUV420_SEMIPLANAR)); | 157 COLOR_FORMAT_YUV420_SEMIPLANAR)); |
| 156 | 158 |
| 157 RETURN_ON_FAILURE( | 159 if (!media_codec_) { |
| 158 media_codec_, | 160 DLOG(ERROR) << "Failed to create/start the codec: " |
| 159 "Failed to create/start the codec: " << input_visible_size.ToString(), | 161 << input_visible_size.ToString(); |
| 160 kPlatformFailureError); | 162 return false; |
| 161 | 163 } |
| 162 base::MessageLoop::current()->PostTask( | |
| 163 FROM_HERE, | |
| 164 base::Bind(&VideoEncodeAccelerator::Client::NotifyInitializeDone, | |
| 165 client_ptr_factory_->GetWeakPtr())); | |
| 166 | 164 |
| 167 num_output_buffers_ = media_codec_->GetOutputBuffersCount(); | 165 num_output_buffers_ = media_codec_->GetOutputBuffersCount(); |
| 168 output_buffers_capacity_ = media_codec_->GetOutputBuffersCapacity(); | 166 output_buffers_capacity_ = media_codec_->GetOutputBuffersCapacity(); |
| 169 base::MessageLoop::current()->PostTask( | 167 base::MessageLoop::current()->PostTask( |
| 170 FROM_HERE, | 168 FROM_HERE, |
| 171 base::Bind(&VideoEncodeAccelerator::Client::RequireBitstreamBuffers, | 169 base::Bind(&VideoEncodeAccelerator::Client::RequireBitstreamBuffers, |
| 172 client_ptr_factory_->GetWeakPtr(), | 170 client_ptr_factory_->GetWeakPtr(), |
| 173 num_output_buffers_, | 171 num_output_buffers_, |
| 174 input_visible_size, | 172 input_visible_size, |
| 175 output_buffers_capacity_)); | 173 output_buffers_capacity_)); |
| 174 return true; |
| 176 } | 175 } |
| 177 | 176 |
| 178 void AndroidVideoEncodeAccelerator::MaybeStartIOTimer() { | 177 void AndroidVideoEncodeAccelerator::MaybeStartIOTimer() { |
| 179 if (!io_timer_.IsRunning() && | 178 if (!io_timer_.IsRunning() && |
| 180 (num_buffers_at_codec_ > 0 || !pending_frames_.empty())) { | 179 (num_buffers_at_codec_ > 0 || !pending_frames_.empty())) { |
| 181 io_timer_.Start(FROM_HERE, | 180 io_timer_.Start(FROM_HERE, |
| 182 EncodePollDelay(), | 181 EncodePollDelay(), |
| 183 this, | 182 this, |
| 184 &AndroidVideoEncodeAccelerator::DoIOTask); | 183 &AndroidVideoEncodeAccelerator::DoIOTask); |
| 185 } | 184 } |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 406 base::MessageLoop::current()->PostTask( | 405 base::MessageLoop::current()->PostTask( |
| 407 FROM_HERE, | 406 FROM_HERE, |
| 408 base::Bind(&VideoEncodeAccelerator::Client::BitstreamBufferReady, | 407 base::Bind(&VideoEncodeAccelerator::Client::BitstreamBufferReady, |
| 409 client_ptr_factory_->GetWeakPtr(), | 408 client_ptr_factory_->GetWeakPtr(), |
| 410 bitstream_buffer.id(), | 409 bitstream_buffer.id(), |
| 411 size, | 410 size, |
| 412 key_frame)); | 411 key_frame)); |
| 413 } | 412 } |
| 414 | 413 |
| 415 } // namespace content | 414 } // namespace content |
| OLD | NEW |