Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(205)

Unified Diff: content/common/gpu/media/mac_video_decode_accelerator.mm

Issue 10411085: Build AVC decoder configuration record (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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()) {

Powered by Google App Engine
This is Rietveld 408576698