diff options
author | strobe@google.com <strobe@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-29 04:24:17 +0000 |
---|---|---|
committer | strobe@google.com <strobe@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-29 04:24:17 +0000 |
commit | d1c8bb00d18fb44a7aa6acd604409b83896be1a5 (patch) | |
tree | 8185c7c15d12eb1eb5391eb4daa3739044a41313 /media/mp4 | |
parent | e963af50ea8b125c18ea850c81022f7d12da2490 (diff) | |
download | chromium_src-d1c8bb00d18fb44a7aa6acd604409b83896be1a5.zip chromium_src-d1c8bb00d18fb44a7aa6acd604409b83896be1a5.tar.gz chromium_src-d1c8bb00d18fb44a7aa6acd604409b83896be1a5.tar.bz2 |
Fix encrypted AAC in BMFF by adding subsample info.
AAC audio is sent to the Source Buffer in ADTS format, which requires
adding a header to each media sample. Encrypted subsample information
was not being adjusted to compensate for the extra clear bytes.
TEST=Manual, pending audio decryption support in decoder
BUG=132351
Review URL: https://chromiumcodereview.appspot.com/10886022
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@153854 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/mp4')
-rw-r--r-- | media/mp4/aac.cc | 4 | ||||
-rw-r--r-- | media/mp4/aac.h | 3 | ||||
-rw-r--r-- | media/mp4/mp4_stream_parser.cc | 50 | ||||
-rw-r--r-- | media/mp4/mp4_stream_parser.h | 3 |
4 files changed, 43 insertions, 17 deletions
diff --git a/media/mp4/aac.cc b/media/mp4/aac.cc index 2804d6b..2982687 100644 --- a/media/mp4/aac.cc +++ b/media/mp4/aac.cc @@ -156,7 +156,7 @@ ChannelLayout AAC::channel_layout() const { } bool AAC::ConvertEsdsToADTS(std::vector<uint8>* buffer) const { - size_t size = buffer->size() + 7; + size_t size = buffer->size() + kADTSHeaderSize; DCHECK(profile_ >= 1 && profile_ <= 4 && frequency_index_ != 0xf && channel_config_ <= 7); @@ -167,7 +167,7 @@ bool AAC::ConvertEsdsToADTS(std::vector<uint8>* buffer) const { std::vector<uint8>& adts = *buffer; - adts.insert(buffer->begin(), 7, 0); + adts.insert(buffer->begin(), kADTSHeaderSize, 0); adts[0] = 0xff; adts[1] = 0xf1; adts[2] = ((profile_ - 1) << 6) + (frequency_index_ << 2) + diff --git a/media/mp4/aac.h b/media/mp4/aac.h index 73464ee..e12b6a4 100644 --- a/media/mp4/aac.h +++ b/media/mp4/aac.h @@ -46,6 +46,9 @@ class MEDIA_EXPORT AAC { // unchanged. bool ConvertEsdsToADTS(std::vector<uint8>* buffer) const; + // Size in bytes of the ADTS header added by ConvertEsdsToADTS(). + static const size_t kADTSHeaderSize = 7; + private: bool SkipDecoderGASpecificConfig(BitReader* bit_reader) const; bool SkipErrorSpecificConfig() const; diff --git a/media/mp4/mp4_stream_parser.cc b/media/mp4/mp4_stream_parser.cc index b025b7a..b8f6331 100644 --- a/media/mp4/mp4_stream_parser.cc +++ b/media/mp4/mp4_stream_parser.cc @@ -309,6 +309,25 @@ bool MP4StreamParser::PrepareAVCBuffer( return true; } +bool MP4StreamParser::PrepareAACBuffer( + const AAC& aac_config, std::vector<uint8>* frame_buf, + std::vector<SubsampleEntry>* subsamples) const { + // Append an ADTS header to every audio sample. + RCHECK(aac_config.ConvertEsdsToADTS(frame_buf)); + + // As above, adjust subsample information to account for the headers. AAC is + // not required to use subsample encryption, so we may need to add an entry. + if (subsamples->empty()) { + SubsampleEntry entry; + entry.clear_bytes = AAC::kADTSHeaderSize; + entry.cypher_bytes = frame_buf->size() - AAC::kADTSHeaderSize; + subsamples->push_back(entry); + } else { + (*subsamples)[0].clear_bytes += AAC::kADTSHeaderSize; + } + return true; +} + bool MP4StreamParser::EnqueueSample(BufferQueue* audio_buffers, BufferQueue* video_buffers, bool* err) { @@ -366,39 +385,40 @@ bool MP4StreamParser::EnqueueSample(BufferQueue* audio_buffers, if (buf_size < runs_->sample_size()) return false; scoped_ptr<DecryptConfig> decrypt_config; - if (runs_->is_encrypted()) + std::vector<SubsampleEntry> subsamples; + if (runs_->is_encrypted()) { decrypt_config = runs_->GetDecryptConfig(); + subsamples = decrypt_config->subsamples(); + } std::vector<uint8> frame_buf(buf, buf + runs_->sample_size()); if (video) { - std::vector<SubsampleEntry> subsamples; - if (decrypt_config.get()) - subsamples = decrypt_config->subsamples(); if (!PrepareAVCBuffer(runs_->video_description().avcc, &frame_buf, &subsamples)) { DLOG(ERROR) << "Failed to prepare AVC sample for decode"; *err = true; return false; } - if (!subsamples.empty()) { - decrypt_config.reset(new DecryptConfig( - decrypt_config->key_id(), - decrypt_config->iv(), - decrypt_config->checksum(), - decrypt_config->data_offset(), - subsamples)); - } } if (audio) { - const AAC& aac = runs_->audio_description().esds.aac; - if (!aac.ConvertEsdsToADTS(&frame_buf)) { - DLOG(ERROR) << "Failed to convert ESDS to ADTS"; + if (!PrepareAACBuffer(runs_->audio_description().esds.aac, + &frame_buf, &subsamples)) { + DLOG(ERROR) << "Failed to prepare AAC sample for decode"; *err = true; return false; } } + if (decrypt_config.get() != NULL && !subsamples.empty()) { + decrypt_config.reset(new DecryptConfig( + decrypt_config->key_id(), + decrypt_config->iv(), + decrypt_config->checksum(), + decrypt_config->data_offset(), + subsamples)); + } + scoped_refptr<StreamParserBuffer> stream_buf = StreamParserBuffer::CopyFrom(&frame_buf[0], frame_buf.size(), runs_->is_keyframe()); diff --git a/media/mp4/mp4_stream_parser.h b/media/mp4/mp4_stream_parser.h index 9710fd2..4c8df36 100644 --- a/media/mp4/mp4_stream_parser.h +++ b/media/mp4/mp4_stream_parser.h @@ -64,6 +64,9 @@ class MEDIA_EXPORT MP4StreamParser : public StreamParser { bool PrepareAVCBuffer(const AVCDecoderConfigurationRecord& avc_config, std::vector<uint8>* frame_buf, std::vector<SubsampleEntry>* subsamples) const; + bool PrepareAACBuffer(const AAC& aac_config, + std::vector<uint8>* frame_buf, + std::vector<SubsampleEntry>* subsamples) const; bool EnqueueSample(BufferQueue* audio_buffers, BufferQueue* video_buffers, bool* err); |