Chromium Code Reviews| Index: content/common/gpu/media/mac_video_decode_accelerator.mm |
| diff --git a/content/common/gpu/media/mac_video_decode_accelerator.mm b/content/common/gpu/media/mac_video_decode_accelerator.mm |
| index a68b4d22c41114c19af4a5be6c20040fd812b2d0..14c104cf99e0569159b8e54f3235d4d8c04c63a9 100644 |
| --- a/content/common/gpu/media/mac_video_decode_accelerator.mm |
| +++ b/content/common/gpu/media/mac_video_decode_accelerator.mm |
| @@ -85,34 +85,13 @@ MacVideoDecodeAccelerator::MacVideoDecodeAccelerator( |
| media::VideoDecodeAccelerator::Client* client) |
| : client_(client), |
| cgl_context_(NULL), |
| - nalu_len_field_size_(0), |
| - frame_width_(0), |
| - frame_height_(0), |
| - did_request_pictures_(false) { |
| + did_build_config_record_(false) { |
| } |
| void MacVideoDecodeAccelerator::SetGLContext(void* gl_context) { |
| cgl_context_ = static_cast<CGLContextObj>(gl_context); |
| } |
| -bool MacVideoDecodeAccelerator::SetConfigInfo( |
| - uint32_t frame_width, |
| - uint32_t frame_height, |
| - const std::vector<uint8_t>& avc_data) { |
| - frame_width_ = frame_width; |
| - frame_height_ = frame_height; |
| - nalu_len_field_size_ = (avc_data[4] & 0x03) + 1; |
| - |
| - DCHECK(!vda_.get()); |
| - vda_ = new gfx::VideoDecodeAccelerationSupport(); |
| - gfx::VideoDecodeAccelerationSupport::Status status = vda_->Create( |
| - frame_width_, frame_height_, |
| - kCVPixelFormatType_422YpCbCr8, &avc_data.front(), avc_data.size()); |
| - if (status != gfx::VideoDecodeAccelerationSupport::VDA_SUCCESS) |
| - return false; |
| - return true; |
| -} |
| - |
| bool MacVideoDecodeAccelerator::Initialize(media::VideoCodecProfile profile) { |
| if (client_) |
| client_->NotifyInitializeDone(); |
| @@ -127,44 +106,44 @@ void MacVideoDecodeAccelerator::Decode( |
| return; |
| } |
| - size_t buffer_size = bitstream_buffer.size(); |
| - if (buffer_size < nalu_len_field_size_ + 1) { |
| - if (client_) |
| - client_->NotifyEndOfBitstreamBuffer(bitstream_buffer.id()); |
| - return; |
| - } |
| - |
| - // The decoder can only handle slice types (1-5). |
| - const uint8_t* buffer = static_cast<const uint8_t*>(memory.memory()); |
| - uint8_t nalu_type = buffer[nalu_len_field_size_] & 0x1f; |
| - if (nalu_type < 1 || nalu_type > 5) { |
| - if (client_) |
| - client_->NotifyEndOfBitstreamBuffer(bitstream_buffer.id()); |
| - return; |
| - } |
| - |
| - // Keep a ref counted copy of the buffer. |
| - std::vector<uint8_t> vector(buffer, buffer + buffer_size); |
| - scoped_refptr<base::RefCountedBytes> bytes( |
| - base::RefCountedBytes::TakeVector(&vector)); |
| - |
| - // Store the buffer size at the beginning of the buffer as the decoder |
| - // expects. |
| - size_t frame_buffer_size = buffer_size - nalu_len_field_size_; |
| - for (size_t i = 0; i < nalu_len_field_size_; ++i) { |
| - size_t shift = nalu_len_field_size_ * 8 - (i + 1) * 8; |
| - bytes->data()[i] = (frame_buffer_size >> shift) & 0xff; |
| - } |
| - |
| - vda_->Decode(bytes->front(), bytes->size(), |
| - base::Bind(&MacVideoDecodeAccelerator::OnFrameReady, this, |
| - bitstream_buffer.id(), bytes)); |
| - |
| - if (!did_request_pictures_) { |
| - did_request_pictures_ = true; |
| - if (client_) |
| - client_->ProvidePictureBuffers( |
| - kNumPictureBuffers, gfx::Size(frame_width_, frame_height_)); |
| + h264_parser_.SetStream(static_cast<const uint8_t*>(memory.memory()), |
|
Ami GONE FROM CHROMIUM
2012/05/23 19:41:19
The fact that you feed all bitstreambuffers to the
sail
2012/05/28 21:45:46
I'd like to keep using the parser so that I can ha
|
| + bitstream_buffer.size()); |
| + while (true) { |
| + content::H264NALU nalu; |
| + content::H264Parser::Result result = h264_parser_.AdvanceToNextNALU(&nalu); |
| + if (result == content::H264Parser::kEOStream) { |
| + if (client_) |
| + client_->NotifyEndOfBitstreamBuffer(bitstream_buffer.id()); |
| + return; |
| + } |
| + if (result != content::H264Parser::kOk) { |
| + if (client_) |
| + client_->NotifyError(UNREADABLE_INPUT); |
| + return; |
| + } |
| + |
| + if (!did_build_config_record_) { |
| + bool did_consume_nalu = false; |
| + if (!config_record_builder_.ProcessNextNALU( |
| + &h264_parser_, &nalu, &did_consume_nalu)) { |
| + if (client_) |
| + client_->NotifyError(UNREADABLE_INPUT); |
| + return; |
| + } |
| + |
| + if (config_record_builder_.can_build_record()) { |
| + did_build_config_record_ = true; |
| + CreateDecoder(); |
| + } |
| + |
| + if (did_consume_nalu) |
| + continue; |
| + } |
| + |
| + // If the decoder has been created and this is a slice type then pass it |
| + // to the decoder. |
| + if (vda_.get() && nalu.nal_unit_type >= 1 && nalu.nal_unit_type <= 5) |
| + DecodeNALU(&nalu, bitstream_buffer.id()); |
| } |
| } |
| @@ -257,6 +236,53 @@ void MacVideoDecodeAccelerator::NotifyResetDone() { |
| client_->NotifyResetDone(); |
| } |
| +void MacVideoDecodeAccelerator::CreateDecoder() { |
| + std::vector<uint8_t> extra_data( |
| + config_record_builder_.BuildConfigRecord()); |
| + vda_ = new gfx::VideoDecodeAccelerationSupport(); |
| + gfx::VideoDecodeAccelerationSupport::Status status = vda_->Create( |
| + config_record_builder_.coded_width(), |
| + config_record_builder_.coded_height(), |
| + kCVPixelFormatType_422YpCbCr8, |
| + &extra_data[0], extra_data.size()); |
| + if (status != gfx::VideoDecodeAccelerationSupport::VDA_SUCCESS) { |
| + if (client_) |
| + client_->NotifyError(PLATFORM_FAILURE); |
| + return; |
| + } |
| + |
| + if (client_) { |
| + client_->ProvidePictureBuffers( |
| + kNumPictureBuffers, |
| + gfx::Size(config_record_builder_.coded_width(), |
| + config_record_builder_.coded_height())); |
| + } |
| +} |
| + |
| +void MacVideoDecodeAccelerator::DecodeNALU(const content::H264NALU* nalu, |
| + int32 bitstream_buffer_id) { |
| + // Assume the NALU lenght field size is 4 bytes. |
|
Ami GONE FROM CHROMIUM
2012/05/23 19:41:19
typo: length
sail
2012/05/28 21:45:46
Done.
|
| + const int kNALULengthFieldSize = 4; |
| + std::vector<uint8_t> data(kNALULengthFieldSize + nalu->size, 0); |
|
Ami GONE FROM CHROMIUM
2012/05/23 19:41:19
Why the ", 0"?
sail
2012/05/28 21:45:46
Done.
|
| + |
| + // Store the buffer size at the beginning of the buffer as the decoder |
| + // expects. |
| + for (size_t i = 0; i < kNALULengthFieldSize; ++i) { |
| + size_t shift = kNALULengthFieldSize * 8 - (i + 1) * 8; |
| + data[i] = (nalu->size >> shift) & 0xff; |
| + } |
| + |
| + // Copy the NALU data. |
| + memcpy(&data[kNALULengthFieldSize], nalu->data, nalu->size); |
| + |
| + // Keep a ref counted copy of the buffer. |
| + scoped_refptr<base::RefCountedBytes> bytes( |
| + base::RefCountedBytes::TakeVector(&data)); |
| + vda_->Decode(bytes->front(), bytes->size(), |
| + base::Bind(&MacVideoDecodeAccelerator::OnFrameReady, this, |
| + bitstream_buffer_id, bytes)); |
| +} |
| + |
| MacVideoDecodeAccelerator::PendingPictureInfo::PendingPictureInfo( |
| media::PictureBuffer pic) |
| : picture_buffer(pic.id(), pic.size(), pic.texture_id()) { |