summaryrefslogtreecommitdiffstats
path: root/media/mp4
diff options
context:
space:
mode:
authorstrobe@google.com <strobe@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-29 04:24:17 +0000
committerstrobe@google.com <strobe@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-29 04:24:17 +0000
commitd1c8bb00d18fb44a7aa6acd604409b83896be1a5 (patch)
tree8185c7c15d12eb1eb5391eb4daa3739044a41313 /media/mp4
parente963af50ea8b125c18ea850c81022f7d12da2490 (diff)
downloadchromium_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.cc4
-rw-r--r--media/mp4/aac.h3
-rw-r--r--media/mp4/mp4_stream_parser.cc50
-rw-r--r--media/mp4/mp4_stream_parser.h3
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);