Replace u?int(8|16|32|64) with u?int(8|16|32|64)_t
u?int(8|16|32|64) are DEPRECATED per base/basictypes.h. The change was made using the below commands with some adjustments for pretty formatting: > find {media,app,mpd} -name '*.proto' -prune -o -type f -exec sed -r -i 's/\b(u?int[0-9]+)\b/\1_t/g' {} \; > git clang-format Change-Id: I99d2e5e0fbbdbc5d7b9eb121b4622de780413f53
This commit is contained in:
parent
7e6cd6e853
commit
d1068964ae
|
@ -70,7 +70,7 @@ scoped_ptr<KeySource> CreateEncryptionKeySource() {
|
||||||
scoped_ptr<KeySource> encryption_key_source;
|
scoped_ptr<KeySource> encryption_key_source;
|
||||||
if (FLAGS_enable_widevine_encryption) {
|
if (FLAGS_enable_widevine_encryption) {
|
||||||
scoped_ptr<RequestSigner> signer(CreateSigner());
|
scoped_ptr<RequestSigner> signer(CreateSigner());
|
||||||
std::vector<uint8> content_id;
|
std::vector<uint8_t> content_id;
|
||||||
if (!base::HexStringToBytes(FLAGS_content_id, &content_id)) {
|
if (!base::HexStringToBytes(FLAGS_content_id, &content_id)) {
|
||||||
LOG(ERROR) << "Invalid content_id hex string specified.";
|
LOG(ERROR) << "Invalid content_id hex string specified.";
|
||||||
return scoped_ptr<KeySource>();
|
return scoped_ptr<KeySource>();
|
||||||
|
|
|
@ -25,7 +25,7 @@ struct StreamDescriptor {
|
||||||
std::string input;
|
std::string input;
|
||||||
std::string output;
|
std::string output;
|
||||||
std::string segment_template;
|
std::string segment_template;
|
||||||
uint32 bandwidth;
|
uint32_t bandwidth;
|
||||||
};
|
};
|
||||||
|
|
||||||
class StreamDescriptorCompareFn {
|
class StreamDescriptorCompareFn {
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// Increment an 8-byte counter by 1. Return true if overflowed.
|
// Increment an 8-byte counter by 1. Return true if overflowed.
|
||||||
bool Increment64(uint8* counter) {
|
bool Increment64(uint8_t* counter) {
|
||||||
DCHECK(counter);
|
DCHECK(counter);
|
||||||
for (int i = 7; i >= 0; --i)
|
for (int i = 7; i >= 0; --i)
|
||||||
if (++counter[i] != 0)
|
if (++counter[i] != 0)
|
||||||
|
@ -33,7 +33,7 @@ bool IsKeySizeValidForAes(size_t key_size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CENC protection scheme uses 128-bit keys in counter mode.
|
// CENC protection scheme uses 128-bit keys in counter mode.
|
||||||
const uint32 kCencKeySize = 16;
|
const uint32_t kCencKeySize = 16;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
@ -50,9 +50,9 @@ AesCtrEncryptor::AesCtrEncryptor()
|
||||||
|
|
||||||
AesCtrEncryptor::~AesCtrEncryptor() {}
|
AesCtrEncryptor::~AesCtrEncryptor() {}
|
||||||
|
|
||||||
bool AesCtrEncryptor::InitializeWithRandomIv(const std::vector<uint8>& key,
|
bool AesCtrEncryptor::InitializeWithRandomIv(const std::vector<uint8_t>& key,
|
||||||
uint8 iv_size) {
|
uint8_t iv_size) {
|
||||||
std::vector<uint8> iv(iv_size, 0);
|
std::vector<uint8_t> iv(iv_size, 0);
|
||||||
if (RAND_bytes(&iv[0], iv_size) != 1) {
|
if (RAND_bytes(&iv[0], iv_size) != 1) {
|
||||||
LOG(ERROR) << "RAND_bytes failed with error: "
|
LOG(ERROR) << "RAND_bytes failed with error: "
|
||||||
<< ERR_error_string(ERR_get_error(), NULL);
|
<< ERR_error_string(ERR_get_error(), NULL);
|
||||||
|
@ -61,8 +61,8 @@ bool AesCtrEncryptor::InitializeWithRandomIv(const std::vector<uint8>& key,
|
||||||
return InitializeWithIv(key, iv);
|
return InitializeWithIv(key, iv);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AesCtrEncryptor::InitializeWithIv(const std::vector<uint8>& key,
|
bool AesCtrEncryptor::InitializeWithIv(const std::vector<uint8_t>& key,
|
||||||
const std::vector<uint8>& iv) {
|
const std::vector<uint8_t>& iv) {
|
||||||
if (key.size() != kCencKeySize) {
|
if (key.size() != kCencKeySize) {
|
||||||
LOG(ERROR) << "Invalid key size of " << key.size() << " for CENC.";
|
LOG(ERROR) << "Invalid key size of " << key.size() << " for CENC.";
|
||||||
return false;
|
return false;
|
||||||
|
@ -77,9 +77,9 @@ bool AesCtrEncryptor::InitializeWithIv(const std::vector<uint8>& key,
|
||||||
return SetIv(iv);
|
return SetIv(iv);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AesCtrEncryptor::Encrypt(const uint8* plaintext,
|
bool AesCtrEncryptor::Encrypt(const uint8_t* plaintext,
|
||||||
size_t plaintext_size,
|
size_t plaintext_size,
|
||||||
uint8* ciphertext) {
|
uint8_t* ciphertext) {
|
||||||
DCHECK(plaintext);
|
DCHECK(plaintext);
|
||||||
DCHECK(ciphertext);
|
DCHECK(ciphertext);
|
||||||
DCHECK(aes_key_);
|
DCHECK(aes_key_);
|
||||||
|
@ -130,7 +130,7 @@ void AesCtrEncryptor::UpdateIv() {
|
||||||
counter_overflow_ = false;
|
counter_overflow_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AesCtrEncryptor::SetIv(const std::vector<uint8>& iv) {
|
bool AesCtrEncryptor::SetIv(const std::vector<uint8_t>& iv) {
|
||||||
if (!IsIvSizeValid(iv.size())) {
|
if (!IsIvSizeValid(iv.size())) {
|
||||||
LOG(ERROR) << "Invalid IV size: " << iv.size();
|
LOG(ERROR) << "Invalid IV size: " << iv.size();
|
||||||
return false;
|
return false;
|
||||||
|
@ -145,8 +145,8 @@ bool AesCtrEncryptor::SetIv(const std::vector<uint8>& iv) {
|
||||||
AesCbcPkcs5Encryptor::AesCbcPkcs5Encryptor() {}
|
AesCbcPkcs5Encryptor::AesCbcPkcs5Encryptor() {}
|
||||||
AesCbcPkcs5Encryptor::~AesCbcPkcs5Encryptor() {}
|
AesCbcPkcs5Encryptor::~AesCbcPkcs5Encryptor() {}
|
||||||
|
|
||||||
bool AesCbcPkcs5Encryptor::InitializeWithIv(const std::vector<uint8>& key,
|
bool AesCbcPkcs5Encryptor::InitializeWithIv(const std::vector<uint8_t>& key,
|
||||||
const std::vector<uint8>& iv) {
|
const std::vector<uint8_t>& iv) {
|
||||||
if (!IsKeySizeValidForAes(key.size())) {
|
if (!IsKeySizeValidForAes(key.size())) {
|
||||||
LOG(ERROR) << "Invalid AES key size: " << key.size();
|
LOG(ERROR) << "Invalid AES key size: " << key.size();
|
||||||
return false;
|
return false;
|
||||||
|
@ -175,16 +175,16 @@ void AesCbcPkcs5Encryptor::Encrypt(const std::string& plaintext,
|
||||||
padded_text.append(num_padding_bytes, static_cast<char>(num_padding_bytes));
|
padded_text.append(num_padding_bytes, static_cast<char>(num_padding_bytes));
|
||||||
|
|
||||||
ciphertext->resize(padded_text.size());
|
ciphertext->resize(padded_text.size());
|
||||||
std::vector<uint8> iv(iv_);
|
std::vector<uint8_t> iv(iv_);
|
||||||
AES_cbc_encrypt(reinterpret_cast<const uint8*>(padded_text.data()),
|
AES_cbc_encrypt(reinterpret_cast<const uint8_t*>(padded_text.data()),
|
||||||
reinterpret_cast<uint8*>(string_as_array(ciphertext)),
|
reinterpret_cast<uint8_t*>(string_as_array(ciphertext)),
|
||||||
padded_text.size(),
|
padded_text.size(),
|
||||||
encrypt_key_.get(),
|
encrypt_key_.get(),
|
||||||
&iv[0],
|
&iv[0],
|
||||||
AES_ENCRYPT);
|
AES_ENCRYPT);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AesCbcPkcs5Encryptor::SetIv(const std::vector<uint8>& iv) {
|
bool AesCbcPkcs5Encryptor::SetIv(const std::vector<uint8_t>& iv) {
|
||||||
if (iv.size() != AES_BLOCK_SIZE) {
|
if (iv.size() != AES_BLOCK_SIZE) {
|
||||||
LOG(ERROR) << "Invalid IV size: " << iv.size();
|
LOG(ERROR) << "Invalid IV size: " << iv.size();
|
||||||
return false;
|
return false;
|
||||||
|
@ -197,8 +197,8 @@ bool AesCbcPkcs5Encryptor::SetIv(const std::vector<uint8>& iv) {
|
||||||
AesCbcPkcs5Decryptor::AesCbcPkcs5Decryptor() {}
|
AesCbcPkcs5Decryptor::AesCbcPkcs5Decryptor() {}
|
||||||
AesCbcPkcs5Decryptor::~AesCbcPkcs5Decryptor() {}
|
AesCbcPkcs5Decryptor::~AesCbcPkcs5Decryptor() {}
|
||||||
|
|
||||||
bool AesCbcPkcs5Decryptor::InitializeWithIv(const std::vector<uint8>& key,
|
bool AesCbcPkcs5Decryptor::InitializeWithIv(const std::vector<uint8_t>& key,
|
||||||
const std::vector<uint8>& iv) {
|
const std::vector<uint8_t>& iv) {
|
||||||
if (!IsKeySizeValidForAes(key.size())) {
|
if (!IsKeySizeValidForAes(key.size())) {
|
||||||
LOG(ERROR) << "Invalid AES key size: " << key.size();
|
LOG(ERROR) << "Invalid AES key size: " << key.size();
|
||||||
return false;
|
return false;
|
||||||
|
@ -227,15 +227,15 @@ bool AesCbcPkcs5Decryptor::Decrypt(const std::string& ciphertext,
|
||||||
DCHECK(decrypt_key_);
|
DCHECK(decrypt_key_);
|
||||||
|
|
||||||
plaintext->resize(ciphertext.size());
|
plaintext->resize(ciphertext.size());
|
||||||
AES_cbc_encrypt(reinterpret_cast<const uint8*>(ciphertext.data()),
|
AES_cbc_encrypt(reinterpret_cast<const uint8_t*>(ciphertext.data()),
|
||||||
reinterpret_cast<uint8*>(string_as_array(plaintext)),
|
reinterpret_cast<uint8_t*>(string_as_array(plaintext)),
|
||||||
ciphertext.size(),
|
ciphertext.size(),
|
||||||
decrypt_key_.get(),
|
decrypt_key_.get(),
|
||||||
&iv_[0],
|
&iv_[0],
|
||||||
AES_DECRYPT);
|
AES_DECRYPT);
|
||||||
|
|
||||||
// Strip off PKCS5 padding bytes.
|
// Strip off PKCS5 padding bytes.
|
||||||
const uint8 num_padding_bytes = (*plaintext)[plaintext->size() - 1];
|
const uint8_t num_padding_bytes = (*plaintext)[plaintext->size() - 1];
|
||||||
if (num_padding_bytes > AES_BLOCK_SIZE) {
|
if (num_padding_bytes > AES_BLOCK_SIZE) {
|
||||||
LOG(ERROR) << "Padding length is too large : "
|
LOG(ERROR) << "Padding length is too large : "
|
||||||
<< static_cast<int>(num_padding_bytes);
|
<< static_cast<int>(num_padding_bytes);
|
||||||
|
@ -245,7 +245,7 @@ bool AesCbcPkcs5Decryptor::Decrypt(const std::string& ciphertext,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AesCbcPkcs5Decryptor::SetIv(const std::vector<uint8>& iv) {
|
bool AesCbcPkcs5Decryptor::SetIv(const std::vector<uint8_t>& iv) {
|
||||||
if (iv.size() != AES_BLOCK_SIZE) {
|
if (iv.size() != AES_BLOCK_SIZE) {
|
||||||
LOG(ERROR) << "Invalid IV size: " << iv.size();
|
LOG(ERROR) << "Invalid IV size: " << iv.size();
|
||||||
return false;
|
return false;
|
||||||
|
@ -258,8 +258,8 @@ bool AesCbcPkcs5Decryptor::SetIv(const std::vector<uint8>& iv) {
|
||||||
AesCbcCtsEncryptor::AesCbcCtsEncryptor() {}
|
AesCbcCtsEncryptor::AesCbcCtsEncryptor() {}
|
||||||
AesCbcCtsEncryptor::~AesCbcCtsEncryptor() {}
|
AesCbcCtsEncryptor::~AesCbcCtsEncryptor() {}
|
||||||
|
|
||||||
bool AesCbcCtsEncryptor::InitializeWithIv(const std::vector<uint8>& key,
|
bool AesCbcCtsEncryptor::InitializeWithIv(const std::vector<uint8_t>& key,
|
||||||
const std::vector<uint8>& iv) {
|
const std::vector<uint8_t>& iv) {
|
||||||
if (!IsKeySizeValidForAes(key.size())) {
|
if (!IsKeySizeValidForAes(key.size())) {
|
||||||
LOG(ERROR) << "Invalid AES key size: " << key.size();
|
LOG(ERROR) << "Invalid AES key size: " << key.size();
|
||||||
return false;
|
return false;
|
||||||
|
@ -276,9 +276,9 @@ bool AesCbcCtsEncryptor::InitializeWithIv(const std::vector<uint8>& key,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AesCbcCtsEncryptor::Encrypt(const uint8* plaintext,
|
void AesCbcCtsEncryptor::Encrypt(const uint8_t* plaintext,
|
||||||
size_t size,
|
size_t size,
|
||||||
uint8* ciphertext) {
|
uint8_t* ciphertext) {
|
||||||
DCHECK(plaintext);
|
DCHECK(plaintext);
|
||||||
DCHECK(ciphertext);
|
DCHECK(ciphertext);
|
||||||
|
|
||||||
|
@ -288,7 +288,7 @@ void AesCbcCtsEncryptor::Encrypt(const uint8* plaintext,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8> iv(iv_);
|
std::vector<uint8_t> iv(iv_);
|
||||||
size_t residual_block_size = size % AES_BLOCK_SIZE;
|
size_t residual_block_size = size % AES_BLOCK_SIZE;
|
||||||
size_t cbc_size = size - residual_block_size;
|
size_t cbc_size = size - residual_block_size;
|
||||||
|
|
||||||
|
@ -305,8 +305,8 @@ void AesCbcCtsEncryptor::Encrypt(const uint8* plaintext,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Zero-pad the residual block and encrypt using CBC.
|
// Zero-pad the residual block and encrypt using CBC.
|
||||||
std::vector<uint8> residual_block(plaintext + size - residual_block_size,
|
std::vector<uint8_t> residual_block(plaintext + size - residual_block_size,
|
||||||
plaintext + size);
|
plaintext + size);
|
||||||
residual_block.resize(AES_BLOCK_SIZE, 0);
|
residual_block.resize(AES_BLOCK_SIZE, 0);
|
||||||
AES_cbc_encrypt(&residual_block[0],
|
AES_cbc_encrypt(&residual_block[0],
|
||||||
&residual_block[0],
|
&residual_block[0],
|
||||||
|
@ -320,7 +320,7 @@ void AesCbcCtsEncryptor::Encrypt(const uint8* plaintext,
|
||||||
// encrypted block. It may appear that some encrypted bits of the last full
|
// encrypted block. It may appear that some encrypted bits of the last full
|
||||||
// block are lost, but they are not, as they were used as the IV when
|
// block are lost, but they are not, as they were used as the IV when
|
||||||
// encrypting the zero-padded residual block.
|
// encrypting the zero-padded residual block.
|
||||||
uint8* residual_ciphertext_block = ciphertext + size - residual_block_size;
|
uint8_t* residual_ciphertext_block = ciphertext + size - residual_block_size;
|
||||||
memcpy(residual_ciphertext_block,
|
memcpy(residual_ciphertext_block,
|
||||||
residual_ciphertext_block - AES_BLOCK_SIZE,
|
residual_ciphertext_block - AES_BLOCK_SIZE,
|
||||||
residual_block_size);
|
residual_block_size);
|
||||||
|
@ -329,8 +329,8 @@ void AesCbcCtsEncryptor::Encrypt(const uint8* plaintext,
|
||||||
AES_BLOCK_SIZE);
|
AES_BLOCK_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AesCbcCtsEncryptor::Encrypt(const std::vector<uint8>& plaintext,
|
void AesCbcCtsEncryptor::Encrypt(const std::vector<uint8_t>& plaintext,
|
||||||
std::vector<uint8>* ciphertext) {
|
std::vector<uint8_t>* ciphertext) {
|
||||||
DCHECK(ciphertext);
|
DCHECK(ciphertext);
|
||||||
|
|
||||||
ciphertext->resize(plaintext.size(), 0);
|
ciphertext->resize(plaintext.size(), 0);
|
||||||
|
@ -340,7 +340,7 @@ void AesCbcCtsEncryptor::Encrypt(const std::vector<uint8>& plaintext,
|
||||||
return Encrypt(plaintext.data(), plaintext.size(), &(*ciphertext)[0]);
|
return Encrypt(plaintext.data(), plaintext.size(), &(*ciphertext)[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AesCbcCtsEncryptor::SetIv(const std::vector<uint8>& iv) {
|
bool AesCbcCtsEncryptor::SetIv(const std::vector<uint8_t>& iv) {
|
||||||
if (iv.size() != AES_BLOCK_SIZE) {
|
if (iv.size() != AES_BLOCK_SIZE) {
|
||||||
LOG(ERROR) << "Invalid IV size: " << iv.size();
|
LOG(ERROR) << "Invalid IV size: " << iv.size();
|
||||||
return false;
|
return false;
|
||||||
|
@ -353,8 +353,8 @@ bool AesCbcCtsEncryptor::SetIv(const std::vector<uint8>& iv) {
|
||||||
AesCbcCtsDecryptor::AesCbcCtsDecryptor() {}
|
AesCbcCtsDecryptor::AesCbcCtsDecryptor() {}
|
||||||
AesCbcCtsDecryptor::~AesCbcCtsDecryptor() {}
|
AesCbcCtsDecryptor::~AesCbcCtsDecryptor() {}
|
||||||
|
|
||||||
bool AesCbcCtsDecryptor::InitializeWithIv(const std::vector<uint8>& key,
|
bool AesCbcCtsDecryptor::InitializeWithIv(const std::vector<uint8_t>& key,
|
||||||
const std::vector<uint8>& iv) {
|
const std::vector<uint8_t>& iv) {
|
||||||
if (!IsKeySizeValidForAes(key.size())) {
|
if (!IsKeySizeValidForAes(key.size())) {
|
||||||
LOG(ERROR) << "Invalid AES key size: " << key.size();
|
LOG(ERROR) << "Invalid AES key size: " << key.size();
|
||||||
return false;
|
return false;
|
||||||
|
@ -371,9 +371,9 @@ bool AesCbcCtsDecryptor::InitializeWithIv(const std::vector<uint8>& key,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AesCbcCtsDecryptor::Decrypt(const uint8* ciphertext,
|
void AesCbcCtsDecryptor::Decrypt(const uint8_t* ciphertext,
|
||||||
size_t size,
|
size_t size,
|
||||||
uint8* plaintext) {
|
uint8_t* plaintext) {
|
||||||
DCHECK(ciphertext);
|
DCHECK(ciphertext);
|
||||||
DCHECK(plaintext);
|
DCHECK(plaintext);
|
||||||
|
|
||||||
|
@ -383,7 +383,7 @@ void AesCbcCtsDecryptor::Decrypt(const uint8* ciphertext,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8> iv(iv_);
|
std::vector<uint8_t> iv(iv_);
|
||||||
size_t residual_block_size = size % AES_BLOCK_SIZE;
|
size_t residual_block_size = size % AES_BLOCK_SIZE;
|
||||||
|
|
||||||
if (residual_block_size == 0) {
|
if (residual_block_size == 0) {
|
||||||
|
@ -410,8 +410,8 @@ void AesCbcCtsDecryptor::Decrypt(const uint8* ciphertext,
|
||||||
|
|
||||||
// Determine what the last IV should be so that we can "skip ahead" in the
|
// Determine what the last IV should be so that we can "skip ahead" in the
|
||||||
// CBC decryption.
|
// CBC decryption.
|
||||||
std::vector<uint8> last_iv(ciphertext + size - residual_block_size,
|
std::vector<uint8_t> last_iv(ciphertext + size - residual_block_size,
|
||||||
ciphertext + size);
|
ciphertext + size);
|
||||||
last_iv.resize(AES_BLOCK_SIZE, 0);
|
last_iv.resize(AES_BLOCK_SIZE, 0);
|
||||||
|
|
||||||
// Decrypt the next-to-last block using the IV determined above. This decrypts
|
// Decrypt the next-to-last block using the IV determined above. This decrypts
|
||||||
|
@ -425,17 +425,17 @@ void AesCbcCtsDecryptor::Decrypt(const uint8* ciphertext,
|
||||||
|
|
||||||
// Swap back the residual block bits and the next-to-last full block.
|
// Swap back the residual block bits and the next-to-last full block.
|
||||||
if (plaintext == ciphertext) {
|
if (plaintext == ciphertext) {
|
||||||
uint8* ptr1 = plaintext + size - residual_block_size;
|
uint8_t* ptr1 = plaintext + size - residual_block_size;
|
||||||
uint8* ptr2 = plaintext + size - residual_block_size - AES_BLOCK_SIZE;
|
uint8_t* ptr2 = plaintext + size - residual_block_size - AES_BLOCK_SIZE;
|
||||||
for (size_t i = 0; i < residual_block_size; ++i) {
|
for (size_t i = 0; i < residual_block_size; ++i) {
|
||||||
uint8 temp = *ptr1;
|
uint8_t temp = *ptr1;
|
||||||
*ptr1 = *ptr2;
|
*ptr1 = *ptr2;
|
||||||
*ptr2 = temp;
|
*ptr2 = temp;
|
||||||
++ptr1;
|
++ptr1;
|
||||||
++ptr2;
|
++ptr2;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
uint8* residual_plaintext_block = plaintext + size - residual_block_size;
|
uint8_t* residual_plaintext_block = plaintext + size - residual_block_size;
|
||||||
memcpy(residual_plaintext_block,
|
memcpy(residual_plaintext_block,
|
||||||
residual_plaintext_block - AES_BLOCK_SIZE,
|
residual_plaintext_block - AES_BLOCK_SIZE,
|
||||||
residual_block_size);
|
residual_block_size);
|
||||||
|
@ -453,8 +453,8 @@ void AesCbcCtsDecryptor::Decrypt(const uint8* ciphertext,
|
||||||
AES_DECRYPT);
|
AES_DECRYPT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AesCbcCtsDecryptor::Decrypt(const std::vector<uint8>& ciphertext,
|
void AesCbcCtsDecryptor::Decrypt(const std::vector<uint8_t>& ciphertext,
|
||||||
std::vector<uint8>* plaintext) {
|
std::vector<uint8_t>* plaintext) {
|
||||||
DCHECK(plaintext);
|
DCHECK(plaintext);
|
||||||
|
|
||||||
plaintext->resize(ciphertext.size(), 0);
|
plaintext->resize(ciphertext.size(), 0);
|
||||||
|
@ -464,7 +464,7 @@ void AesCbcCtsDecryptor::Decrypt(const std::vector<uint8>& ciphertext,
|
||||||
return Decrypt(ciphertext.data(), ciphertext.size(), &(*plaintext)[0]);
|
return Decrypt(ciphertext.data(), ciphertext.size(), &(*plaintext)[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AesCbcCtsDecryptor::SetIv(const std::vector<uint8>& iv) {
|
bool AesCbcCtsDecryptor::SetIv(const std::vector<uint8_t>& iv) {
|
||||||
if (iv.size() != AES_BLOCK_SIZE) {
|
if (iv.size() != AES_BLOCK_SIZE) {
|
||||||
LOG(ERROR) << "Invalid IV size: " << iv.size();
|
LOG(ERROR) << "Invalid IV size: " << iv.size();
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -32,46 +32,46 @@ class AesCtrEncryptor {
|
||||||
/// @param key should be 16 bytes in size as specified in CENC spec.
|
/// @param key should be 16 bytes in size as specified in CENC spec.
|
||||||
/// @param iv_size should be either 8 or 16 as specified in CENC spec.
|
/// @param iv_size should be either 8 or 16 as specified in CENC spec.
|
||||||
/// @return true on successful initialization, false otherwise.
|
/// @return true on successful initialization, false otherwise.
|
||||||
bool InitializeWithRandomIv(const std::vector<uint8>& key, uint8 iv_size);
|
bool InitializeWithRandomIv(const std::vector<uint8_t>& key, uint8_t iv_size);
|
||||||
|
|
||||||
/// Initialize the encryptor with specified key and IV. block_offset() is
|
/// Initialize the encryptor with specified key and IV. block_offset() is
|
||||||
/// reset to 0 on success.
|
/// reset to 0 on success.
|
||||||
/// @param key should be 16 bytes in size as specified in CENC spec.
|
/// @param key should be 16 bytes in size as specified in CENC spec.
|
||||||
/// @param iv should be 8 bytes or 16 bytes in size as specified in CENC spec.
|
/// @param iv should be 8 bytes or 16 bytes in size as specified in CENC spec.
|
||||||
/// @return true on successful initialization, false otherwise.
|
/// @return true on successful initialization, false otherwise.
|
||||||
bool InitializeWithIv(const std::vector<uint8>& key,
|
bool InitializeWithIv(const std::vector<uint8_t>& key,
|
||||||
const std::vector<uint8>& iv);
|
const std::vector<uint8_t>& iv);
|
||||||
|
|
||||||
/// @name Various forms of encrypt calls.
|
/// @name Various forms of encrypt calls.
|
||||||
/// block_offset() will be updated according to input plaintext size.
|
/// block_offset() will be updated according to input plaintext size.
|
||||||
/// @{
|
/// @{
|
||||||
bool Encrypt(const uint8* plaintext,
|
bool Encrypt(const uint8_t* plaintext,
|
||||||
size_t plaintext_size,
|
size_t plaintext_size,
|
||||||
uint8* ciphertext);
|
uint8_t* ciphertext);
|
||||||
|
|
||||||
bool Encrypt(const std::vector<uint8>& plaintext,
|
bool Encrypt(const std::vector<uint8_t>& plaintext,
|
||||||
std::vector<uint8>* ciphertext) {
|
std::vector<uint8_t>* ciphertext) {
|
||||||
ciphertext->resize(plaintext.size());
|
ciphertext->resize(plaintext.size());
|
||||||
return Encrypt(&plaintext[0], plaintext.size(), &(*ciphertext)[0]);
|
return Encrypt(&plaintext[0], plaintext.size(), &(*ciphertext)[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Encrypt(const std::string& plaintext, std::string* ciphertext) {
|
bool Encrypt(const std::string& plaintext, std::string* ciphertext) {
|
||||||
ciphertext->resize(plaintext.size());
|
ciphertext->resize(plaintext.size());
|
||||||
return Encrypt(reinterpret_cast<const uint8*>(plaintext.data()),
|
return Encrypt(reinterpret_cast<const uint8_t*>(plaintext.data()),
|
||||||
plaintext.size(),
|
plaintext.size(),
|
||||||
reinterpret_cast<uint8*>(string_as_array(ciphertext)));
|
reinterpret_cast<uint8_t*>(string_as_array(ciphertext)));
|
||||||
}
|
}
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
// For AES CTR, encryption and decryption are identical.
|
// For AES CTR, encryption and decryption are identical.
|
||||||
bool Decrypt(const uint8* ciphertext,
|
bool Decrypt(const uint8_t* ciphertext,
|
||||||
size_t ciphertext_size,
|
size_t ciphertext_size,
|
||||||
uint8* plaintext) {
|
uint8_t* plaintext) {
|
||||||
return Encrypt(ciphertext, ciphertext_size, plaintext);
|
return Encrypt(ciphertext, ciphertext_size, plaintext);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Decrypt(const std::vector<uint8>& ciphertext,
|
bool Decrypt(const std::vector<uint8_t>& ciphertext,
|
||||||
std::vector<uint8>* plaintext) {
|
std::vector<uint8_t>* plaintext) {
|
||||||
return Encrypt(ciphertext, plaintext);
|
return Encrypt(ciphertext, plaintext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,23 +87,23 @@ class AesCtrEncryptor {
|
||||||
|
|
||||||
/// Set IV. @a block_offset_ is reset to 0 on success.
|
/// Set IV. @a block_offset_ is reset to 0 on success.
|
||||||
/// @return true if successful, false if the input is invalid.
|
/// @return true if successful, false if the input is invalid.
|
||||||
bool SetIv(const std::vector<uint8>& iv);
|
bool SetIv(const std::vector<uint8_t>& iv);
|
||||||
|
|
||||||
const std::vector<uint8>& iv() const { return iv_; }
|
const std::vector<uint8_t>& iv() const { return iv_; }
|
||||||
|
|
||||||
uint32 block_offset() const { return block_offset_; }
|
uint32_t block_offset() const { return block_offset_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Initialization vector, with size 8 or 16.
|
// Initialization vector, with size 8 or 16.
|
||||||
std::vector<uint8> iv_;
|
std::vector<uint8_t> iv_;
|
||||||
// Current block offset.
|
// Current block offset.
|
||||||
uint32 block_offset_;
|
uint32_t block_offset_;
|
||||||
// Openssl AES_KEY.
|
// Openssl AES_KEY.
|
||||||
scoped_ptr<AES_KEY> aes_key_;
|
scoped_ptr<AES_KEY> aes_key_;
|
||||||
// Current AES-CTR counter.
|
// Current AES-CTR counter.
|
||||||
std::vector<uint8> counter_;
|
std::vector<uint8_t> counter_;
|
||||||
// Encrypted counter.
|
// Encrypted counter.
|
||||||
std::vector<uint8> encrypted_counter_;
|
std::vector<uint8_t> encrypted_counter_;
|
||||||
// Keep track of whether the counter has overflowed.
|
// Keep track of whether the counter has overflowed.
|
||||||
bool counter_overflow_;
|
bool counter_overflow_;
|
||||||
|
|
||||||
|
@ -122,20 +122,20 @@ class AesCbcPkcs5Encryptor {
|
||||||
/// in AES spec.
|
/// in AES spec.
|
||||||
/// @param iv should be 16 bytes in size.
|
/// @param iv should be 16 bytes in size.
|
||||||
/// @return true on successful initialization, false otherwise.
|
/// @return true on successful initialization, false otherwise.
|
||||||
bool InitializeWithIv(const std::vector<uint8>& key,
|
bool InitializeWithIv(const std::vector<uint8_t>& key,
|
||||||
const std::vector<uint8>& iv);
|
const std::vector<uint8_t>& iv);
|
||||||
|
|
||||||
/// @param plaintext will be PKCS5 padded before being encrypted.
|
/// @param plaintext will be PKCS5 padded before being encrypted.
|
||||||
/// @param ciphertext should not be NULL.
|
/// @param ciphertext should not be NULL.
|
||||||
void Encrypt(const std::string& plaintext, std::string* ciphertext);
|
void Encrypt(const std::string& plaintext, std::string* ciphertext);
|
||||||
|
|
||||||
/// @return true if successful, false if the input is invalid.
|
/// @return true if successful, false if the input is invalid.
|
||||||
bool SetIv(const std::vector<uint8>& iv);
|
bool SetIv(const std::vector<uint8_t>& iv);
|
||||||
|
|
||||||
const std::vector<uint8>& iv() const { return iv_; }
|
const std::vector<uint8_t>& iv() const { return iv_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<uint8> iv_;
|
std::vector<uint8_t> iv_;
|
||||||
scoped_ptr<AES_KEY> encrypt_key_;
|
scoped_ptr<AES_KEY> encrypt_key_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(AesCbcPkcs5Encryptor);
|
DISALLOW_COPY_AND_ASSIGN(AesCbcPkcs5Encryptor);
|
||||||
|
@ -153,8 +153,8 @@ class AesCbcPkcs5Decryptor {
|
||||||
/// in AES spec.
|
/// in AES spec.
|
||||||
/// @param iv should be 16 bytes in size.
|
/// @param iv should be 16 bytes in size.
|
||||||
/// @return true on successful initialization, false otherwise.
|
/// @return true on successful initialization, false otherwise.
|
||||||
bool InitializeWithIv(const std::vector<uint8>& key,
|
bool InitializeWithIv(const std::vector<uint8_t>& key,
|
||||||
const std::vector<uint8>& iv);
|
const std::vector<uint8_t>& iv);
|
||||||
|
|
||||||
/// @param ciphertext is expected to be padded with PKCS5 padding.
|
/// @param ciphertext is expected to be padded with PKCS5 padding.
|
||||||
/// @param plaintext should not be NULL.
|
/// @param plaintext should not be NULL.
|
||||||
|
@ -162,12 +162,12 @@ class AesCbcPkcs5Decryptor {
|
||||||
bool Decrypt(const std::string& ciphertext, std::string* plaintext);
|
bool Decrypt(const std::string& ciphertext, std::string* plaintext);
|
||||||
|
|
||||||
/// @return true if successful, false if the input is invalid.
|
/// @return true if successful, false if the input is invalid.
|
||||||
bool SetIv(const std::vector<uint8>& iv);
|
bool SetIv(const std::vector<uint8_t>& iv);
|
||||||
|
|
||||||
const std::vector<uint8>& iv() const { return iv_; }
|
const std::vector<uint8_t>& iv() const { return iv_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<uint8> iv_;
|
std::vector<uint8_t> iv_;
|
||||||
scoped_ptr<AES_KEY> decrypt_key_;
|
scoped_ptr<AES_KEY> decrypt_key_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(AesCbcPkcs5Decryptor);
|
DISALLOW_COPY_AND_ASSIGN(AesCbcPkcs5Decryptor);
|
||||||
|
@ -185,32 +185,30 @@ class AesCbcCtsEncryptor {
|
||||||
/// in AES spec.
|
/// in AES spec.
|
||||||
/// @param iv should be 16 bytes in size.
|
/// @param iv should be 16 bytes in size.
|
||||||
/// @return true on successful initialization, false otherwise.
|
/// @return true on successful initialization, false otherwise.
|
||||||
bool InitializeWithIv(const std::vector<uint8>& key,
|
bool InitializeWithIv(const std::vector<uint8_t>& key,
|
||||||
const std::vector<uint8>& iv);
|
const std::vector<uint8_t>& iv);
|
||||||
|
|
||||||
/// @param plaintext points to the data to be encrypted.
|
/// @param plaintext points to the data to be encrypted.
|
||||||
/// @param size is the number of bytes to be encrypted. If less than 16
|
/// @param size is the number of bytes to be encrypted. If less than 16
|
||||||
/// bytes, it will be copied in the clear.
|
/// bytes, it will be copied in the clear.
|
||||||
/// @param ciphertext should not be NULL. The buffer should be at least
|
/// @param ciphertext should not be NULL. The buffer should be at least
|
||||||
/// @a size bytes in length.
|
/// @a size bytes in length.
|
||||||
void Encrypt(const uint8* plaintext,
|
void Encrypt(const uint8_t* plaintext, size_t size, uint8_t* ciphertext);
|
||||||
size_t size,
|
|
||||||
uint8* ciphertext);
|
|
||||||
|
|
||||||
/// @param plaintext contains the data to be encrypted. If less than 16
|
/// @param plaintext contains the data to be encrypted. If less than 16
|
||||||
/// bytes in size, it will be copied in the clear.
|
/// bytes in size, it will be copied in the clear.
|
||||||
/// @param ciphertext should not be NULL. Caller retains ownership.
|
/// @param ciphertext should not be NULL. Caller retains ownership.
|
||||||
void Encrypt(const std::vector<uint8>& plaintext,
|
void Encrypt(const std::vector<uint8_t>& plaintext,
|
||||||
std::vector<uint8>* ciphertext);
|
std::vector<uint8_t>* ciphertext);
|
||||||
|
|
||||||
/// @param iv is the initialization vector. Should be 16 bytes in size.
|
/// @param iv is the initialization vector. Should be 16 bytes in size.
|
||||||
/// @return true if successful, false if the input is invalid.
|
/// @return true if successful, false if the input is invalid.
|
||||||
bool SetIv(const std::vector<uint8>& iv);
|
bool SetIv(const std::vector<uint8_t>& iv);
|
||||||
|
|
||||||
const std::vector<uint8>& iv() const { return iv_; }
|
const std::vector<uint8_t>& iv() const { return iv_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<uint8> iv_;
|
std::vector<uint8_t> iv_;
|
||||||
scoped_ptr<AES_KEY> encrypt_key_;
|
scoped_ptr<AES_KEY> encrypt_key_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(AesCbcCtsEncryptor);
|
DISALLOW_COPY_AND_ASSIGN(AesCbcCtsEncryptor);
|
||||||
|
@ -228,31 +226,29 @@ class AesCbcCtsDecryptor {
|
||||||
/// in AES spec.
|
/// in AES spec.
|
||||||
/// @param iv should be 16 bytes in size.
|
/// @param iv should be 16 bytes in size.
|
||||||
/// @return true on successful initialization, false otherwise.
|
/// @return true on successful initialization, false otherwise.
|
||||||
bool InitializeWithIv(const std::vector<uint8>& key,
|
bool InitializeWithIv(const std::vector<uint8_t>& key,
|
||||||
const std::vector<uint8>& iv);
|
const std::vector<uint8_t>& iv);
|
||||||
|
|
||||||
/// @param ciphertext points to the data to be decrypted.
|
/// @param ciphertext points to the data to be decrypted.
|
||||||
/// @param size is the number of bytes to be decrypted. If less than 16
|
/// @param size is the number of bytes to be decrypted. If less than 16
|
||||||
/// bytes, it will be copied in the clear.
|
/// bytes, it will be copied in the clear.
|
||||||
/// @param plaintext should not be NULL. The buffer should be at least
|
/// @param plaintext should not be NULL. The buffer should be at least
|
||||||
/// @a size bytes in length.
|
/// @a size bytes in length.
|
||||||
void Decrypt(const uint8* ciphertext,
|
void Decrypt(const uint8_t* ciphertext, size_t size, uint8_t* plaintext);
|
||||||
size_t size,
|
|
||||||
uint8* plaintext);
|
|
||||||
|
|
||||||
/// @param ciphertext contains the data to be decrypted. If less than 16
|
/// @param ciphertext contains the data to be decrypted. If less than 16
|
||||||
/// bytes in size, it will be copied in the clear.
|
/// bytes in size, it will be copied in the clear.
|
||||||
/// @param plaintext should not be NULL. Caller retains ownership.
|
/// @param plaintext should not be NULL. Caller retains ownership.
|
||||||
void Decrypt(const std::vector<uint8>& ciphertext,
|
void Decrypt(const std::vector<uint8_t>& ciphertext,
|
||||||
std::vector<uint8>* plaintext);
|
std::vector<uint8_t>* plaintext);
|
||||||
|
|
||||||
/// @return true if successful, false if the input is invalid.
|
/// @return true if successful, false if the input is invalid.
|
||||||
bool SetIv(const std::vector<uint8>& iv);
|
bool SetIv(const std::vector<uint8_t>& iv);
|
||||||
|
|
||||||
const std::vector<uint8>& iv() const { return iv_; }
|
const std::vector<uint8_t>& iv() const { return iv_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<uint8> iv_;
|
std::vector<uint8_t> iv_;
|
||||||
scoped_ptr<AES_KEY> decrypt_key_;
|
scoped_ptr<AES_KEY> decrypt_key_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(AesCbcCtsDecryptor);
|
DISALLOW_COPY_AND_ASSIGN(AesCbcCtsDecryptor);
|
||||||
|
|
|
@ -13,17 +13,17 @@
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
const uint32 kAesBlockSize = 16;
|
const uint32_t kAesBlockSize = 16;
|
||||||
|
|
||||||
// From NIST SP 800-38a test case: - F.5.1 CTR-AES128.Encrypt
|
// From NIST SP 800-38a test case: - F.5.1 CTR-AES128.Encrypt
|
||||||
// http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
|
// http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
|
||||||
const uint8 kAesKey[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
|
const uint8_t kAesKey[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
|
||||||
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
|
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
|
||||||
|
|
||||||
const uint8 kAesIv[] = {0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
|
const uint8_t kAesIv[] = {0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
|
||||||
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff};
|
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff};
|
||||||
|
|
||||||
const uint8 kAesCtrPlaintext[] = {
|
const uint8_t kAesCtrPlaintext[] = {
|
||||||
// Block #1
|
// Block #1
|
||||||
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
|
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
|
||||||
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
|
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
|
||||||
|
@ -37,7 +37,7 @@ const uint8 kAesCtrPlaintext[] = {
|
||||||
0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
|
0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
|
||||||
0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10};
|
0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10};
|
||||||
|
|
||||||
const uint8 kAesCtrCiphertext[] = {
|
const uint8_t kAesCtrCiphertext[] = {
|
||||||
// Block #1
|
// Block #1
|
||||||
0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26,
|
0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26,
|
||||||
0x1b, 0xef, 0x68, 0x64, 0x99, 0x0d, 0xb6, 0xce,
|
0x1b, 0xef, 0x68, 0x64, 0x99, 0x0d, 0xb6, 0xce,
|
||||||
|
@ -53,20 +53,20 @@ const uint8 kAesCtrCiphertext[] = {
|
||||||
|
|
||||||
// Subsample test cases.
|
// Subsample test cases.
|
||||||
struct SubsampleTestCase {
|
struct SubsampleTestCase {
|
||||||
const uint8* subsample_sizes;
|
const uint8_t* subsample_sizes;
|
||||||
uint32 subsample_count;
|
uint32_t subsample_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint8 kSubsampleTest1[] = {64};
|
const uint8_t kSubsampleTest1[] = {64};
|
||||||
const uint8 kSubsampleTest2[] = {13, 51};
|
const uint8_t kSubsampleTest2[] = {13, 51};
|
||||||
const uint8 kSubsampleTest3[] = {52, 12};
|
const uint8_t kSubsampleTest3[] = {52, 12};
|
||||||
const uint8 kSubsampleTest4[] = {16, 48};
|
const uint8_t kSubsampleTest4[] = {16, 48};
|
||||||
const uint8 kSubsampleTest5[] = {3, 16, 45};
|
const uint8_t kSubsampleTest5[] = {3, 16, 45};
|
||||||
const uint8 kSubsampleTest6[] = {18, 12, 34};
|
const uint8_t kSubsampleTest6[] = {18, 12, 34};
|
||||||
const uint8 kSubsampleTest7[] = {8, 16, 2, 38};
|
const uint8_t kSubsampleTest7[] = {8, 16, 2, 38};
|
||||||
const uint8 kSubsampleTest8[] = {10, 1, 33, 20};
|
const uint8_t kSubsampleTest8[] = {10, 1, 33, 20};
|
||||||
const uint8 kSubsampleTest9[] = {7, 19, 6, 32};
|
const uint8_t kSubsampleTest9[] = {7, 19, 6, 32};
|
||||||
const uint8 kSubsampleTest10[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9};
|
const uint8_t kSubsampleTest10[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 9};
|
||||||
|
|
||||||
const SubsampleTestCase kSubsampleTestCases[] = {
|
const SubsampleTestCase kSubsampleTestCases[] = {
|
||||||
{kSubsampleTest1, arraysize(kSubsampleTest1)},
|
{kSubsampleTest1, arraysize(kSubsampleTest1)},
|
||||||
|
@ -81,29 +81,29 @@ const SubsampleTestCase kSubsampleTestCases[] = {
|
||||||
{kSubsampleTest10, arraysize(kSubsampleTest10)}};
|
{kSubsampleTest10, arraysize(kSubsampleTest10)}};
|
||||||
|
|
||||||
// IV test values.
|
// IV test values.
|
||||||
const uint32 kTextSizeInBytes = 60; // 3 full blocks + 1 partial block.
|
const uint32_t kTextSizeInBytes = 60; // 3 full blocks + 1 partial block.
|
||||||
|
|
||||||
const uint8 kIv128Zero[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
const uint8_t kIv128Zero[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
const uint8 kIv128Two[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2};
|
const uint8_t kIv128Two[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2};
|
||||||
const uint8 kIv128Four[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4};
|
const uint8_t kIv128Four[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4};
|
||||||
const uint8 kIv128Max64[] = {0, 0, 0, 0, 0, 0, 0, 0,
|
const uint8_t kIv128Max64[] = {0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||||
const uint8 kIv128OneAndThree[] = {0, 0, 0, 0, 0, 0, 0, 1,
|
const uint8_t kIv128OneAndThree[] = {0, 0, 0, 0, 0, 0, 0, 1,
|
||||||
0, 0, 0, 0, 0, 0, 0, 3};
|
0, 0, 0, 0, 0, 0, 0, 3};
|
||||||
const uint8 kIv128MaxMinusOne[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
const uint8_t kIv128MaxMinusOne[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
0xff, 0xff, 0xff, 0xfe};
|
0xff, 0xff, 0xff, 0xfe};
|
||||||
|
|
||||||
const uint8 kIv64Zero[] = {0, 0, 0, 0, 0, 0, 0, 0};
|
const uint8_t kIv64Zero[] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
const uint8 kIv64One[] = {0, 0, 0, 0, 0, 0, 0, 1};
|
const uint8_t kIv64One[] = {0, 0, 0, 0, 0, 0, 0, 1};
|
||||||
const uint8 kIv64MaxMinusOne[] = {0xff, 0xff, 0xff, 0xff,
|
const uint8_t kIv64MaxMinusOne[] = {0xff, 0xff, 0xff, 0xff,
|
||||||
0xff, 0xff, 0xff, 0xfe};
|
0xff, 0xff, 0xff, 0xfe};
|
||||||
const uint8 kIv64Max[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
const uint8_t kIv64Max[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||||
|
|
||||||
struct IvTestCase {
|
struct IvTestCase {
|
||||||
const uint8* iv_test;
|
const uint8_t* iv_test;
|
||||||
uint32 iv_size;
|
uint32_t iv_size;
|
||||||
const uint8* iv_expected;
|
const uint8_t* iv_expected;
|
||||||
};
|
};
|
||||||
|
|
||||||
// As recommended in ISO/IEC FDIS 23001-7: CENC spec,
|
// As recommended in ISO/IEC FDIS 23001-7: CENC spec,
|
||||||
|
@ -121,12 +121,12 @@ const IvTestCase kIvTestCases[] = {
|
||||||
{kIv64Max, arraysize(kIv64Max), kIv64Zero}};
|
{kIv64Max, arraysize(kIv64Max), kIv64Zero}};
|
||||||
|
|
||||||
// We support AES 128, i.e. 16 bytes key only.
|
// We support AES 128, i.e. 16 bytes key only.
|
||||||
const uint8 kInvalidKey[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2,
|
const uint8_t kInvalidKey[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2,
|
||||||
0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09};
|
0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09};
|
||||||
|
|
||||||
// We support Iv of size 8 or 16 only as defined in CENC spec.
|
// We support Iv of size 8 or 16 only as defined in CENC spec.
|
||||||
const uint8 kInvalidIv[] = {0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
|
const uint8_t kInvalidIv[] = {0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
|
||||||
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe};
|
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
@ -147,26 +147,26 @@ class AesCtrEncryptorTest : public testing::Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::vector<uint8> key_;
|
std::vector<uint8_t> key_;
|
||||||
std::vector<uint8> iv_;
|
std::vector<uint8_t> iv_;
|
||||||
std::vector<uint8> plaintext_;
|
std::vector<uint8_t> plaintext_;
|
||||||
std::vector<uint8> ciphertext_;
|
std::vector<uint8_t> ciphertext_;
|
||||||
AesCtrEncryptor encryptor_;
|
AesCtrEncryptor encryptor_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(AesCtrEncryptorTest, NistTestCase) {
|
TEST_F(AesCtrEncryptorTest, NistTestCase) {
|
||||||
std::vector<uint8> encrypted;
|
std::vector<uint8_t> encrypted;
|
||||||
EXPECT_TRUE(encryptor_.Encrypt(plaintext_, &encrypted));
|
EXPECT_TRUE(encryptor_.Encrypt(plaintext_, &encrypted));
|
||||||
EXPECT_EQ(ciphertext_, encrypted);
|
EXPECT_EQ(ciphertext_, encrypted);
|
||||||
|
|
||||||
EXPECT_TRUE(encryptor_.SetIv(iv_));
|
EXPECT_TRUE(encryptor_.SetIv(iv_));
|
||||||
std::vector<uint8> decrypted;
|
std::vector<uint8_t> decrypted;
|
||||||
EXPECT_TRUE(encryptor_.Decrypt(encrypted, &decrypted));
|
EXPECT_TRUE(encryptor_.Decrypt(encrypted, &decrypted));
|
||||||
EXPECT_EQ(plaintext_, decrypted);
|
EXPECT_EQ(plaintext_, decrypted);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AesCtrEncryptorTest, NistTestCaseInplaceEncryptionDecryption) {
|
TEST_F(AesCtrEncryptorTest, NistTestCaseInplaceEncryptionDecryption) {
|
||||||
std::vector<uint8> buffer = plaintext_;
|
std::vector<uint8_t> buffer = plaintext_;
|
||||||
EXPECT_TRUE(encryptor_.Encrypt(&buffer[0], buffer.size(), &buffer[0]));
|
EXPECT_TRUE(encryptor_.Encrypt(&buffer[0], buffer.size(), &buffer[0]));
|
||||||
EXPECT_EQ(ciphertext_, buffer);
|
EXPECT_EQ(ciphertext_, buffer);
|
||||||
|
|
||||||
|
@ -195,22 +195,22 @@ TEST_F(AesCtrEncryptorTest, 128BitIVBoundaryCaseEncryption) {
|
||||||
// There are four blocks of text in |plaintext_|. The first block should be
|
// There are four blocks of text in |plaintext_|. The first block should be
|
||||||
// encrypted with IV = kIv128Max64, the subsequent blocks should be encrypted
|
// encrypted with IV = kIv128Max64, the subsequent blocks should be encrypted
|
||||||
// with iv 0 to 3.
|
// with iv 0 to 3.
|
||||||
std::vector<uint8> iv_max64(kIv128Max64,
|
std::vector<uint8_t> iv_max64(kIv128Max64,
|
||||||
kIv128Max64 + arraysize(kIv128Max64));
|
kIv128Max64 + arraysize(kIv128Max64));
|
||||||
ASSERT_TRUE(encryptor_.InitializeWithIv(key_, iv_max64));
|
ASSERT_TRUE(encryptor_.InitializeWithIv(key_, iv_max64));
|
||||||
std::vector<uint8> encrypted;
|
std::vector<uint8_t> encrypted;
|
||||||
EXPECT_TRUE(encryptor_.Encrypt(plaintext_, &encrypted));
|
EXPECT_TRUE(encryptor_.Encrypt(plaintext_, &encrypted));
|
||||||
|
|
||||||
std::vector<uint8> iv_one_and_three(
|
std::vector<uint8_t> iv_one_and_three(
|
||||||
kIv128OneAndThree, kIv128OneAndThree + arraysize(kIv128OneAndThree));
|
kIv128OneAndThree, kIv128OneAndThree + arraysize(kIv128OneAndThree));
|
||||||
encryptor_.UpdateIv();
|
encryptor_.UpdateIv();
|
||||||
EXPECT_EQ(iv_one_and_three, encryptor_.iv());
|
EXPECT_EQ(iv_one_and_three, encryptor_.iv());
|
||||||
|
|
||||||
ASSERT_TRUE(encryptor_.InitializeWithIv(key_, iv_max64));
|
ASSERT_TRUE(encryptor_.InitializeWithIv(key_, iv_max64));
|
||||||
std::vector<uint8> encrypted_verify(plaintext_.size(), 0);
|
std::vector<uint8_t> encrypted_verify(plaintext_.size(), 0);
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
encryptor_.Encrypt(&plaintext_[0], kAesBlockSize, &encrypted_verify[0]));
|
encryptor_.Encrypt(&plaintext_[0], kAesBlockSize, &encrypted_verify[0]));
|
||||||
std::vector<uint8> iv_zero(kIv128Zero, kIv128Zero + arraysize(kIv128Zero));
|
std::vector<uint8_t> iv_zero(kIv128Zero, kIv128Zero + arraysize(kIv128Zero));
|
||||||
ASSERT_TRUE(encryptor_.InitializeWithIv(key_, iv_zero));
|
ASSERT_TRUE(encryptor_.InitializeWithIv(key_, iv_zero));
|
||||||
EXPECT_TRUE(encryptor_.Encrypt(&plaintext_[kAesBlockSize],
|
EXPECT_TRUE(encryptor_.Encrypt(&plaintext_[kAesBlockSize],
|
||||||
kAesBlockSize * 3,
|
kAesBlockSize * 3,
|
||||||
|
@ -219,7 +219,7 @@ TEST_F(AesCtrEncryptorTest, 128BitIVBoundaryCaseEncryption) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AesCtrEncryptorTest, InitWithRandomIv) {
|
TEST_F(AesCtrEncryptorTest, InitWithRandomIv) {
|
||||||
const uint8 kIvSize = 8;
|
const uint8_t kIvSize = 8;
|
||||||
ASSERT_TRUE(encryptor_.InitializeWithRandomIv(key_, kIvSize));
|
ASSERT_TRUE(encryptor_.InitializeWithRandomIv(key_, kIvSize));
|
||||||
ASSERT_EQ(kIvSize, encryptor_.iv().size());
|
ASSERT_EQ(kIvSize, encryptor_.iv().size());
|
||||||
LOG(INFO) << "Random IV: " << base::HexEncode(&encryptor_.iv()[0],
|
LOG(INFO) << "Random IV: " << base::HexEncode(&encryptor_.iv()[0],
|
||||||
|
@ -227,12 +227,12 @@ TEST_F(AesCtrEncryptorTest, InitWithRandomIv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AesCtrEncryptorTest, UnsupportedKeySize) {
|
TEST_F(AesCtrEncryptorTest, UnsupportedKeySize) {
|
||||||
std::vector<uint8> key(kInvalidKey, kInvalidKey + arraysize(kInvalidKey));
|
std::vector<uint8_t> key(kInvalidKey, kInvalidKey + arraysize(kInvalidKey));
|
||||||
ASSERT_FALSE(encryptor_.InitializeWithIv(key, iv_));
|
ASSERT_FALSE(encryptor_.InitializeWithIv(key, iv_));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AesCtrEncryptorTest, UnsupportedIV) {
|
TEST_F(AesCtrEncryptorTest, UnsupportedIV) {
|
||||||
std::vector<uint8> iv(kInvalidIv, kInvalidIv + arraysize(kInvalidIv));
|
std::vector<uint8_t> iv(kInvalidIv, kInvalidIv + arraysize(kInvalidIv));
|
||||||
ASSERT_FALSE(encryptor_.InitializeWithIv(key_, iv));
|
ASSERT_FALSE(encryptor_.InitializeWithIv(key_, iv));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,9 +247,9 @@ class AesCtrEncryptorSubsampleTest
|
||||||
TEST_P(AesCtrEncryptorSubsampleTest, NistTestCaseSubsamples) {
|
TEST_P(AesCtrEncryptorSubsampleTest, NistTestCaseSubsamples) {
|
||||||
const SubsampleTestCase* test_case = &GetParam();
|
const SubsampleTestCase* test_case = &GetParam();
|
||||||
|
|
||||||
std::vector<uint8> encrypted(plaintext_.size(), 0);
|
std::vector<uint8_t> encrypted(plaintext_.size(), 0);
|
||||||
for (uint32 i = 0, offset = 0; i < test_case->subsample_count; ++i) {
|
for (uint32_t i = 0, offset = 0; i < test_case->subsample_count; ++i) {
|
||||||
uint32 len = test_case->subsample_sizes[i];
|
uint32_t len = test_case->subsample_sizes[i];
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
encryptor_.Encrypt(&plaintext_[offset], len, &encrypted[offset]));
|
encryptor_.Encrypt(&plaintext_[offset], len, &encrypted[offset]));
|
||||||
offset += len;
|
offset += len;
|
||||||
|
@ -258,9 +258,9 @@ TEST_P(AesCtrEncryptorSubsampleTest, NistTestCaseSubsamples) {
|
||||||
EXPECT_EQ(ciphertext_, encrypted);
|
EXPECT_EQ(ciphertext_, encrypted);
|
||||||
|
|
||||||
EXPECT_TRUE(encryptor_.SetIv(iv_));
|
EXPECT_TRUE(encryptor_.SetIv(iv_));
|
||||||
std::vector<uint8> decrypted(encrypted.size(), 0);
|
std::vector<uint8_t> decrypted(encrypted.size(), 0);
|
||||||
for (uint32 i = 0, offset = 0; i < test_case->subsample_count; ++i) {
|
for (uint32_t i = 0, offset = 0; i < test_case->subsample_count; ++i) {
|
||||||
uint32 len = test_case->subsample_sizes[i];
|
uint32_t len = test_case->subsample_sizes[i];
|
||||||
EXPECT_TRUE(
|
EXPECT_TRUE(
|
||||||
encryptor_.Decrypt(&encrypted[offset], len, &decrypted[offset]));
|
encryptor_.Decrypt(&encrypted[offset], len, &decrypted[offset]));
|
||||||
offset += len;
|
offset += len;
|
||||||
|
@ -277,18 +277,18 @@ class AesCtrEncryptorIvTest : public ::testing::TestWithParam<IvTestCase> {};
|
||||||
|
|
||||||
TEST_P(AesCtrEncryptorIvTest, IvTest) {
|
TEST_P(AesCtrEncryptorIvTest, IvTest) {
|
||||||
// Some dummy key and plaintext.
|
// Some dummy key and plaintext.
|
||||||
std::vector<uint8> key(16, 1);
|
std::vector<uint8_t> key(16, 1);
|
||||||
std::vector<uint8> plaintext(kTextSizeInBytes, 3);
|
std::vector<uint8_t> plaintext(kTextSizeInBytes, 3);
|
||||||
|
|
||||||
std::vector<uint8> iv_test(GetParam().iv_test,
|
std::vector<uint8_t> iv_test(GetParam().iv_test,
|
||||||
GetParam().iv_test + GetParam().iv_size);
|
GetParam().iv_test + GetParam().iv_size);
|
||||||
std::vector<uint8> iv_expected(GetParam().iv_expected,
|
std::vector<uint8_t> iv_expected(GetParam().iv_expected,
|
||||||
GetParam().iv_expected + GetParam().iv_size);
|
GetParam().iv_expected + GetParam().iv_size);
|
||||||
|
|
||||||
AesCtrEncryptor encryptor;
|
AesCtrEncryptor encryptor;
|
||||||
ASSERT_TRUE(encryptor.InitializeWithIv(key, iv_test));
|
ASSERT_TRUE(encryptor.InitializeWithIv(key, iv_test));
|
||||||
|
|
||||||
std::vector<uint8> encrypted;
|
std::vector<uint8_t> encrypted;
|
||||||
EXPECT_TRUE(encryptor.Encrypt(plaintext, &encrypted));
|
EXPECT_TRUE(encryptor.Encrypt(plaintext, &encrypted));
|
||||||
encryptor.UpdateIv();
|
encryptor.UpdateIv();
|
||||||
EXPECT_EQ(iv_expected, encryptor.iv());
|
EXPECT_EQ(iv_expected, encryptor.iv());
|
||||||
|
@ -300,8 +300,8 @@ INSTANTIATE_TEST_CASE_P(IvTestCases,
|
||||||
|
|
||||||
class AesCbcPkcs5EncryptorTestEncryptionDecryption : public testing::Test {
|
class AesCbcPkcs5EncryptorTestEncryptionDecryption : public testing::Test {
|
||||||
public:
|
public:
|
||||||
void TestEncryptionDecryption(const std::vector<uint8>& key,
|
void TestEncryptionDecryption(const std::vector<uint8_t>& key,
|
||||||
const std::vector<uint8>& iv,
|
const std::vector<uint8_t>& iv,
|
||||||
const std::string& plaintext,
|
const std::string& plaintext,
|
||||||
const std::string& expected_ciphertext_hex) {
|
const std::string& expected_ciphertext_hex) {
|
||||||
AesCbcPkcs5Encryptor encryptor;
|
AesCbcPkcs5Encryptor encryptor;
|
||||||
|
@ -323,14 +323,14 @@ class AesCbcPkcs5EncryptorTestEncryptionDecryption : public testing::Test {
|
||||||
|
|
||||||
TEST_F(AesCbcPkcs5EncryptorTestEncryptionDecryption, EncryptAES256CBC) {
|
TEST_F(AesCbcPkcs5EncryptorTestEncryptionDecryption, EncryptAES256CBC) {
|
||||||
// NIST SP 800-38A test vector F.2.5 CBC-AES256.Encrypt.
|
// NIST SP 800-38A test vector F.2.5 CBC-AES256.Encrypt.
|
||||||
static const uint8 kAesCbcKey[] = {
|
static const uint8_t kAesCbcKey[] = {
|
||||||
0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae,
|
0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae,
|
||||||
0xf0, 0x85, 0x7d, 0x77, 0x81, 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61,
|
0xf0, 0x85, 0x7d, 0x77, 0x81, 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61,
|
||||||
0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4};
|
0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4};
|
||||||
static const uint8 kAesCbcIv[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
|
static const uint8_t kAesCbcIv[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
|
||||||
0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
|
0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
|
||||||
0x0c, 0x0d, 0x0e, 0x0f};
|
0x0c, 0x0d, 0x0e, 0x0f};
|
||||||
static const uint8 kAesCbcPlaintext[] = {
|
static const uint8_t kAesCbcPlaintext[] = {
|
||||||
// Block #1
|
// Block #1
|
||||||
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
|
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
|
||||||
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
|
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
|
||||||
|
@ -343,7 +343,7 @@ TEST_F(AesCbcPkcs5EncryptorTestEncryptionDecryption, EncryptAES256CBC) {
|
||||||
// Block #4
|
// Block #4
|
||||||
0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
|
0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
|
||||||
0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10};
|
0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10};
|
||||||
static const uint8 kAesCbcCiphertext[] = {
|
static const uint8_t kAesCbcCiphertext[] = {
|
||||||
// Block #1
|
// Block #1
|
||||||
0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba,
|
0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba,
|
||||||
0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6,
|
0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6,
|
||||||
|
@ -360,8 +360,9 @@ TEST_F(AesCbcPkcs5EncryptorTestEncryptionDecryption, EncryptAES256CBC) {
|
||||||
0x3f, 0x46, 0x17, 0x96, 0xd6, 0xb0, 0xd6, 0xb2,
|
0x3f, 0x46, 0x17, 0x96, 0xd6, 0xb0, 0xd6, 0xb2,
|
||||||
0xe0, 0xc2, 0xa7, 0x2b, 0x4d, 0x80, 0xe6, 0x44};
|
0xe0, 0xc2, 0xa7, 0x2b, 0x4d, 0x80, 0xe6, 0x44};
|
||||||
|
|
||||||
const std::vector<uint8> key(kAesCbcKey, kAesCbcKey + arraysize(kAesCbcKey));
|
const std::vector<uint8_t> key(kAesCbcKey,
|
||||||
const std::vector<uint8> iv(kAesCbcIv, kAesCbcIv + arraysize(kAesCbcIv));
|
kAesCbcKey + arraysize(kAesCbcKey));
|
||||||
|
const std::vector<uint8_t> iv(kAesCbcIv, kAesCbcIv + arraysize(kAesCbcIv));
|
||||||
const std::string plaintext(reinterpret_cast<const char*>(kAesCbcPlaintext),
|
const std::string plaintext(reinterpret_cast<const char*>(kAesCbcPlaintext),
|
||||||
sizeof(kAesCbcPlaintext));
|
sizeof(kAesCbcPlaintext));
|
||||||
const std::string expected_ciphertext_hex =
|
const std::string expected_ciphertext_hex =
|
||||||
|
@ -379,8 +380,8 @@ TEST_F(AesCbcPkcs5EncryptorTestEncryptionDecryption, EncryptAES128CBCRegression)
|
||||||
"D4A67A0BA33C30F207344D81D1E944BBE65587C3D7D9939A"
|
"D4A67A0BA33C30F207344D81D1E944BBE65587C3D7D9939A"
|
||||||
"C070C62B9C15A3EA312EA4AD1BC7929F4D3C16B03AD5ADA8";
|
"C070C62B9C15A3EA312EA4AD1BC7929F4D3C16B03AD5ADA8";
|
||||||
|
|
||||||
const std::vector<uint8> key(kKey.begin(), kKey.end());
|
const std::vector<uint8_t> key(kKey.begin(), kKey.end());
|
||||||
const std::vector<uint8> iv(kIv.begin(), kIv.end());
|
const std::vector<uint8_t> iv(kIv.begin(), kIv.end());
|
||||||
|
|
||||||
TestEncryptionDecryption(key, iv, kPlaintext, kExpectedCiphertextHex);
|
TestEncryptionDecryption(key, iv, kPlaintext, kExpectedCiphertextHex);
|
||||||
}
|
}
|
||||||
|
@ -391,8 +392,8 @@ TEST_F(AesCbcPkcs5EncryptorTestEncryptionDecryption, EncryptAES192CBCRegression)
|
||||||
const std::string kPlaintext = "Small text";
|
const std::string kPlaintext = "Small text";
|
||||||
const std::string kExpectedCiphertextHex = "78DE5D7C2714FC5C61346C5416F6C89A";
|
const std::string kExpectedCiphertextHex = "78DE5D7C2714FC5C61346C5416F6C89A";
|
||||||
|
|
||||||
const std::vector<uint8> key(kKey.begin(), kKey.end());
|
const std::vector<uint8_t> key(kKey.begin(), kKey.end());
|
||||||
const std::vector<uint8> iv(kIv.begin(), kIv.end());
|
const std::vector<uint8_t> iv(kIv.begin(), kIv.end());
|
||||||
|
|
||||||
TestEncryptionDecryption(key, iv, kPlaintext, kExpectedCiphertextHex);
|
TestEncryptionDecryption(key, iv, kPlaintext, kExpectedCiphertextHex);
|
||||||
}
|
}
|
||||||
|
@ -407,18 +408,18 @@ class AesCbcPkcs5EncryptorTest : public testing::Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::vector<uint8> key_;
|
std::vector<uint8_t> key_;
|
||||||
std::vector<uint8> iv_;
|
std::vector<uint8_t> iv_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(AesCbcPkcs5EncryptorTest, UnsupportedKeySize) {
|
TEST_F(AesCbcPkcs5EncryptorTest, UnsupportedKeySize) {
|
||||||
AesCbcPkcs5Encryptor encryptor;
|
AesCbcPkcs5Encryptor encryptor;
|
||||||
EXPECT_FALSE(encryptor.InitializeWithIv(std::vector<uint8>(15, 0), iv_));
|
EXPECT_FALSE(encryptor.InitializeWithIv(std::vector<uint8_t>(15, 0), iv_));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AesCbcPkcs5EncryptorTest, UnsupportedIvSize) {
|
TEST_F(AesCbcPkcs5EncryptorTest, UnsupportedIvSize) {
|
||||||
AesCbcPkcs5Encryptor encryptor;
|
AesCbcPkcs5Encryptor encryptor;
|
||||||
EXPECT_FALSE(encryptor.InitializeWithIv(key_, std::vector<uint8>(14, 0)));
|
EXPECT_FALSE(encryptor.InitializeWithIv(key_, std::vector<uint8_t>(14, 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AesCbcPkcs5EncryptorTest, EmptyEncrypt) {
|
TEST_F(AesCbcPkcs5EncryptorTest, EmptyEncrypt) {
|
||||||
|
@ -448,27 +449,27 @@ class AesCbcCtsEncryptorDecryptorTest : public testing::Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestEncryptDecryptSeparateBuffers(
|
void TestEncryptDecryptSeparateBuffers(
|
||||||
const std::vector<uint8>& plaintext,
|
const std::vector<uint8_t>& plaintext,
|
||||||
const std::vector<uint8>& expected_ciphertext) {
|
const std::vector<uint8_t>& expected_ciphertext) {
|
||||||
ASSERT_TRUE(encryptor_.InitializeWithIv(key_, iv_));
|
ASSERT_TRUE(encryptor_.InitializeWithIv(key_, iv_));
|
||||||
ASSERT_TRUE(decryptor_.InitializeWithIv(key_, iv_));
|
ASSERT_TRUE(decryptor_.InitializeWithIv(key_, iv_));
|
||||||
|
|
||||||
std::vector<uint8> encrypted;
|
std::vector<uint8_t> encrypted;
|
||||||
encryptor_.Encrypt(plaintext, &encrypted);
|
encryptor_.Encrypt(plaintext, &encrypted);
|
||||||
EXPECT_EQ(expected_ciphertext, encrypted);
|
EXPECT_EQ(expected_ciphertext, encrypted);
|
||||||
|
|
||||||
std::vector<uint8> decrypted;
|
std::vector<uint8_t> decrypted;
|
||||||
decryptor_.Decrypt(encrypted, &decrypted);
|
decryptor_.Decrypt(encrypted, &decrypted);
|
||||||
EXPECT_EQ(plaintext, decrypted);
|
EXPECT_EQ(plaintext, decrypted);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestEncryptDecryptInPlace(
|
void TestEncryptDecryptInPlace(
|
||||||
const std::vector<uint8>& plaintext,
|
const std::vector<uint8_t>& plaintext,
|
||||||
const std::vector<uint8>& expected_ciphertext) {
|
const std::vector<uint8_t>& expected_ciphertext) {
|
||||||
ASSERT_TRUE(encryptor_.InitializeWithIv(key_, iv_));
|
ASSERT_TRUE(encryptor_.InitializeWithIv(key_, iv_));
|
||||||
ASSERT_TRUE(decryptor_.InitializeWithIv(key_, iv_));
|
ASSERT_TRUE(decryptor_.InitializeWithIv(key_, iv_));
|
||||||
|
|
||||||
std::vector<uint8> buffer(plaintext);
|
std::vector<uint8_t> buffer(plaintext);
|
||||||
encryptor_.Encrypt(buffer, &buffer);
|
encryptor_.Encrypt(buffer, &buffer);
|
||||||
EXPECT_EQ(expected_ciphertext, buffer);
|
EXPECT_EQ(expected_ciphertext, buffer);
|
||||||
decryptor_.Decrypt(buffer, &buffer);
|
decryptor_.Decrypt(buffer, &buffer);
|
||||||
|
@ -476,20 +477,20 @@ class AesCbcCtsEncryptorDecryptorTest : public testing::Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::vector<uint8> key_;
|
std::vector<uint8_t> key_;
|
||||||
std::vector<uint8> iv_;
|
std::vector<uint8_t> iv_;
|
||||||
AesCbcCtsEncryptor encryptor_;
|
AesCbcCtsEncryptor encryptor_;
|
||||||
AesCbcCtsDecryptor decryptor_;
|
AesCbcCtsDecryptor decryptor_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(AesCbcCtsEncryptorDecryptorTest, TestWithResidualBytes) {
|
TEST_F(AesCbcCtsEncryptorDecryptorTest, TestWithResidualBytes) {
|
||||||
std::vector<uint8> plaintext;
|
std::vector<uint8_t> plaintext;
|
||||||
ASSERT_TRUE(base::HexStringToBytes(
|
ASSERT_TRUE(base::HexStringToBytes(
|
||||||
"e0818f2dc7caaa9edf09285a0c1fca98d39e9b08a47ab6911c4bbdf27d94"
|
"e0818f2dc7caaa9edf09285a0c1fca98d39e9b08a47ab6911c4bbdf27d94"
|
||||||
"f917cdffc9ebb307141f23b0d3921e0ed7f86eb09381286f8e7a4f",
|
"f917cdffc9ebb307141f23b0d3921e0ed7f86eb09381286f8e7a4f",
|
||||||
&plaintext));
|
&plaintext));
|
||||||
|
|
||||||
std::vector<uint8> ciphertext;
|
std::vector<uint8_t> ciphertext;
|
||||||
ASSERT_TRUE(base::HexStringToBytes(
|
ASSERT_TRUE(base::HexStringToBytes(
|
||||||
"b40a0b8704c74e22e8030cad6f272b34ace54cc7c9c64b2018bbcf23df018"
|
"b40a0b8704c74e22e8030cad6f272b34ace54cc7c9c64b2018bbcf23df018"
|
||||||
"39b14899441cf74a9fb2f2b229a609146f31be8e8a826eb6e857e",
|
"39b14899441cf74a9fb2f2b229a609146f31be8e8a826eb6e857e",
|
||||||
|
@ -500,13 +501,13 @@ TEST_F(AesCbcCtsEncryptorDecryptorTest, TestWithResidualBytes) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AesCbcCtsEncryptorDecryptorTest, TestEvenBlocks) {
|
TEST_F(AesCbcCtsEncryptorDecryptorTest, TestEvenBlocks) {
|
||||||
std::vector<uint8> plaintext;
|
std::vector<uint8_t> plaintext;
|
||||||
ASSERT_TRUE(base::HexStringToBytes(
|
ASSERT_TRUE(base::HexStringToBytes(
|
||||||
"3f593e7a204a5e70f2814dca05aa49d36f2daddc9a24e0515802c539efc3"
|
"3f593e7a204a5e70f2814dca05aa49d36f2daddc9a24e0515802c539efc3"
|
||||||
"1094b3ad6c26d6f5c0e387545ce6a4c2c14d",
|
"1094b3ad6c26d6f5c0e387545ce6a4c2c14d",
|
||||||
&plaintext));
|
&plaintext));
|
||||||
|
|
||||||
std::vector<uint8> ciphertext;
|
std::vector<uint8_t> ciphertext;
|
||||||
ASSERT_TRUE(base::HexStringToBytes(
|
ASSERT_TRUE(base::HexStringToBytes(
|
||||||
"5f32cd0504b27b25ee04090d88d37d340c9c0a9fa50b05358b98fad4302ea"
|
"5f32cd0504b27b25ee04090d88d37d340c9c0a9fa50b05358b98fad4302ea"
|
||||||
"480148d8aa091f4e7d186a7223df153f6f7",
|
"480148d8aa091f4e7d186a7223df153f6f7",
|
||||||
|
@ -517,12 +518,12 @@ TEST_F(AesCbcCtsEncryptorDecryptorTest, TestEvenBlocks) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AesCbcCtsEncryptorDecryptorTest, TestOneBlockAndAHalf) {
|
TEST_F(AesCbcCtsEncryptorDecryptorTest, TestOneBlockAndAHalf) {
|
||||||
std::vector<uint8> plaintext;
|
std::vector<uint8_t> plaintext;
|
||||||
ASSERT_TRUE(base::HexStringToBytes(
|
ASSERT_TRUE(base::HexStringToBytes(
|
||||||
"3f593e7a204a5e70f2814dca05aa49d36f2daddc9a4302ea",
|
"3f593e7a204a5e70f2814dca05aa49d36f2daddc9a4302ea",
|
||||||
&plaintext));
|
&plaintext));
|
||||||
|
|
||||||
std::vector<uint8> ciphertext;
|
std::vector<uint8_t> ciphertext;
|
||||||
ASSERT_TRUE(base::HexStringToBytes(
|
ASSERT_TRUE(base::HexStringToBytes(
|
||||||
"623fc113fe02ce85628deb58d652c6995f32cd0504b27b25",
|
"623fc113fe02ce85628deb58d652c6995f32cd0504b27b25",
|
||||||
&ciphertext));
|
&ciphertext));
|
||||||
|
@ -532,7 +533,7 @@ TEST_F(AesCbcCtsEncryptorDecryptorTest, TestOneBlockAndAHalf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AesCbcCtsEncryptorDecryptorTest, TestZeroEncryptedBlocks) {
|
TEST_F(AesCbcCtsEncryptorDecryptorTest, TestZeroEncryptedBlocks) {
|
||||||
std::vector<uint8> plaintext;
|
std::vector<uint8_t> plaintext;
|
||||||
ASSERT_TRUE(base::HexStringToBytes("3f593e7a204a5e70f2", &plaintext));
|
ASSERT_TRUE(base::HexStringToBytes("3f593e7a204a5e70f2", &plaintext));
|
||||||
|
|
||||||
TestEncryptDecryptSeparateBuffers(plaintext, plaintext);
|
TestEncryptDecryptSeparateBuffers(plaintext, plaintext);
|
||||||
|
@ -540,7 +541,7 @@ TEST_F(AesCbcCtsEncryptorDecryptorTest, TestZeroEncryptedBlocks) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AesCbcCtsEncryptorDecryptorTest, TestZeroBytes) {
|
TEST_F(AesCbcCtsEncryptorDecryptorTest, TestZeroBytes) {
|
||||||
std::vector<uint8> plaintext;
|
std::vector<uint8_t> plaintext;
|
||||||
|
|
||||||
TestEncryptDecryptSeparateBuffers(plaintext, plaintext);
|
TestEncryptDecryptSeparateBuffers(plaintext, plaintext);
|
||||||
TestEncryptDecryptInPlace(plaintext, plaintext);
|
TestEncryptDecryptInPlace(plaintext, plaintext);
|
||||||
|
|
|
@ -51,15 +51,15 @@ std::string AudioCodecToString(AudioCodec audio_codec) {
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
AudioStreamInfo::AudioStreamInfo(int track_id,
|
AudioStreamInfo::AudioStreamInfo(int track_id,
|
||||||
uint32 time_scale,
|
uint32_t time_scale,
|
||||||
uint64 duration,
|
uint64_t duration,
|
||||||
AudioCodec codec,
|
AudioCodec codec,
|
||||||
const std::string& codec_string,
|
const std::string& codec_string,
|
||||||
const std::string& language,
|
const std::string& language,
|
||||||
uint8 sample_bits,
|
uint8_t sample_bits,
|
||||||
uint8 num_channels,
|
uint8_t num_channels,
|
||||||
uint32 sampling_frequency,
|
uint32_t sampling_frequency,
|
||||||
const uint8* extra_data,
|
const uint8_t* extra_data,
|
||||||
size_t extra_data_size,
|
size_t extra_data_size,
|
||||||
bool is_encrypted)
|
bool is_encrypted)
|
||||||
: StreamInfo(kStreamAudio,
|
: StreamInfo(kStreamAudio,
|
||||||
|
@ -74,7 +74,8 @@ AudioStreamInfo::AudioStreamInfo(int track_id,
|
||||||
codec_(codec),
|
codec_(codec),
|
||||||
sample_bits_(sample_bits),
|
sample_bits_(sample_bits),
|
||||||
num_channels_(num_channels),
|
num_channels_(num_channels),
|
||||||
sampling_frequency_(sampling_frequency) {}
|
sampling_frequency_(sampling_frequency) {
|
||||||
|
}
|
||||||
|
|
||||||
AudioStreamInfo::~AudioStreamInfo() {}
|
AudioStreamInfo::~AudioStreamInfo() {}
|
||||||
|
|
||||||
|
@ -98,7 +99,7 @@ std::string AudioStreamInfo::ToString() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AudioStreamInfo::GetCodecString(AudioCodec codec,
|
std::string AudioStreamInfo::GetCodecString(AudioCodec codec,
|
||||||
uint8 audio_object_type) {
|
uint8_t audio_object_type) {
|
||||||
switch (codec) {
|
switch (codec) {
|
||||||
case kCodecVorbis:
|
case kCodecVorbis:
|
||||||
return "vorbis";
|
return "vorbis";
|
||||||
|
|
|
@ -38,15 +38,15 @@ class AudioStreamInfo : public StreamInfo {
|
||||||
public:
|
public:
|
||||||
/// Construct an initialized audio stream info object.
|
/// Construct an initialized audio stream info object.
|
||||||
AudioStreamInfo(int track_id,
|
AudioStreamInfo(int track_id,
|
||||||
uint32 time_scale,
|
uint32_t time_scale,
|
||||||
uint64 duration,
|
uint64_t duration,
|
||||||
AudioCodec codec,
|
AudioCodec codec,
|
||||||
const std::string& codec_string,
|
const std::string& codec_string,
|
||||||
const std::string& language,
|
const std::string& language,
|
||||||
uint8 sample_bits,
|
uint8_t sample_bits,
|
||||||
uint8 num_channels,
|
uint8_t num_channels,
|
||||||
uint32 sampling_frequency,
|
uint32_t sampling_frequency,
|
||||||
const uint8* extra_data,
|
const uint8_t* extra_data,
|
||||||
size_t extra_data_size,
|
size_t extra_data_size,
|
||||||
bool is_encrypted);
|
bool is_encrypted);
|
||||||
|
|
||||||
|
@ -57,30 +57,31 @@ class AudioStreamInfo : public StreamInfo {
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
AudioCodec codec() const { return codec_; }
|
AudioCodec codec() const { return codec_; }
|
||||||
uint8 sample_bits() const { return sample_bits_; }
|
uint8_t sample_bits() const { return sample_bits_; }
|
||||||
uint8 sample_bytes() const { return sample_bits_ / 8; }
|
uint8_t sample_bytes() const { return sample_bits_ / 8; }
|
||||||
uint8 num_channels() const { return num_channels_; }
|
uint8_t num_channels() const { return num_channels_; }
|
||||||
uint32 sampling_frequency() const { return sampling_frequency_; }
|
uint32_t sampling_frequency() const { return sampling_frequency_; }
|
||||||
uint32 bytes_per_frame() const {
|
uint32_t bytes_per_frame() const {
|
||||||
return static_cast<uint32>(num_channels_) * sample_bits_ / 8;
|
return static_cast<uint32_t>(num_channels_) * sample_bits_ / 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_sampling_frequency(const uint32 sampling_frequency) {
|
void set_sampling_frequency(const uint32_t sampling_frequency) {
|
||||||
sampling_frequency_ = sampling_frequency;
|
sampling_frequency_ = sampling_frequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// @param audio_object_type is only used by AAC Codec, ignored otherwise.
|
/// @param audio_object_type is only used by AAC Codec, ignored otherwise.
|
||||||
/// @return The codec string.
|
/// @return The codec string.
|
||||||
static std::string GetCodecString(AudioCodec codec, uint8 audio_object_type);
|
static std::string GetCodecString(AudioCodec codec,
|
||||||
|
uint8_t audio_object_type);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual ~AudioStreamInfo();
|
virtual ~AudioStreamInfo();
|
||||||
|
|
||||||
AudioCodec codec_;
|
AudioCodec codec_;
|
||||||
uint8 sample_bits_;
|
uint8_t sample_bits_;
|
||||||
uint8 num_channels_;
|
uint8_t num_channels_;
|
||||||
uint32 sampling_frequency_;
|
uint32_t sampling_frequency_;
|
||||||
|
|
||||||
// Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler
|
// Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler
|
||||||
// generated copy constructor and assignment operator. Since the extra data is
|
// generated copy constructor and assignment operator. Since the extra data is
|
||||||
|
|
|
@ -10,45 +10,44 @@
|
||||||
namespace edash_packager {
|
namespace edash_packager {
|
||||||
namespace media {
|
namespace media {
|
||||||
|
|
||||||
AudioTimestampHelper::AudioTimestampHelper(uint32 timescale,
|
AudioTimestampHelper::AudioTimestampHelper(uint32_t timescale,
|
||||||
uint32 samples_per_second)
|
uint32_t samples_per_second)
|
||||||
: base_timestamp_(kNoTimestamp),
|
: base_timestamp_(kNoTimestamp), frame_count_(0) {
|
||||||
frame_count_(0) {
|
|
||||||
DCHECK_GT(samples_per_second, 0u);
|
DCHECK_GT(samples_per_second, 0u);
|
||||||
double fps = samples_per_second;
|
double fps = samples_per_second;
|
||||||
ticks_per_frame_ = timescale / fps;
|
ticks_per_frame_ = timescale / fps;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioTimestampHelper::SetBaseTimestamp(int64 base_timestamp) {
|
void AudioTimestampHelper::SetBaseTimestamp(int64_t base_timestamp) {
|
||||||
base_timestamp_ = base_timestamp;
|
base_timestamp_ = base_timestamp;
|
||||||
frame_count_ = 0;
|
frame_count_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 AudioTimestampHelper::base_timestamp() const {
|
int64_t AudioTimestampHelper::base_timestamp() const {
|
||||||
return base_timestamp_;
|
return base_timestamp_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioTimestampHelper::AddFrames(int64 frame_count) {
|
void AudioTimestampHelper::AddFrames(int64_t frame_count) {
|
||||||
DCHECK_GE(frame_count, 0);
|
DCHECK_GE(frame_count, 0);
|
||||||
DCHECK(base_timestamp_ != kNoTimestamp);
|
DCHECK(base_timestamp_ != kNoTimestamp);
|
||||||
frame_count_ += frame_count;
|
frame_count_ += frame_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 AudioTimestampHelper::GetTimestamp() const {
|
int64_t AudioTimestampHelper::GetTimestamp() const {
|
||||||
return ComputeTimestamp(frame_count_);
|
return ComputeTimestamp(frame_count_);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 AudioTimestampHelper::GetFrameDuration(int64 frame_count) const {
|
int64_t AudioTimestampHelper::GetFrameDuration(int64_t frame_count) const {
|
||||||
DCHECK_GE(frame_count, 0);
|
DCHECK_GE(frame_count, 0);
|
||||||
int64 end_timestamp = ComputeTimestamp(frame_count_ + frame_count);
|
int64_t end_timestamp = ComputeTimestamp(frame_count_ + frame_count);
|
||||||
return end_timestamp - GetTimestamp();
|
return end_timestamp - GetTimestamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 AudioTimestampHelper::GetFramesToTarget(int64 target) const {
|
int64_t AudioTimestampHelper::GetFramesToTarget(int64_t target) const {
|
||||||
DCHECK(base_timestamp_ != kNoTimestamp);
|
DCHECK(base_timestamp_ != kNoTimestamp);
|
||||||
DCHECK(target >= base_timestamp_);
|
DCHECK(target >= base_timestamp_);
|
||||||
|
|
||||||
int64 delta_in_ticks = (target - GetTimestamp());
|
int64_t delta_in_ticks = (target - GetTimestamp());
|
||||||
if (delta_in_ticks == 0)
|
if (delta_in_ticks == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -56,18 +55,16 @@ int64 AudioTimestampHelper::GetFramesToTarget(int64 target) const {
|
||||||
// created from |frame_count_| are computed relative to this base.
|
// created from |frame_count_| are computed relative to this base.
|
||||||
// This ensures that the time to frame computation here is the proper inverse
|
// This ensures that the time to frame computation here is the proper inverse
|
||||||
// of the frame to time computation in ComputeTimestamp().
|
// of the frame to time computation in ComputeTimestamp().
|
||||||
int64 delta_from_base = target - base_timestamp_;
|
int64_t delta_from_base = target - base_timestamp_;
|
||||||
|
|
||||||
// Compute frame count for the time delta. This computation rounds to
|
// Compute frame count for the time delta. This computation rounds to
|
||||||
// the nearest whole number of frames.
|
// the nearest whole number of frames.
|
||||||
double threshold = ticks_per_frame_ / 2;
|
double threshold = ticks_per_frame_ / 2;
|
||||||
int64 target_frame_count =
|
int64_t target_frame_count = (delta_from_base + threshold) / ticks_per_frame_;
|
||||||
(delta_from_base + threshold) / ticks_per_frame_;
|
|
||||||
return target_frame_count - frame_count_;
|
return target_frame_count - frame_count_;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 AudioTimestampHelper::ComputeTimestamp(
|
int64_t AudioTimestampHelper::ComputeTimestamp(int64_t frame_count) const {
|
||||||
int64 frame_count) const {
|
|
||||||
DCHECK_GE(frame_count, 0);
|
DCHECK_GE(frame_count, 0);
|
||||||
DCHECK(base_timestamp_ != kNoTimestamp);
|
DCHECK(base_timestamp_ != kNoTimestamp);
|
||||||
double frames_ticks = ticks_per_frame_ * frame_count;
|
double frames_ticks = ticks_per_frame_ * frame_count;
|
||||||
|
|
|
@ -27,42 +27,43 @@ namespace media {
|
||||||
// accumulated frames to reach a target timestamp.
|
// accumulated frames to reach a target timestamp.
|
||||||
class AudioTimestampHelper {
|
class AudioTimestampHelper {
|
||||||
public:
|
public:
|
||||||
explicit AudioTimestampHelper(uint32 timescale, uint32 samples_per_second);
|
explicit AudioTimestampHelper(uint32_t timescale,
|
||||||
|
uint32_t samples_per_second);
|
||||||
|
|
||||||
// Sets the base timestamp to |base_timestamp| and the sets count to 0.
|
// Sets the base timestamp to |base_timestamp| and the sets count to 0.
|
||||||
void SetBaseTimestamp(int64 base_timestamp);
|
void SetBaseTimestamp(int64_t base_timestamp);
|
||||||
|
|
||||||
int64 base_timestamp() const;
|
int64_t base_timestamp() const;
|
||||||
int64 frame_count() const { return frame_count_; }
|
int64_t frame_count() const { return frame_count_; }
|
||||||
|
|
||||||
// Adds |frame_count| to the frame counter.
|
// Adds |frame_count| to the frame counter.
|
||||||
// Note: SetBaseTimestamp() must be called with a value other than
|
// Note: SetBaseTimestamp() must be called with a value other than
|
||||||
// kNoTimestamp() before this method can be called.
|
// kNoTimestamp() before this method can be called.
|
||||||
void AddFrames(int64 frame_count);
|
void AddFrames(int64_t frame_count);
|
||||||
|
|
||||||
// Get the current timestamp. This value is computed from the base_timestamp()
|
// Get the current timestamp. This value is computed from the base_timestamp()
|
||||||
// and the number of sample frames that have been added so far.
|
// and the number of sample frames that have been added so far.
|
||||||
int64 GetTimestamp() const;
|
int64_t GetTimestamp() const;
|
||||||
|
|
||||||
// Gets the duration if |frame_count| frames were added to the current
|
// Gets the duration if |frame_count| frames were added to the current
|
||||||
// timestamp reported by GetTimestamp(). This method ensures that
|
// timestamp reported by GetTimestamp(). This method ensures that
|
||||||
// (GetTimestamp() + GetFrameDuration(n)) will equal the timestamp that
|
// (GetTimestamp() + GetFrameDuration(n)) will equal the timestamp that
|
||||||
// GetTimestamp() will return if AddFrames(n) is called.
|
// GetTimestamp() will return if AddFrames(n) is called.
|
||||||
int64 GetFrameDuration(int64 frame_count) const;
|
int64_t GetFrameDuration(int64_t frame_count) const;
|
||||||
|
|
||||||
// Returns the number of frames needed to reach the target timestamp.
|
// Returns the number of frames needed to reach the target timestamp.
|
||||||
// Note: |target| must be >= |base_timestamp_|.
|
// Note: |target| must be >= |base_timestamp_|.
|
||||||
int64 GetFramesToTarget(int64 target) const;
|
int64_t GetFramesToTarget(int64_t target) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int64 ComputeTimestamp(int64 frame_count) const;
|
int64_t ComputeTimestamp(int64_t frame_count) const;
|
||||||
|
|
||||||
double ticks_per_frame_;
|
double ticks_per_frame_;
|
||||||
|
|
||||||
int64 base_timestamp_;
|
int64_t base_timestamp_;
|
||||||
|
|
||||||
// Number of frames accumulated by AddFrames() calls.
|
// Number of frames accumulated by AddFrames() calls.
|
||||||
int64 frame_count_;
|
int64_t frame_count_;
|
||||||
|
|
||||||
DISALLOW_IMPLICIT_CONSTRUCTORS(AudioTimestampHelper);
|
DISALLOW_IMPLICIT_CONSTRUCTORS(AudioTimestampHelper);
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,8 +10,8 @@
|
||||||
namespace edash_packager {
|
namespace edash_packager {
|
||||||
namespace media {
|
namespace media {
|
||||||
|
|
||||||
static const uint32 kDefaultSampleRate = 44100;
|
static const uint32_t kDefaultSampleRate = 44100;
|
||||||
static const uint32 kTimescale = 1000000;
|
static const uint32_t kTimescale = 1000000;
|
||||||
|
|
||||||
class AudioTimestampHelperTest : public ::testing::Test {
|
class AudioTimestampHelperTest : public ::testing::Test {
|
||||||
public:
|
public:
|
||||||
|
@ -21,12 +21,12 @@ class AudioTimestampHelperTest : public ::testing::Test {
|
||||||
|
|
||||||
// Adds frames to the helper and returns the current timestamp in
|
// Adds frames to the helper and returns the current timestamp in
|
||||||
// microseconds.
|
// microseconds.
|
||||||
int64 AddFrames(int frames) {
|
int64_t AddFrames(int frames) {
|
||||||
helper_.AddFrames(frames);
|
helper_.AddFrames(frames);
|
||||||
return helper_.GetTimestamp();
|
return helper_.GetTimestamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 FramesToTarget(int target_in_microseconds) {
|
int64_t FramesToTarget(int target_in_microseconds) {
|
||||||
return helper_.GetFramesToTarget(target_in_microseconds);
|
return helper_.GetFramesToTarget(target_in_microseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ TEST_F(AudioTimestampHelperTest, Basic) {
|
||||||
|
|
||||||
// Verify that adding frames one frame at a time matches the timestamp
|
// Verify that adding frames one frame at a time matches the timestamp
|
||||||
// returned if the same number of frames are added all at once.
|
// returned if the same number of frames are added all at once.
|
||||||
int64 timestamp_1 = helper_.GetTimestamp();
|
int64_t timestamp_1 = helper_.GetTimestamp();
|
||||||
helper_.SetBaseTimestamp(kNoTimestamp);
|
helper_.SetBaseTimestamp(kNoTimestamp);
|
||||||
EXPECT_TRUE(kNoTimestamp == helper_.base_timestamp());
|
EXPECT_TRUE(kNoTimestamp == helper_.base_timestamp());
|
||||||
helper_.SetBaseTimestamp(0);
|
helper_.SetBaseTimestamp(0);
|
||||||
|
@ -75,14 +75,14 @@ TEST_F(AudioTimestampHelperTest, GetDuration) {
|
||||||
helper_.SetBaseTimestamp(100);
|
helper_.SetBaseTimestamp(100);
|
||||||
|
|
||||||
int frame_count = 5;
|
int frame_count = 5;
|
||||||
int64 expected_durations[] = { 113, 113, 114, 113, 113, 114 };
|
int64_t expected_durations[] = {113, 113, 114, 113, 113, 114};
|
||||||
for (size_t i = 0; i < arraysize(expected_durations); ++i) {
|
for (size_t i = 0; i < arraysize(expected_durations); ++i) {
|
||||||
int64 duration = helper_.GetFrameDuration(frame_count);
|
int64_t duration = helper_.GetFrameDuration(frame_count);
|
||||||
EXPECT_EQ(expected_durations[i], duration);
|
EXPECT_EQ(expected_durations[i], duration);
|
||||||
|
|
||||||
int64 timestamp_1 = helper_.GetTimestamp() + duration;
|
int64_t timestamp_1 = helper_.GetTimestamp() + duration;
|
||||||
helper_.AddFrames(frame_count);
|
helper_.AddFrames(frame_count);
|
||||||
int64 timestamp_2 = helper_.GetTimestamp();
|
int64_t timestamp_2 = helper_.GetTimestamp();
|
||||||
EXPECT_TRUE(timestamp_1 == timestamp_2);
|
EXPECT_TRUE(timestamp_1 == timestamp_2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
namespace edash_packager {
|
namespace edash_packager {
|
||||||
namespace media {
|
namespace media {
|
||||||
|
|
||||||
BitReader::BitReader(const uint8* data, off_t size)
|
BitReader::BitReader(const uint8_t* data, off_t size)
|
||||||
: data_(data), bytes_left_(size), num_remaining_bits_in_curr_byte_(0) {
|
: data_(data), bytes_left_(size), num_remaining_bits_in_curr_byte_(0) {
|
||||||
DCHECK(data_ != NULL && bytes_left_ > 0);
|
DCHECK(data_ != NULL && bytes_left_ > 0);
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ bool BitReader::SkipBits(int num_bits) {
|
||||||
// Less than 8 bits remaining to skip. Use ReadBitsInternal to verify
|
// Less than 8 bits remaining to skip. Use ReadBitsInternal to verify
|
||||||
// that the remaining bits we need exist, and adjust them as necessary
|
// that the remaining bits we need exist, and adjust them as necessary
|
||||||
// for subsequent operations.
|
// for subsequent operations.
|
||||||
uint64 not_needed;
|
uint64_t not_needed;
|
||||||
return ReadBitsInternal(num_bits, ¬_needed);
|
return ReadBitsInternal(num_bits, ¬_needed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ int BitReader::bits_available() const {
|
||||||
return 8 * bytes_left_ + num_remaining_bits_in_curr_byte_;
|
return 8 * bytes_left_ + num_remaining_bits_in_curr_byte_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BitReader::ReadBitsInternal(int num_bits, uint64* out) {
|
bool BitReader::ReadBitsInternal(int num_bits, uint64_t* out) {
|
||||||
DCHECK_LE(num_bits, 64);
|
DCHECK_LE(num_bits, 64);
|
||||||
|
|
||||||
*out = 0;
|
*out = 0;
|
||||||
|
|
|
@ -19,7 +19,7 @@ class BitReader {
|
||||||
/// Initialize the BitReader object to read a data buffer.
|
/// Initialize the BitReader object to read a data buffer.
|
||||||
/// @param data points to the beginning of the buffer.
|
/// @param data points to the beginning of the buffer.
|
||||||
/// @param size is the buffer size in bytes.
|
/// @param size is the buffer size in bytes.
|
||||||
BitReader(const uint8* data, off_t size);
|
BitReader(const uint8_t* data, off_t size);
|
||||||
~BitReader();
|
~BitReader();
|
||||||
|
|
||||||
/// Read a number of bits from stream.
|
/// Read a number of bits from stream.
|
||||||
|
@ -33,7 +33,7 @@ class BitReader {
|
||||||
/// operations will always return false unless @a num_bits is 0.
|
/// operations will always return false unless @a num_bits is 0.
|
||||||
template<typename T> bool ReadBits(int num_bits, T *out) {
|
template<typename T> bool ReadBits(int num_bits, T *out) {
|
||||||
DCHECK_LE(num_bits, static_cast<int>(sizeof(T) * 8));
|
DCHECK_LE(num_bits, static_cast<int>(sizeof(T) * 8));
|
||||||
uint64 temp;
|
uint64_t temp;
|
||||||
bool ret = ReadBitsInternal(num_bits, &temp);
|
bool ret = ReadBitsInternal(num_bits, &temp);
|
||||||
*out = static_cast<T>(temp);
|
*out = static_cast<T>(temp);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -52,7 +52,7 @@ class BitReader {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Help function used by ReadBits to avoid inlining the bit reading logic.
|
// Help function used by ReadBits to avoid inlining the bit reading logic.
|
||||||
bool ReadBitsInternal(int num_bits, uint64* out);
|
bool ReadBitsInternal(int num_bits, uint64_t* out);
|
||||||
|
|
||||||
// Advance to the next byte, loading it into curr_byte_.
|
// Advance to the next byte, loading it into curr_byte_.
|
||||||
// If the num_remaining_bits_in_curr_byte_ is 0 after this function returns,
|
// If the num_remaining_bits_in_curr_byte_ is 0 after this function returns,
|
||||||
|
@ -60,14 +60,14 @@ class BitReader {
|
||||||
void UpdateCurrByte();
|
void UpdateCurrByte();
|
||||||
|
|
||||||
// Pointer to the next unread (not in curr_byte_) byte in the stream.
|
// Pointer to the next unread (not in curr_byte_) byte in the stream.
|
||||||
const uint8* data_;
|
const uint8_t* data_;
|
||||||
|
|
||||||
// Bytes left in the stream (without the curr_byte_).
|
// Bytes left in the stream (without the curr_byte_).
|
||||||
off_t bytes_left_;
|
off_t bytes_left_;
|
||||||
|
|
||||||
// Contents of the current byte; first unread bit starting at position
|
// Contents of the current byte; first unread bit starting at position
|
||||||
// 8 - num_remaining_bits_in_curr_byte_ from MSB.
|
// 8 - num_remaining_bits_in_curr_byte_ from MSB.
|
||||||
uint8 curr_byte_;
|
uint8_t curr_byte_;
|
||||||
|
|
||||||
// Number of bits remaining in curr_byte_
|
// Number of bits remaining in curr_byte_
|
||||||
int num_remaining_bits_in_curr_byte_;
|
int num_remaining_bits_in_curr_byte_;
|
||||||
|
|
|
@ -10,10 +10,10 @@ namespace edash_packager {
|
||||||
namespace media {
|
namespace media {
|
||||||
|
|
||||||
TEST(BitReaderTest, NormalOperationTest) {
|
TEST(BitReaderTest, NormalOperationTest) {
|
||||||
uint8 value8;
|
uint8_t value8;
|
||||||
uint64 value64;
|
uint64_t value64;
|
||||||
// 0101 0101 1001 1001 repeats 4 times
|
// 0101 0101 1001 1001 repeats 4 times
|
||||||
uint8 buffer[] = {0x55, 0x99, 0x55, 0x99, 0x55, 0x99, 0x55, 0x99};
|
uint8_t buffer[] = {0x55, 0x99, 0x55, 0x99, 0x55, 0x99, 0x55, 0x99};
|
||||||
BitReader reader1(buffer, 6); // Initialize with 6 bytes only
|
BitReader reader1(buffer, 6); // Initialize with 6 bytes only
|
||||||
|
|
||||||
EXPECT_TRUE(reader1.ReadBits(1, &value8));
|
EXPECT_TRUE(reader1.ReadBits(1, &value8));
|
||||||
|
@ -36,8 +36,8 @@ TEST(BitReaderTest, NormalOperationTest) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BitReaderTest, ReadBeyondEndTest) {
|
TEST(BitReaderTest, ReadBeyondEndTest) {
|
||||||
uint8 value8;
|
uint8_t value8;
|
||||||
uint8 buffer[] = {0x12};
|
uint8_t buffer[] = {0x12};
|
||||||
BitReader reader1(buffer, sizeof(buffer));
|
BitReader reader1(buffer, sizeof(buffer));
|
||||||
|
|
||||||
EXPECT_TRUE(reader1.ReadBits(4, &value8));
|
EXPECT_TRUE(reader1.ReadBits(4, &value8));
|
||||||
|
@ -47,8 +47,8 @@ TEST(BitReaderTest, ReadBeyondEndTest) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(BitReaderTest, SkipBitsTest) {
|
TEST(BitReaderTest, SkipBitsTest) {
|
||||||
uint8 value8;
|
uint8_t value8;
|
||||||
uint8 buffer[] = { 0x0a, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
|
uint8_t buffer[] = {0x0a, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
|
||||||
BitReader reader1(buffer, sizeof(buffer));
|
BitReader reader1(buffer, sizeof(buffer));
|
||||||
|
|
||||||
EXPECT_TRUE(reader1.SkipBits(2));
|
EXPECT_TRUE(reader1.SkipBits(2));
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
namespace edash_packager {
|
namespace edash_packager {
|
||||||
namespace media {
|
namespace media {
|
||||||
|
|
||||||
bool BufferReader::Read1(uint8* v) {
|
bool BufferReader::Read1(uint8_t* v) {
|
||||||
DCHECK(v != NULL);
|
DCHECK(v != NULL);
|
||||||
if (!HasBytes(1))
|
if (!HasBytes(1))
|
||||||
return false;
|
return false;
|
||||||
|
@ -19,20 +19,32 @@ bool BufferReader::Read1(uint8* v) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BufferReader::Read2(uint16* v) { return Read(v); }
|
bool BufferReader::Read2(uint16_t* v) {
|
||||||
bool BufferReader::Read2s(int16* v) { return Read(v); }
|
return Read(v);
|
||||||
bool BufferReader::Read4(uint32* v) { return Read(v); }
|
}
|
||||||
bool BufferReader::Read4s(int32* v) { return Read(v); }
|
bool BufferReader::Read2s(int16_t* v) {
|
||||||
bool BufferReader::Read8(uint64* v) { return Read(v); }
|
return Read(v);
|
||||||
bool BufferReader::Read8s(int64* v) { return Read(v); }
|
}
|
||||||
bool BufferReader::ReadNBytesInto8(uint64* v, size_t num_bytes) {
|
bool BufferReader::Read4(uint32_t* v) {
|
||||||
|
return Read(v);
|
||||||
|
}
|
||||||
|
bool BufferReader::Read4s(int32_t* v) {
|
||||||
|
return Read(v);
|
||||||
|
}
|
||||||
|
bool BufferReader::Read8(uint64_t* v) {
|
||||||
|
return Read(v);
|
||||||
|
}
|
||||||
|
bool BufferReader::Read8s(int64_t* v) {
|
||||||
|
return Read(v);
|
||||||
|
}
|
||||||
|
bool BufferReader::ReadNBytesInto8(uint64_t* v, size_t num_bytes) {
|
||||||
return ReadNBytes(v, num_bytes);
|
return ReadNBytes(v, num_bytes);
|
||||||
}
|
}
|
||||||
bool BufferReader::ReadNBytesInto8s(int64* v, size_t num_bytes) {
|
bool BufferReader::ReadNBytesInto8s(int64_t* v, size_t num_bytes) {
|
||||||
return ReadNBytes(v, num_bytes);
|
return ReadNBytes(v, num_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BufferReader::ReadToVector(std::vector<uint8>* vec, size_t count) {
|
bool BufferReader::ReadToVector(std::vector<uint8_t>* vec, size_t count) {
|
||||||
DCHECK(vec != NULL);
|
DCHECK(vec != NULL);
|
||||||
if (!HasBytes(count))
|
if (!HasBytes(count))
|
||||||
return false;
|
return false;
|
||||||
|
@ -65,10 +77,10 @@ bool BufferReader::ReadNBytes(T* v, size_t num_bytes) {
|
||||||
// T is a signed type.
|
// T is a signed type.
|
||||||
const bool sign_extension_required =
|
const bool sign_extension_required =
|
||||||
num_bytes < sizeof(*v) && static_cast<T>(-1) < 0;
|
num_bytes < sizeof(*v) && static_cast<T>(-1) < 0;
|
||||||
// Perform sign extension by casting the byte value to int8, which will be
|
// Perform sign extension by casting the byte value to int8_t, which will be
|
||||||
// sign extended automatically when it is implicitly converted to T.
|
// sign extended automatically when it is implicitly converted to T.
|
||||||
T tmp =
|
T tmp = sign_extension_required ? static_cast<int8_t>(buf_[pos_++])
|
||||||
sign_extension_required ? static_cast<int8>(buf_[pos_++]) : buf_[pos_++];
|
: buf_[pos_++];
|
||||||
for (size_t i = 1; i < num_bytes; ++i) {
|
for (size_t i = 1; i < num_bytes; ++i) {
|
||||||
tmp <<= 8;
|
tmp <<= 8;
|
||||||
tmp |= buf_[pos_++];
|
tmp |= buf_[pos_++];
|
||||||
|
|
|
@ -20,7 +20,7 @@ namespace media {
|
||||||
class BufferReader {
|
class BufferReader {
|
||||||
public:
|
public:
|
||||||
/// Create a BufferReader from a raw buffer.
|
/// Create a BufferReader from a raw buffer.
|
||||||
BufferReader(const uint8* buf, size_t size)
|
BufferReader(const uint8_t* buf, size_t size)
|
||||||
: buf_(buf), size_(size), pos_(0) {}
|
: buf_(buf), size_(size), pos_(0) {}
|
||||||
~BufferReader() {}
|
~BufferReader() {}
|
||||||
|
|
||||||
|
@ -32,13 +32,13 @@ class BufferReader {
|
||||||
/// the stream pointer.
|
/// the stream pointer.
|
||||||
/// @return false if there are not enough bytes in the buffer.
|
/// @return false if there are not enough bytes in the buffer.
|
||||||
/// @{
|
/// @{
|
||||||
bool Read1(uint8* v) WARN_UNUSED_RESULT;
|
bool Read1(uint8_t* v) WARN_UNUSED_RESULT;
|
||||||
bool Read2(uint16* v) WARN_UNUSED_RESULT;
|
bool Read2(uint16_t* v) WARN_UNUSED_RESULT;
|
||||||
bool Read2s(int16* v) WARN_UNUSED_RESULT;
|
bool Read2s(int16_t* v) WARN_UNUSED_RESULT;
|
||||||
bool Read4(uint32* v) WARN_UNUSED_RESULT;
|
bool Read4(uint32_t* v) WARN_UNUSED_RESULT;
|
||||||
bool Read4s(int32* v) WARN_UNUSED_RESULT;
|
bool Read4s(int32_t* v) WARN_UNUSED_RESULT;
|
||||||
bool Read8(uint64* v) WARN_UNUSED_RESULT;
|
bool Read8(uint64_t* v) WARN_UNUSED_RESULT;
|
||||||
bool Read8s(int64* v) WARN_UNUSED_RESULT;
|
bool Read8s(int64_t* v) WARN_UNUSED_RESULT;
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// Read N-byte integer of the corresponding signedness and store it in the
|
/// Read N-byte integer of the corresponding signedness and store it in the
|
||||||
|
@ -46,17 +46,17 @@ class BufferReader {
|
||||||
/// @param num_bytes should not be larger than 8 bytes.
|
/// @param num_bytes should not be larger than 8 bytes.
|
||||||
/// @return false if there are not enough bytes in the buffer, true otherwise.
|
/// @return false if there are not enough bytes in the buffer, true otherwise.
|
||||||
/// @{
|
/// @{
|
||||||
bool ReadNBytesInto8(uint64* v, size_t num_bytes) WARN_UNUSED_RESULT;
|
bool ReadNBytesInto8(uint64_t* v, size_t num_bytes) WARN_UNUSED_RESULT;
|
||||||
bool ReadNBytesInto8s(int64* v, size_t num_bytes) WARN_UNUSED_RESULT;
|
bool ReadNBytesInto8s(int64_t* v, size_t num_bytes) WARN_UNUSED_RESULT;
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
bool ReadToVector(std::vector<uint8>* t, size_t count) WARN_UNUSED_RESULT;
|
bool ReadToVector(std::vector<uint8_t>* t, size_t count) WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
/// Advance the stream by this many bytes.
|
/// Advance the stream by this many bytes.
|
||||||
/// @return false if there are not enough bytes in the buffer, true otherwise.
|
/// @return false if there are not enough bytes in the buffer, true otherwise.
|
||||||
bool SkipBytes(size_t num_bytes) WARN_UNUSED_RESULT;
|
bool SkipBytes(size_t num_bytes) WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
const uint8* data() const { return buf_; }
|
const uint8_t* data() const { return buf_; }
|
||||||
size_t size() const { return size_; }
|
size_t size() const { return size_; }
|
||||||
void set_size(size_t size) { size_ = size; }
|
void set_size(size_t size) { size_ = size; }
|
||||||
size_t pos() const { return pos_; }
|
size_t pos() const { return pos_; }
|
||||||
|
@ -68,7 +68,7 @@ class BufferReader {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool ReadNBytes(T* t, size_t num_bytes) WARN_UNUSED_RESULT;
|
bool ReadNBytes(T* t, size_t num_bytes) WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
const uint8* buf_;
|
const uint8_t* buf_;
|
||||||
size_t size_;
|
size_t size_;
|
||||||
size_t pos_;
|
size_t pos_;
|
||||||
|
|
||||||
|
|
|
@ -21,26 +21,40 @@ BufferWriter::BufferWriter(size_t reserved_size_in_bytes) {
|
||||||
}
|
}
|
||||||
BufferWriter::~BufferWriter() {}
|
BufferWriter::~BufferWriter() {}
|
||||||
|
|
||||||
void BufferWriter::AppendInt(uint8 v) { buf_.push_back(v); }
|
void BufferWriter::AppendInt(uint8_t v) {
|
||||||
void BufferWriter::AppendInt(uint16 v) { AppendInternal(base::HostToNet16(v)); }
|
buf_.push_back(v);
|
||||||
void BufferWriter::AppendInt(uint32 v) { AppendInternal(base::HostToNet32(v)); }
|
}
|
||||||
void BufferWriter::AppendInt(uint64 v) { AppendInternal(base::HostToNet64(v)); }
|
void BufferWriter::AppendInt(uint16_t v) {
|
||||||
void BufferWriter::AppendInt(int16 v) { AppendInternal(base::HostToNet16(v)); }
|
AppendInternal(base::HostToNet16(v));
|
||||||
void BufferWriter::AppendInt(int32 v) { AppendInternal(base::HostToNet32(v)); }
|
}
|
||||||
void BufferWriter::AppendInt(int64 v) { AppendInternal(base::HostToNet64(v)); }
|
void BufferWriter::AppendInt(uint32_t v) {
|
||||||
|
AppendInternal(base::HostToNet32(v));
|
||||||
|
}
|
||||||
|
void BufferWriter::AppendInt(uint64_t v) {
|
||||||
|
AppendInternal(base::HostToNet64(v));
|
||||||
|
}
|
||||||
|
void BufferWriter::AppendInt(int16_t v) {
|
||||||
|
AppendInternal(base::HostToNet16(v));
|
||||||
|
}
|
||||||
|
void BufferWriter::AppendInt(int32_t v) {
|
||||||
|
AppendInternal(base::HostToNet32(v));
|
||||||
|
}
|
||||||
|
void BufferWriter::AppendInt(int64_t v) {
|
||||||
|
AppendInternal(base::HostToNet64(v));
|
||||||
|
}
|
||||||
|
|
||||||
void BufferWriter::AppendNBytes(uint64 v, size_t num_bytes) {
|
void BufferWriter::AppendNBytes(uint64_t v, size_t num_bytes) {
|
||||||
DCHECK_GE(sizeof(v), num_bytes);
|
DCHECK_GE(sizeof(v), num_bytes);
|
||||||
v = base::HostToNet64(v);
|
v = base::HostToNet64(v);
|
||||||
const uint8* data = reinterpret_cast<uint8*>(&v);
|
const uint8_t* data = reinterpret_cast<uint8_t*>(&v);
|
||||||
AppendArray(&data[sizeof(v) - num_bytes], num_bytes);
|
AppendArray(&data[sizeof(v) - num_bytes], num_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BufferWriter::AppendVector(const std::vector<uint8>& v) {
|
void BufferWriter::AppendVector(const std::vector<uint8_t>& v) {
|
||||||
buf_.insert(buf_.end(), v.begin(), v.end());
|
buf_.insert(buf_.end(), v.begin(), v.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void BufferWriter::AppendArray(const uint8* buf, size_t size) {
|
void BufferWriter::AppendArray(const uint8_t* buf, size_t size) {
|
||||||
buf_.insert(buf_.end(), buf, buf + size);
|
buf_.insert(buf_.end(), buf, buf + size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,9 +66,9 @@ Status BufferWriter::WriteToFile(File* file) {
|
||||||
DCHECK(file);
|
DCHECK(file);
|
||||||
|
|
||||||
size_t remaining_size = buf_.size();
|
size_t remaining_size = buf_.size();
|
||||||
const uint8* buf = &buf_[0];
|
const uint8_t* buf = &buf_[0];
|
||||||
while (remaining_size > 0) {
|
while (remaining_size > 0) {
|
||||||
int64 size_written = file->Write(buf, remaining_size);
|
int64_t size_written = file->Write(buf, remaining_size);
|
||||||
if (size_written <= 0) {
|
if (size_written <= 0) {
|
||||||
return Status(error::FILE_FAILURE,
|
return Status(error::FILE_FAILURE,
|
||||||
"Fail to write to file in BufferWriter");
|
"Fail to write to file in BufferWriter");
|
||||||
|
@ -68,7 +82,7 @@ Status BufferWriter::WriteToFile(File* file) {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void BufferWriter::AppendInternal(T v) {
|
void BufferWriter::AppendInternal(T v) {
|
||||||
AppendArray(reinterpret_cast<uint8*>(&v), sizeof(T));
|
AppendArray(reinterpret_cast<uint8_t*>(&v), sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace media
|
} // namespace media
|
||||||
|
|
|
@ -32,31 +32,31 @@ class BufferWriter {
|
||||||
/// These convenience functions append the integers (in network byte order,
|
/// These convenience functions append the integers (in network byte order,
|
||||||
/// i.e. big endian) of various size and signedness to the end of the buffer.
|
/// i.e. big endian) of various size and signedness to the end of the buffer.
|
||||||
/// @{
|
/// @{
|
||||||
void AppendInt(uint8 v);
|
void AppendInt(uint8_t v);
|
||||||
void AppendInt(uint16 v);
|
void AppendInt(uint16_t v);
|
||||||
void AppendInt(uint32 v);
|
void AppendInt(uint32_t v);
|
||||||
void AppendInt(uint64 v);
|
void AppendInt(uint64_t v);
|
||||||
void AppendInt(int16 v);
|
void AppendInt(int16_t v);
|
||||||
void AppendInt(int32 v);
|
void AppendInt(int32_t v);
|
||||||
void AppendInt(int64 v);
|
void AppendInt(int64_t v);
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
/// Append the least significant @a num_bytes of @a v to buffer.
|
/// Append the least significant @a num_bytes of @a v to buffer.
|
||||||
/// @param num_bytes should not be larger than sizeof(@a v), i.e. 8 on a
|
/// @param num_bytes should not be larger than sizeof(@a v), i.e. 8 on a
|
||||||
/// 64-bit system.
|
/// 64-bit system.
|
||||||
void AppendNBytes(uint64 v, size_t num_bytes);
|
void AppendNBytes(uint64_t v, size_t num_bytes);
|
||||||
|
|
||||||
void AppendVector(const std::vector<uint8>& v);
|
void AppendVector(const std::vector<uint8_t>& v);
|
||||||
void AppendArray(const uint8* buf, size_t size);
|
void AppendArray(const uint8_t* buf, size_t size);
|
||||||
void AppendBuffer(const BufferWriter& buffer);
|
void AppendBuffer(const BufferWriter& buffer);
|
||||||
|
|
||||||
void Swap(BufferWriter* buffer) { buf_.swap(buffer->buf_); }
|
void Swap(BufferWriter* buffer) { buf_.swap(buffer->buf_); }
|
||||||
void SwapBuffer(std::vector<uint8>* buffer) { buf_.swap(*buffer); }
|
void SwapBuffer(std::vector<uint8_t>* buffer) { buf_.swap(*buffer); }
|
||||||
|
|
||||||
void Clear() { buf_.clear(); }
|
void Clear() { buf_.clear(); }
|
||||||
size_t Size() const { return buf_.size(); }
|
size_t Size() const { return buf_.size(); }
|
||||||
/// @return Underlying buffer. Behavior is undefined if the buffer size is 0.
|
/// @return Underlying buffer. Behavior is undefined if the buffer size is 0.
|
||||||
const uint8* Buffer() const { return vector_as_array(&buf_); }
|
const uint8_t* Buffer() const { return vector_as_array(&buf_); }
|
||||||
|
|
||||||
/// Write the buffer to file. The internal buffer will be cleared after
|
/// Write the buffer to file. The internal buffer will be cleared after
|
||||||
/// writing.
|
/// writing.
|
||||||
|
@ -69,7 +69,7 @@ class BufferWriter {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void AppendInternal(T v);
|
void AppendInternal(T v);
|
||||||
|
|
||||||
std::vector<uint8> buf_;
|
std::vector<uint8_t> buf_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(BufferWriter);
|
DISALLOW_COPY_AND_ASSIGN(BufferWriter);
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,20 +16,20 @@ namespace {
|
||||||
const int kReservedBufferCapacity = 1000;
|
const int kReservedBufferCapacity = 1000;
|
||||||
// Min values for various integers of different size. Min values for signed
|
// Min values for various integers of different size. Min values for signed
|
||||||
// integers are already defined in //base/basictypes.h.
|
// integers are already defined in //base/basictypes.h.
|
||||||
const uint8 kuint8min = 0;
|
const uint8_t kuint8min = 0;
|
||||||
const uint16 kuint16min = 0;
|
const uint16_t kuint16min = 0;
|
||||||
const uint32 kuint32min = 0;
|
const uint32_t kuint32min = 0;
|
||||||
const uint64 kuint64min = 0;
|
const uint64_t kuint64min = 0;
|
||||||
// Max values for various integers are already defined in //base/basictypes.h.
|
// Max values for various integers are already defined in //base/basictypes.h.
|
||||||
// Other integer values.
|
// Other integer values.
|
||||||
const uint8 kuint8 = 10;
|
const uint8_t kuint8 = 10;
|
||||||
const uint16 kuint16 = 1000;
|
const uint16_t kuint16 = 1000;
|
||||||
const int16 kint16 = -1000;
|
const int16_t kint16 = -1000;
|
||||||
const uint32 kuint32 = 1000000;
|
const uint32_t kuint32 = 1000000;
|
||||||
const int32 kint32 = -1000000;
|
const int32_t kint32 = -1000000;
|
||||||
const uint64 kuint64 = 10000000000ULL;
|
const uint64_t kuint64 = 10000000000ULL;
|
||||||
const int64 kint64 = -10000000000LL;
|
const int64_t kint64 = -10000000000LL;
|
||||||
const uint8 kuint8Array[] = {10, 1, 100, 5, 3, 60};
|
const uint8_t kuint8Array[] = {10, 1, 100, 5, 3, 60};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace edash_packager {
|
namespace edash_packager {
|
||||||
|
@ -43,13 +43,13 @@ class BufferWriterTest : public testing::Test {
|
||||||
reader_.reset(new BufferReader(writer_->Buffer(), writer_->Size()));
|
reader_.reset(new BufferReader(writer_->Buffer(), writer_->Size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ReadInt(uint8* v) { return reader_->Read1(v); }
|
bool ReadInt(uint8_t* v) { return reader_->Read1(v); }
|
||||||
bool ReadInt(uint16* v) { return reader_->Read2(v); }
|
bool ReadInt(uint16_t* v) { return reader_->Read2(v); }
|
||||||
bool ReadInt(int16* v) { return reader_->Read2s(v); }
|
bool ReadInt(int16_t* v) { return reader_->Read2s(v); }
|
||||||
bool ReadInt(uint32* v) { return reader_->Read4(v); }
|
bool ReadInt(uint32_t* v) { return reader_->Read4(v); }
|
||||||
bool ReadInt(int32* v) { return reader_->Read4s(v); }
|
bool ReadInt(int32_t* v) { return reader_->Read4s(v); }
|
||||||
bool ReadInt(uint64* v) { return reader_->Read8(v); }
|
bool ReadInt(uint64_t* v) { return reader_->Read8(v); }
|
||||||
bool ReadInt(int64* v) { return reader_->Read8s(v); }
|
bool ReadInt(int64_t* v) { return reader_->Read8s(v); }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void ReadAndExpect(T expectation) {
|
void ReadAndExpect(T expectation) {
|
||||||
|
@ -89,26 +89,26 @@ TEST_F(BufferWriterTest, Append8s) { Verify(kint64min, kint64max, kint64); }
|
||||||
|
|
||||||
TEST_F(BufferWriterTest, AppendNBytes) {
|
TEST_F(BufferWriterTest, AppendNBytes) {
|
||||||
// Write the least significant four bytes and verify the result.
|
// Write the least significant four bytes and verify the result.
|
||||||
writer_->AppendNBytes(kuint64, sizeof(uint32));
|
writer_->AppendNBytes(kuint64, sizeof(uint32_t));
|
||||||
ASSERT_EQ(sizeof(uint32), writer_->Size());
|
ASSERT_EQ(sizeof(uint32_t), writer_->Size());
|
||||||
|
|
||||||
CreateReader();
|
CreateReader();
|
||||||
ReadAndExpect(static_cast<uint32>(kuint64 & 0xFFFFFFFF));
|
ReadAndExpect(static_cast<uint32_t>(kuint64 & 0xFFFFFFFF));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BufferWriterTest, AppendEmptyVector) {
|
TEST_F(BufferWriterTest, AppendEmptyVector) {
|
||||||
std::vector<uint8> v;
|
std::vector<uint8_t> v;
|
||||||
writer_->AppendVector(v);
|
writer_->AppendVector(v);
|
||||||
ASSERT_EQ(0u, writer_->Size());
|
ASSERT_EQ(0u, writer_->Size());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BufferWriterTest, AppendVector) {
|
TEST_F(BufferWriterTest, AppendVector) {
|
||||||
std::vector<uint8> v(kuint8Array, kuint8Array + sizeof(kuint8Array));
|
std::vector<uint8_t> v(kuint8Array, kuint8Array + sizeof(kuint8Array));
|
||||||
writer_->AppendVector(v);
|
writer_->AppendVector(v);
|
||||||
ASSERT_EQ(sizeof(kuint8Array), writer_->Size());
|
ASSERT_EQ(sizeof(kuint8Array), writer_->Size());
|
||||||
|
|
||||||
CreateReader();
|
CreateReader();
|
||||||
std::vector<uint8> data_read;
|
std::vector<uint8_t> data_read;
|
||||||
ASSERT_TRUE(reader_->ReadToVector(&data_read, sizeof(kuint8Array)));
|
ASSERT_TRUE(reader_->ReadToVector(&data_read, sizeof(kuint8Array)));
|
||||||
ASSERT_EQ(v, data_read);
|
ASSERT_EQ(v, data_read);
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,7 @@ TEST_F(BufferWriterTest, AppendArray) {
|
||||||
ASSERT_EQ(sizeof(kuint8Array), writer_->Size());
|
ASSERT_EQ(sizeof(kuint8Array), writer_->Size());
|
||||||
|
|
||||||
CreateReader();
|
CreateReader();
|
||||||
std::vector<uint8> data_read;
|
std::vector<uint8_t> data_read;
|
||||||
ASSERT_TRUE(reader_->ReadToVector(&data_read, sizeof(kuint8Array)));
|
ASSERT_TRUE(reader_->ReadToVector(&data_read, sizeof(kuint8Array)));
|
||||||
for (size_t i = 0; i < sizeof(kuint8Array); ++i)
|
for (size_t i = 0; i < sizeof(kuint8Array); ++i)
|
||||||
EXPECT_EQ(kuint8Array[i], data_read[i]);
|
EXPECT_EQ(kuint8Array[i], data_read[i]);
|
||||||
|
@ -177,7 +177,7 @@ TEST_F(BufferWriterTest, WriteToFile) {
|
||||||
// Read the file and verify.
|
// Read the file and verify.
|
||||||
File* const input_file = File::Open(path.value().c_str(), "r");
|
File* const input_file = File::Open(path.value().c_str(), "r");
|
||||||
ASSERT_TRUE(input_file != NULL);
|
ASSERT_TRUE(input_file != NULL);
|
||||||
std::vector<uint8> data_read(sizeof(kuint8Array), 0);
|
std::vector<uint8_t> data_read(sizeof(kuint8Array), 0);
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(
|
||||||
sizeof(kuint8Array),
|
sizeof(kuint8Array),
|
||||||
static_cast<size_t>(input_file->Read(&data_read[0], data_read.size())));
|
static_cast<size_t>(input_file->Read(&data_read[0], data_read.size())));
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace media {
|
||||||
enum { kDefaultQueueSize = 1024 };
|
enum { kDefaultQueueSize = 1024 };
|
||||||
|
|
||||||
ByteQueue::ByteQueue()
|
ByteQueue::ByteQueue()
|
||||||
: buffer_(new uint8[kDefaultQueueSize]),
|
: buffer_(new uint8_t[kDefaultQueueSize]),
|
||||||
size_(kDefaultQueueSize),
|
size_(kDefaultQueueSize),
|
||||||
offset_(0),
|
offset_(0),
|
||||||
used_(0) {
|
used_(0) {
|
||||||
|
@ -26,7 +26,7 @@ void ByteQueue::Reset() {
|
||||||
used_ = 0;
|
used_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ByteQueue::Push(const uint8* data, int size) {
|
void ByteQueue::Push(const uint8_t* data, int size) {
|
||||||
DCHECK(data);
|
DCHECK(data);
|
||||||
DCHECK_GT(size, 0);
|
DCHECK_GT(size, 0);
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ void ByteQueue::Push(const uint8* data, int size) {
|
||||||
// Sanity check to make sure we didn't overflow.
|
// Sanity check to make sure we didn't overflow.
|
||||||
CHECK_GT(new_size, size_);
|
CHECK_GT(new_size, size_);
|
||||||
|
|
||||||
scoped_ptr<uint8[]> new_buffer(new uint8[new_size]);
|
scoped_ptr<uint8_t[]> new_buffer(new uint8_t[new_size]);
|
||||||
|
|
||||||
// Copy the data from the old buffer to the start of the new one.
|
// Copy the data from the old buffer to the start of the new one.
|
||||||
if (used_ > 0)
|
if (used_ > 0)
|
||||||
|
@ -60,7 +60,7 @@ void ByteQueue::Push(const uint8* data, int size) {
|
||||||
used_ += size;
|
used_ += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ByteQueue::Peek(const uint8** data, int* size) const {
|
void ByteQueue::Peek(const uint8_t** data, int* size) const {
|
||||||
DCHECK(data);
|
DCHECK(data);
|
||||||
DCHECK(size);
|
DCHECK(size);
|
||||||
*data = front();
|
*data = front();
|
||||||
|
@ -80,7 +80,9 @@ void ByteQueue::Pop(int count) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8* ByteQueue::front() const { return buffer_.get() + offset_; }
|
uint8_t* ByteQueue::front() const {
|
||||||
|
return buffer_.get() + offset_;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace media
|
} // namespace media
|
||||||
} // namespace edash_packager
|
} // namespace edash_packager
|
||||||
|
|
|
@ -25,11 +25,11 @@ class ByteQueue {
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
/// Append new bytes to the end of the queue.
|
/// Append new bytes to the end of the queue.
|
||||||
void Push(const uint8* data, int size);
|
void Push(const uint8_t* data, int size);
|
||||||
|
|
||||||
/// Get a pointer to the front of the queue and the queue size.
|
/// Get a pointer to the front of the queue and the queue size.
|
||||||
/// These values are only valid until the next Push() or Pop() call.
|
/// These values are only valid until the next Push() or Pop() call.
|
||||||
void Peek(const uint8** data, int* size) const;
|
void Peek(const uint8_t** data, int* size) const;
|
||||||
|
|
||||||
/// Remove a number of bytes from the front of the queue.
|
/// Remove a number of bytes from the front of the queue.
|
||||||
/// @param count specifies number of bytes to be popped.
|
/// @param count specifies number of bytes to be popped.
|
||||||
|
@ -37,9 +37,9 @@ class ByteQueue {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Returns a pointer to the front of the queue.
|
// Returns a pointer to the front of the queue.
|
||||||
uint8* front() const;
|
uint8_t* front() const;
|
||||||
|
|
||||||
scoped_ptr<uint8[]> buffer_;
|
scoped_ptr<uint8_t[]> buffer_;
|
||||||
|
|
||||||
// Size of |buffer_|.
|
// Size of |buffer_|.
|
||||||
size_t size_;
|
size_t size_;
|
||||||
|
|
|
@ -14,11 +14,10 @@
|
||||||
namespace edash_packager {
|
namespace edash_packager {
|
||||||
namespace media {
|
namespace media {
|
||||||
|
|
||||||
#define TAG(a, b, c, d) \
|
#define TAG(a, b, c, d) \
|
||||||
((static_cast<uint32>(static_cast<uint8>(a)) << 24) | \
|
((static_cast<uint32_t>(static_cast<uint8_t>(a)) << 24) | \
|
||||||
(static_cast<uint8>(b) << 16) | \
|
(static_cast<uint8_t>(b) << 16) | (static_cast<uint8_t>(c) << 8) | \
|
||||||
(static_cast<uint8>(c) << 8) | \
|
(static_cast<uint8_t>(d)))
|
||||||
(static_cast<uint8>(d)))
|
|
||||||
|
|
||||||
#define RCHECK(x) \
|
#define RCHECK(x) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -29,28 +28,28 @@ namespace media {
|
||||||
#define UTF8_BYTE_ORDER_MARK "\xef\xbb\xbf"
|
#define UTF8_BYTE_ORDER_MARK "\xef\xbb\xbf"
|
||||||
|
|
||||||
// Helper function to read 2 bytes (16 bits, big endian) from a buffer.
|
// Helper function to read 2 bytes (16 bits, big endian) from a buffer.
|
||||||
static int Read16(const uint8* p) {
|
static int Read16(const uint8_t* p) {
|
||||||
return p[0] << 8 | p[1];
|
return p[0] << 8 | p[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to read 3 bytes (24 bits, big endian) from a buffer.
|
// Helper function to read 3 bytes (24 bits, big endian) from a buffer.
|
||||||
static uint32 Read24(const uint8* p) {
|
static uint32_t Read24(const uint8_t* p) {
|
||||||
return p[0] << 16 | p[1] << 8 | p[2];
|
return p[0] << 16 | p[1] << 8 | p[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to read 4 bytes (32 bits, big endian) from a buffer.
|
// Helper function to read 4 bytes (32 bits, big endian) from a buffer.
|
||||||
static uint32 Read32(const uint8* p) {
|
static uint32_t Read32(const uint8_t* p) {
|
||||||
return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
|
return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to read 4 bytes (32 bits, little endian) from a buffer.
|
// Helper function to read 4 bytes (32 bits, little endian) from a buffer.
|
||||||
static uint32 Read32LE(const uint8* p) {
|
static uint32_t Read32LE(const uint8_t* p) {
|
||||||
return p[3] << 24 | p[2] << 16 | p[1] << 8 | p[0];
|
return p[3] << 24 | p[2] << 16 | p[1] << 8 | p[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to do buffer comparisons with a string without going off the
|
// Helper function to do buffer comparisons with a string without going off the
|
||||||
// end of the buffer.
|
// end of the buffer.
|
||||||
static bool StartsWith(const uint8* buffer,
|
static bool StartsWith(const uint8_t* buffer,
|
||||||
size_t buffer_size,
|
size_t buffer_size,
|
||||||
const char* prefix) {
|
const char* prefix) {
|
||||||
size_t prefix_size = strlen(prefix);
|
size_t prefix_size = strlen(prefix);
|
||||||
|
@ -60,19 +59,19 @@ static bool StartsWith(const uint8* buffer,
|
||||||
|
|
||||||
// Helper function to do buffer comparisons with another buffer (to allow for
|
// Helper function to do buffer comparisons with another buffer (to allow for
|
||||||
// embedded \0 in the comparison) without going off the end of the buffer.
|
// embedded \0 in the comparison) without going off the end of the buffer.
|
||||||
static bool StartsWith(const uint8* buffer,
|
static bool StartsWith(const uint8_t* buffer,
|
||||||
size_t buffer_size,
|
size_t buffer_size,
|
||||||
const uint8* prefix,
|
const uint8_t* prefix,
|
||||||
size_t prefix_size) {
|
size_t prefix_size) {
|
||||||
return (prefix_size <= buffer_size &&
|
return (prefix_size <= buffer_size &&
|
||||||
memcmp(buffer, prefix, prefix_size) == 0);
|
memcmp(buffer, prefix, prefix_size) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to read up to 64 bits from a bit stream.
|
// Helper function to read up to 64 bits from a bit stream.
|
||||||
static uint64 ReadBits(BitReader* reader, int num_bits) {
|
static uint64_t ReadBits(BitReader* reader, int num_bits) {
|
||||||
DCHECK_GE(reader->bits_available(), num_bits);
|
DCHECK_GE(reader->bits_available(), num_bits);
|
||||||
DCHECK((num_bits > 0) && (num_bits <= 64));
|
DCHECK((num_bits > 0) && (num_bits <= 64));
|
||||||
uint64 value;
|
uint64_t value;
|
||||||
reader->ReadBits(num_bits, &value);
|
reader->ReadBits(num_bits, &value);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -92,7 +91,7 @@ const int kAc3FrameSizeTable[38][3] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Checks for an ADTS AAC container.
|
// Checks for an ADTS AAC container.
|
||||||
static bool CheckAac(const uint8* buffer, int buffer_size) {
|
static bool CheckAac(const uint8_t* buffer, int buffer_size) {
|
||||||
// Audio Data Transport Stream (ADTS) header is 7 or 9 bytes
|
// Audio Data Transport Stream (ADTS) header is 7 or 9 bytes
|
||||||
// (from http://wiki.multimedia.cx/index.php?title=ADTS)
|
// (from http://wiki.multimedia.cx/index.php?title=ADTS)
|
||||||
RCHECK(buffer_size > 6);
|
RCHECK(buffer_size > 6);
|
||||||
|
@ -128,10 +127,10 @@ static bool CheckAac(const uint8* buffer, int buffer_size) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint16 kAc3SyncWord = 0x0b77;
|
const uint16_t kAc3SyncWord = 0x0b77;
|
||||||
|
|
||||||
// Checks for an AC3 container.
|
// Checks for an AC3 container.
|
||||||
static bool CheckAc3(const uint8* buffer, int buffer_size) {
|
static bool CheckAc3(const uint8_t* buffer, int buffer_size) {
|
||||||
// Reference: ATSC Standard: Digital Audio Compression (AC-3, E-AC-3)
|
// Reference: ATSC Standard: Digital Audio Compression (AC-3, E-AC-3)
|
||||||
// Doc. A/52:2012
|
// Doc. A/52:2012
|
||||||
// (http://www.atsc.org/cms/standards/A52-2012(12-17).pdf)
|
// (http://www.atsc.org/cms/standards/A52-2012(12-17).pdf)
|
||||||
|
@ -166,7 +165,7 @@ static bool CheckAc3(const uint8* buffer, int buffer_size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks for an EAC3 container (very similar to AC3)
|
// Checks for an EAC3 container (very similar to AC3)
|
||||||
static bool CheckEac3(const uint8* buffer, int buffer_size) {
|
static bool CheckEac3(const uint8_t* buffer, int buffer_size) {
|
||||||
// Reference: ATSC Standard: Digital Audio Compression (AC-3, E-AC-3)
|
// Reference: ATSC Standard: Digital Audio Compression (AC-3, E-AC-3)
|
||||||
// Doc. A/52:2012
|
// Doc. A/52:2012
|
||||||
// (http://www.atsc.org/cms/standards/A52-2012(12-17).pdf)
|
// (http://www.atsc.org/cms/standards/A52-2012(12-17).pdf)
|
||||||
|
@ -204,7 +203,7 @@ static bool CheckEac3(const uint8* buffer, int buffer_size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Additional checks for a BINK container.
|
// Additional checks for a BINK container.
|
||||||
static bool CheckBink(const uint8* buffer, int buffer_size) {
|
static bool CheckBink(const uint8_t* buffer, int buffer_size) {
|
||||||
// Reference: http://wiki.multimedia.cx/index.php?title=Bink_Container
|
// Reference: http://wiki.multimedia.cx/index.php?title=Bink_Container
|
||||||
RCHECK(buffer_size >= 44);
|
RCHECK(buffer_size >= 44);
|
||||||
|
|
||||||
|
@ -230,7 +229,7 @@ static bool CheckBink(const uint8* buffer, int buffer_size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Additional checks for a CAF container.
|
// Additional checks for a CAF container.
|
||||||
static bool CheckCaf(const uint8* buffer, int buffer_size) {
|
static bool CheckCaf(const uint8_t* buffer, int buffer_size) {
|
||||||
// Reference: Apple Core Audio Format Specification 1.0
|
// Reference: Apple Core Audio Format Specification 1.0
|
||||||
// (https://developer.apple.com/library/mac/#documentation/MusicAudio/Reference/CAFSpec/CAF_spec/CAF_spec.html)
|
// (https://developer.apple.com/library/mac/#documentation/MusicAudio/Reference/CAFSpec/CAF_spec/CAF_spec.html)
|
||||||
RCHECK(buffer_size >= 52);
|
RCHECK(buffer_size >= 52);
|
||||||
|
@ -271,7 +270,7 @@ static bool kExtAudioIdValid[8] = { true, false, true, false, false, false,
|
||||||
true, false };
|
true, false };
|
||||||
|
|
||||||
// Additional checks for a DTS container.
|
// Additional checks for a DTS container.
|
||||||
static bool CheckDts(const uint8* buffer, int buffer_size) {
|
static bool CheckDts(const uint8_t* buffer, int buffer_size) {
|
||||||
// Reference: ETSI TS 102 114 V1.3.1 (2011-08)
|
// Reference: ETSI TS 102 114 V1.3.1 (2011-08)
|
||||||
// (http://www.etsi.org/deliver/etsi_ts/102100_102199/102114/01.03.01_60/ts_102114v010301p.pdf)
|
// (http://www.etsi.org/deliver/etsi_ts/102100_102199/102114/01.03.01_60/ts_102114v010301p.pdf)
|
||||||
RCHECK(buffer_size > 11);
|
RCHECK(buffer_size > 11);
|
||||||
|
@ -326,7 +325,7 @@ static bool CheckDts(const uint8* buffer, int buffer_size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks for a DV container.
|
// Checks for a DV container.
|
||||||
static bool CheckDV(const uint8* buffer, int buffer_size) {
|
static bool CheckDV(const uint8_t* buffer, int buffer_size) {
|
||||||
// Reference: SMPTE 314M (Annex A has differences with IEC 61834).
|
// Reference: SMPTE 314M (Annex A has differences with IEC 61834).
|
||||||
// (http://standards.smpte.org/content/978-1-61482-454-1/st-314-2005/SEC1.body.pdf)
|
// (http://standards.smpte.org/content/978-1-61482-454-1/st-314-2005/SEC1.body.pdf)
|
||||||
RCHECK(buffer_size > 11);
|
RCHECK(buffer_size > 11);
|
||||||
|
@ -389,7 +388,7 @@ static bool CheckDV(const uint8* buffer, int buffer_size) {
|
||||||
|
|
||||||
|
|
||||||
// Checks for a GSM container.
|
// Checks for a GSM container.
|
||||||
static bool CheckGsm(const uint8* buffer, int buffer_size) {
|
static bool CheckGsm(const uint8_t* buffer, int buffer_size) {
|
||||||
// Reference: ETSI EN 300 961 V8.1.1
|
// Reference: ETSI EN 300 961 V8.1.1
|
||||||
// (http://www.etsi.org/deliver/etsi_en/300900_300999/300961/08.01.01_60/en_300961v080101p.pdf)
|
// (http://www.etsi.org/deliver/etsi_en/300900_300999/300961/08.01.01_60/en_300961v080101p.pdf)
|
||||||
// also http://tools.ietf.org/html/rfc3551#page-24
|
// also http://tools.ietf.org/html/rfc3551#page-24
|
||||||
|
@ -410,20 +409,20 @@ static bool CheckGsm(const uint8* buffer, int buffer_size) {
|
||||||
// number of bytes that must remain in the buffer when |start_code| is found.
|
// number of bytes that must remain in the buffer when |start_code| is found.
|
||||||
// Returns true if start_code found (and enough space in the buffer after it),
|
// Returns true if start_code found (and enough space in the buffer after it),
|
||||||
// false otherwise.
|
// false otherwise.
|
||||||
static bool AdvanceToStartCode(const uint8* buffer,
|
static bool AdvanceToStartCode(const uint8_t* buffer,
|
||||||
int buffer_size,
|
int buffer_size,
|
||||||
int* offset,
|
int* offset,
|
||||||
int bytes_needed,
|
int bytes_needed,
|
||||||
int num_bits,
|
int num_bits,
|
||||||
uint32 start_code) {
|
uint32_t start_code) {
|
||||||
DCHECK_GE(bytes_needed, 3);
|
DCHECK_GE(bytes_needed, 3);
|
||||||
DCHECK_LE(num_bits, 24); // Only supports up to 24 bits.
|
DCHECK_LE(num_bits, 24); // Only supports up to 24 bits.
|
||||||
|
|
||||||
// Create a mask to isolate |num_bits| bits, once shifted over.
|
// Create a mask to isolate |num_bits| bits, once shifted over.
|
||||||
uint32 bits_to_shift = 24 - num_bits;
|
uint32_t bits_to_shift = 24 - num_bits;
|
||||||
uint32 mask = (1 << num_bits) - 1;
|
uint32_t mask = (1 << num_bits) - 1;
|
||||||
while (*offset + bytes_needed < buffer_size) {
|
while (*offset + bytes_needed < buffer_size) {
|
||||||
uint32 next = Read24(buffer + *offset);
|
uint32_t next = Read24(buffer + *offset);
|
||||||
if (((next >> bits_to_shift) & mask) == start_code)
|
if (((next >> bits_to_shift) & mask) == start_code)
|
||||||
return true;
|
return true;
|
||||||
++(*offset);
|
++(*offset);
|
||||||
|
@ -432,7 +431,7 @@ static bool AdvanceToStartCode(const uint8* buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks for an H.261 container.
|
// Checks for an H.261 container.
|
||||||
static bool CheckH261(const uint8* buffer, int buffer_size) {
|
static bool CheckH261(const uint8_t* buffer, int buffer_size) {
|
||||||
// Reference: ITU-T Recommendation H.261 (03/1993)
|
// Reference: ITU-T Recommendation H.261 (03/1993)
|
||||||
// (http://www.itu.int/rec/T-REC-H.261-199303-I/en)
|
// (http://www.itu.int/rec/T-REC-H.261-199303-I/en)
|
||||||
RCHECK(buffer_size > 16);
|
RCHECK(buffer_size > 16);
|
||||||
|
@ -480,7 +479,7 @@ static bool CheckH261(const uint8* buffer, int buffer_size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks for an H.263 container.
|
// Checks for an H.263 container.
|
||||||
static bool CheckH263(const uint8* buffer, int buffer_size) {
|
static bool CheckH263(const uint8_t* buffer, int buffer_size) {
|
||||||
// Reference: ITU-T Recommendation H.263 (01/2005)
|
// Reference: ITU-T Recommendation H.263 (01/2005)
|
||||||
// (http://www.itu.int/rec/T-REC-H.263-200501-I/en)
|
// (http://www.itu.int/rec/T-REC-H.263-200501-I/en)
|
||||||
// header is PSC(22b) + TR(8b) + PTYPE(8+b).
|
// header is PSC(22b) + TR(8b) + PTYPE(8+b).
|
||||||
|
@ -548,7 +547,7 @@ static bool CheckH263(const uint8* buffer, int buffer_size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks for an H.264 container.
|
// Checks for an H.264 container.
|
||||||
static bool CheckH264(const uint8* buffer, int buffer_size) {
|
static bool CheckH264(const uint8_t* buffer, int buffer_size) {
|
||||||
// Reference: ITU-T Recommendation H.264 (01/2012)
|
// Reference: ITU-T Recommendation H.264 (01/2012)
|
||||||
// (http://www.itu.int/rec/T-REC-H.264)
|
// (http://www.itu.int/rec/T-REC-H.264)
|
||||||
// Section B.1: Byte stream NAL unit syntax and semantics.
|
// Section B.1: Byte stream NAL unit syntax and semantics.
|
||||||
|
@ -604,7 +603,7 @@ static const char kHls2[] = "#EXT-X-TARGETDURATION:";
|
||||||
static const char kHls3[] = "#EXT-X-MEDIA-SEQUENCE:";
|
static const char kHls3[] = "#EXT-X-MEDIA-SEQUENCE:";
|
||||||
|
|
||||||
// Additional checks for a HLS container.
|
// Additional checks for a HLS container.
|
||||||
static bool CheckHls(const uint8* buffer, int buffer_size) {
|
static bool CheckHls(const uint8_t* buffer, int buffer_size) {
|
||||||
// HLS is simply a play list used for Apple HTTP Live Streaming.
|
// HLS is simply a play list used for Apple HTTP Live Streaming.
|
||||||
// Reference: Apple HTTP Live Streaming Overview
|
// Reference: Apple HTTP Live Streaming Overview
|
||||||
// (http://goo.gl/MIwxj)
|
// (http://goo.gl/MIwxj)
|
||||||
|
@ -630,7 +629,7 @@ static bool CheckHls(const uint8* buffer, int buffer_size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks for a MJPEG stream.
|
// Checks for a MJPEG stream.
|
||||||
static bool CheckMJpeg(const uint8* buffer, int buffer_size) {
|
static bool CheckMJpeg(const uint8_t* buffer, int buffer_size) {
|
||||||
// Reference: ISO/IEC 10918-1 : 1993(E), Annex B
|
// Reference: ISO/IEC 10918-1 : 1993(E), Annex B
|
||||||
// (http://www.w3.org/Graphics/JPEG/itu-t81.pdf)
|
// (http://www.w3.org/Graphics/JPEG/itu-t81.pdf)
|
||||||
RCHECK(buffer_size >= 16);
|
RCHECK(buffer_size >= 16);
|
||||||
|
@ -641,7 +640,7 @@ static bool CheckMJpeg(const uint8* buffer, int buffer_size) {
|
||||||
while (offset + 5 < buffer_size) {
|
while (offset + 5 < buffer_size) {
|
||||||
// Marker codes are always a two byte code with the first byte xFF.
|
// Marker codes are always a two byte code with the first byte xFF.
|
||||||
RCHECK(buffer[offset] == 0xff);
|
RCHECK(buffer[offset] == 0xff);
|
||||||
uint8 code = buffer[offset + 1];
|
uint8_t code = buffer[offset + 1];
|
||||||
RCHECK(code >= 0xc0 || code == 1);
|
RCHECK(code >= 0xc0 || code == 1);
|
||||||
|
|
||||||
// Skip sequences of xFF.
|
// Skip sequences of xFF.
|
||||||
|
@ -699,7 +698,7 @@ enum Mpeg2StartCodes {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Checks for a MPEG2 Program Stream.
|
// Checks for a MPEG2 Program Stream.
|
||||||
static bool CheckMpeg2ProgramStream(const uint8* buffer, int buffer_size) {
|
static bool CheckMpeg2ProgramStream(const uint8_t* buffer, int buffer_size) {
|
||||||
// Reference: ISO/IEC 13818-1 : 2000 (E) / ITU-T Rec. H.222.0 (2000 E).
|
// Reference: ISO/IEC 13818-1 : 2000 (E) / ITU-T Rec. H.222.0 (2000 E).
|
||||||
RCHECK(buffer_size > 14);
|
RCHECK(buffer_size > 14);
|
||||||
|
|
||||||
|
@ -794,10 +793,10 @@ static bool CheckMpeg2ProgramStream(const uint8* buffer, int buffer_size) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8 kMpeg2SyncWord = 0x47;
|
const uint8_t kMpeg2SyncWord = 0x47;
|
||||||
|
|
||||||
// Checks for a MPEG2 Transport Stream.
|
// Checks for a MPEG2 Transport Stream.
|
||||||
static bool CheckMpeg2TransportStream(const uint8* buffer, int buffer_size) {
|
static bool CheckMpeg2TransportStream(const uint8_t* buffer, int buffer_size) {
|
||||||
// Spec: ISO/IEC 13818-1 : 2000 (E) / ITU-T Rec. H.222.0 (2000 E).
|
// Spec: ISO/IEC 13818-1 : 2000 (E) / ITU-T Rec. H.222.0 (2000 E).
|
||||||
// Normal packet size is 188 bytes. However, some systems add various error
|
// Normal packet size is 188 bytes. However, some systems add various error
|
||||||
// correction data at the end, resulting in packet of length 192/204/208
|
// correction data at the end, resulting in packet of length 192/204/208
|
||||||
|
@ -870,7 +869,7 @@ enum Mpeg4StartCodes {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Checks for a raw MPEG4 bitstream container.
|
// Checks for a raw MPEG4 bitstream container.
|
||||||
static bool CheckMpeg4BitStream(const uint8* buffer, int buffer_size) {
|
static bool CheckMpeg4BitStream(const uint8_t* buffer, int buffer_size) {
|
||||||
// Defined in ISO/IEC 14496-2:2001.
|
// Defined in ISO/IEC 14496-2:2001.
|
||||||
// However, no length ... simply scan for start code values.
|
// However, no length ... simply scan for start code values.
|
||||||
// Note tags are very similar to H.264.
|
// Note tags are very similar to H.264.
|
||||||
|
@ -946,7 +945,7 @@ static bool CheckMpeg4BitStream(const uint8* buffer, int buffer_size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Additional checks for a MOV/QuickTime/MPEG4 container.
|
// Additional checks for a MOV/QuickTime/MPEG4 container.
|
||||||
static bool CheckMov(const uint8* buffer, int buffer_size) {
|
static bool CheckMov(const uint8_t* buffer, int buffer_size) {
|
||||||
// Reference: ISO/IEC 14496-12:2005(E).
|
// Reference: ISO/IEC 14496-12:2005(E).
|
||||||
// (http://standards.iso.org/ittf/PubliclyAvailableStandards/c061988_ISO_IEC_14496-12_2012.zip)
|
// (http://standards.iso.org/ittf/PubliclyAvailableStandards/c061988_ISO_IEC_14496-12_2012.zip)
|
||||||
RCHECK(buffer_size > 8);
|
RCHECK(buffer_size > 8);
|
||||||
|
@ -954,7 +953,7 @@ static bool CheckMov(const uint8* buffer, int buffer_size) {
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
while (offset + 8 < buffer_size) {
|
while (offset + 8 < buffer_size) {
|
||||||
int atomsize = Read32(buffer + offset);
|
int atomsize = Read32(buffer + offset);
|
||||||
uint32 atomtype = Read32(buffer + offset + 4);
|
uint32_t atomtype = Read32(buffer + offset + 4);
|
||||||
// Only need to check for ones that are valid at the top level.
|
// Only need to check for ones that are valid at the top level.
|
||||||
switch (atomtype) {
|
switch (atomtype) {
|
||||||
case TAG('f','t','y','p'):
|
case TAG('f','t','y','p'):
|
||||||
|
@ -1021,7 +1020,7 @@ static int kBitRateTableV2L1[16] = { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144,
|
||||||
static int kBitRateTableV2L23[16] = { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,
|
static int kBitRateTableV2L23[16] = { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,
|
||||||
112, 128, 144, 160, 0 };
|
112, 128, 144, 160, 0 };
|
||||||
|
|
||||||
static bool ValidMpegAudioFrameHeader(const uint8* header,
|
static bool ValidMpegAudioFrameHeader(const uint8_t* header,
|
||||||
int header_size,
|
int header_size,
|
||||||
int* framesize) {
|
int* framesize) {
|
||||||
// Reference: http://mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm.
|
// Reference: http://mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm.
|
||||||
|
@ -1081,7 +1080,7 @@ static bool ValidMpegAudioFrameHeader(const uint8* header,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract a size encoded the MP3 way.
|
// Extract a size encoded the MP3 way.
|
||||||
static int GetMp3HeaderSize(const uint8* buffer, int buffer_size) {
|
static int GetMp3HeaderSize(const uint8_t* buffer, int buffer_size) {
|
||||||
DCHECK_GE(buffer_size, 9);
|
DCHECK_GE(buffer_size, 9);
|
||||||
int size = ((buffer[6] & 0x7f) << 21) + ((buffer[7] & 0x7f) << 14) +
|
int size = ((buffer[6] & 0x7f) << 21) + ((buffer[7] & 0x7f) << 14) +
|
||||||
((buffer[8] & 0x7f) << 7) + (buffer[9] & 0x7f) + 10;
|
((buffer[8] & 0x7f) << 7) + (buffer[9] & 0x7f) + 10;
|
||||||
|
@ -1091,7 +1090,7 @@ static int GetMp3HeaderSize(const uint8* buffer, int buffer_size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Additional checks for a MP3 container.
|
// Additional checks for a MP3 container.
|
||||||
static bool CheckMp3(const uint8* buffer, int buffer_size, bool seenHeader) {
|
static bool CheckMp3(const uint8_t* buffer, int buffer_size, bool seenHeader) {
|
||||||
RCHECK(buffer_size >= 10); // Must be enough to read the initial header.
|
RCHECK(buffer_size >= 10); // Must be enough to read the initial header.
|
||||||
|
|
||||||
int framesize;
|
int framesize;
|
||||||
|
@ -1122,7 +1121,7 @@ static bool CheckMp3(const uint8* buffer, int buffer_size, bool seenHeader) {
|
||||||
// accepted is optional whitespace followed by 1 or more digits. |max_digits|
|
// accepted is optional whitespace followed by 1 or more digits. |max_digits|
|
||||||
// specifies the maximum number of digits to process. Returns true if a valid
|
// specifies the maximum number of digits to process. Returns true if a valid
|
||||||
// number is found, false otherwise.
|
// number is found, false otherwise.
|
||||||
static bool VerifyNumber(const uint8* buffer,
|
static bool VerifyNumber(const uint8_t* buffer,
|
||||||
int buffer_size,
|
int buffer_size,
|
||||||
int* offset,
|
int* offset,
|
||||||
int max_digits) {
|
int max_digits) {
|
||||||
|
@ -1150,7 +1149,7 @@ static bool VerifyNumber(const uint8* buffer,
|
||||||
// Check that the next character in |buffer| is one of |c1| or |c2|. |c2| is
|
// Check that the next character in |buffer| is one of |c1| or |c2|. |c2| is
|
||||||
// optional. Returns true if there is a match, false if no match or out of
|
// optional. Returns true if there is a match, false if no match or out of
|
||||||
// space.
|
// space.
|
||||||
static inline bool VerifyCharacters(const uint8* buffer,
|
static inline bool VerifyCharacters(const uint8_t* buffer,
|
||||||
int buffer_size,
|
int buffer_size,
|
||||||
int* offset,
|
int* offset,
|
||||||
char c1,
|
char c1,
|
||||||
|
@ -1161,7 +1160,7 @@ static inline bool VerifyCharacters(const uint8* buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks for a SRT container.
|
// Checks for a SRT container.
|
||||||
static bool CheckSrt(const uint8* buffer, int buffer_size) {
|
static bool CheckSrt(const uint8_t* buffer, int buffer_size) {
|
||||||
// Reference: http://en.wikipedia.org/wiki/SubRip
|
// Reference: http://en.wikipedia.org/wiki/SubRip
|
||||||
RCHECK(buffer_size > 20);
|
RCHECK(buffer_size > 20);
|
||||||
|
|
||||||
|
@ -1222,7 +1221,7 @@ static int GetElementId(BitReader* reader) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read a Matroska Unsigned Integer (VINT).
|
// Read a Matroska Unsigned Integer (VINT).
|
||||||
static uint64 GetVint(BitReader* reader) {
|
static uint64_t GetVint(BitReader* reader) {
|
||||||
// Values are coded with the leading zero bits (max 7) determining size.
|
// Values are coded with the leading zero bits (max 7) determining size.
|
||||||
// If it is an invalid coding or the end of the buffer is reached,
|
// If it is an invalid coding or the end of the buffer is reached,
|
||||||
// return something that will go off the end of the buffer.
|
// return something that will go off the end of the buffer.
|
||||||
|
@ -1244,7 +1243,7 @@ static uint64 GetVint(BitReader* reader) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Additional checks for a WEBM container.
|
// Additional checks for a WEBM container.
|
||||||
static bool CheckWebm(const uint8* buffer, int buffer_size) {
|
static bool CheckWebm(const uint8_t* buffer, int buffer_size) {
|
||||||
// Reference: http://www.matroska.org/technical/specs/index.html
|
// Reference: http://www.matroska.org/technical/specs/index.html
|
||||||
RCHECK(buffer_size > 12);
|
RCHECK(buffer_size > 12);
|
||||||
|
|
||||||
|
@ -1297,7 +1296,7 @@ enum VC1StartCodes {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Checks for a VC1 bitstream container.
|
// Checks for a VC1 bitstream container.
|
||||||
static bool CheckVC1(const uint8* buffer, int buffer_size) {
|
static bool CheckVC1(const uint8_t* buffer, int buffer_size) {
|
||||||
// Reference: SMPTE 421M
|
// Reference: SMPTE 421M
|
||||||
// (http://standards.smpte.org/content/978-1-61482-555-5/st-421-2006/SEC1.body.pdf)
|
// (http://standards.smpte.org/content/978-1-61482-555-5/st-421-2006/SEC1.body.pdf)
|
||||||
// However, no length ... simply scan for start code values.
|
// However, no length ... simply scan for start code values.
|
||||||
|
@ -1405,27 +1404,27 @@ static bool CheckVC1(const uint8* buffer, int buffer_size) {
|
||||||
// For some formats the signature is a bunch of characters. They are defined
|
// For some formats the signature is a bunch of characters. They are defined
|
||||||
// below. Note that the first 4 characters of the string may be used as a TAG
|
// below. Note that the first 4 characters of the string may be used as a TAG
|
||||||
// in LookupContainerByFirst4. For signatures that contain embedded \0, use
|
// in LookupContainerByFirst4. For signatures that contain embedded \0, use
|
||||||
// uint8[].
|
// uint8_t[].
|
||||||
static const char kAmrSignature[] = "#!AMR";
|
static const char kAmrSignature[] = "#!AMR";
|
||||||
static const uint8 kAsfSignature[] = { 0x30, 0x26, 0xb2, 0x75, 0x8e, 0x66, 0xcf,
|
static const uint8_t kAsfSignature[] = {0x30, 0x26, 0xb2, 0x75, 0x8e, 0x66,
|
||||||
0x11, 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62,
|
0xcf, 0x11, 0xa6, 0xd9, 0x00, 0xaa,
|
||||||
0xce, 0x6c };
|
0x00, 0x62, 0xce, 0x6c};
|
||||||
static const char kAssSignature[] = "[Script Info]";
|
static const char kAssSignature[] = "[Script Info]";
|
||||||
static const char kAssBomSignature[] = UTF8_BYTE_ORDER_MARK "[Script Info]";
|
static const char kAssBomSignature[] = UTF8_BYTE_ORDER_MARK "[Script Info]";
|
||||||
static const uint8 kWtvSignature[] = { 0xb7, 0xd8, 0x00, 0x20, 0x37, 0x49, 0xda,
|
static const uint8_t kWtvSignature[] = {0xb7, 0xd8, 0x00, 0x20, 0x37, 0x49,
|
||||||
0x11, 0xa6, 0x4e, 0x00, 0x07, 0xe9, 0x5e,
|
0xda, 0x11, 0xa6, 0x4e, 0x00, 0x07,
|
||||||
0xad, 0x8d };
|
0xe9, 0x5e, 0xad, 0x8d};
|
||||||
|
|
||||||
// Attempt to determine the container type from the buffer provided. This is
|
// Attempt to determine the container type from the buffer provided. This is
|
||||||
// a simple pass, that uses the first 4 bytes of the buffer as an index to get
|
// a simple pass, that uses the first 4 bytes of the buffer as an index to get
|
||||||
// a rough idea of the container format.
|
// a rough idea of the container format.
|
||||||
static MediaContainerName LookupContainerByFirst4(const uint8* buffer,
|
static MediaContainerName LookupContainerByFirst4(const uint8_t* buffer,
|
||||||
int buffer_size) {
|
int buffer_size) {
|
||||||
// Minimum size that the code expects to exist without checking size.
|
// Minimum size that the code expects to exist without checking size.
|
||||||
if (buffer_size < 12)
|
if (buffer_size < 12)
|
||||||
return CONTAINER_UNKNOWN;
|
return CONTAINER_UNKNOWN;
|
||||||
|
|
||||||
uint32 first4 = Read32(buffer);
|
uint32_t first4 = Read32(buffer);
|
||||||
switch (first4) {
|
switch (first4) {
|
||||||
case 0x1a45dfa3:
|
case 0x1a45dfa3:
|
||||||
if (CheckWebm(buffer, buffer_size))
|
if (CheckWebm(buffer, buffer_size))
|
||||||
|
@ -1580,7 +1579,7 @@ static MediaContainerName LookupContainerByFirst4(const uint8* buffer,
|
||||||
|
|
||||||
// Now try a few different ones that look at something other
|
// Now try a few different ones that look at something other
|
||||||
// than the first 4 bytes.
|
// than the first 4 bytes.
|
||||||
uint32 first3 = first4 & 0xffffff00;
|
uint32_t first3 = first4 & 0xffffff00;
|
||||||
switch (first3) {
|
switch (first3) {
|
||||||
case TAG('C','W','S',0):
|
case TAG('C','W','S',0):
|
||||||
case TAG('F','W','S',0):
|
case TAG('F','W','S',0):
|
||||||
|
@ -1593,7 +1592,7 @@ static MediaContainerName LookupContainerByFirst4(const uint8* buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Maybe the first 2 characters are something we can use.
|
// Maybe the first 2 characters are something we can use.
|
||||||
uint32 first2 = Read16(buffer);
|
uint32_t first2 = Read16(buffer);
|
||||||
switch (first2) {
|
switch (first2) {
|
||||||
case kAc3SyncWord:
|
case kAc3SyncWord:
|
||||||
if (CheckAc3(buffer, buffer_size))
|
if (CheckAc3(buffer, buffer_size))
|
||||||
|
@ -1619,7 +1618,7 @@ static MediaContainerName LookupContainerByFirst4(const uint8* buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to determine the container name from the buffer provided.
|
// Attempt to determine the container name from the buffer provided.
|
||||||
MediaContainerName DetermineContainer(const uint8* buffer, int buffer_size) {
|
MediaContainerName DetermineContainer(const uint8_t* buffer, int buffer_size) {
|
||||||
DCHECK(buffer);
|
DCHECK(buffer);
|
||||||
|
|
||||||
// Since MOV/QuickTime/MPEG4 streams are common, check for them first.
|
// Since MOV/QuickTime/MPEG4 streams are common, check for them first.
|
||||||
|
|
|
@ -55,7 +55,7 @@ enum MediaContainerName {
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Determine the container type.
|
/// Determine the container type.
|
||||||
MediaContainerName DetermineContainer(const uint8* buffer, int buffer_size);
|
MediaContainerName DetermineContainer(const uint8_t* buffer, int buffer_size);
|
||||||
|
|
||||||
} // namespace media
|
} // namespace media
|
||||||
} // namespace edash_packager
|
} // namespace edash_packager
|
||||||
|
|
|
@ -14,9 +14,9 @@ namespace media {
|
||||||
// Using a macros to simplify tests. Since EXPECT_EQ outputs the second argument
|
// Using a macros to simplify tests. Since EXPECT_EQ outputs the second argument
|
||||||
// as a string when it fails, this lets the output identify what item actually
|
// as a string when it fails, this lets the output identify what item actually
|
||||||
// failed.
|
// failed.
|
||||||
#define VERIFY(buffer, name) \
|
#define VERIFY(buffer, name) \
|
||||||
EXPECT_EQ(name, \
|
EXPECT_EQ(name, \
|
||||||
DetermineContainer(reinterpret_cast<const uint8*>(buffer), \
|
DetermineContainer(reinterpret_cast<const uint8_t*>(buffer), \
|
||||||
sizeof(buffer)))
|
sizeof(buffer)))
|
||||||
|
|
||||||
// Test that small buffers are handled correctly.
|
// Test that small buffers are handled correctly.
|
||||||
|
@ -57,30 +57,30 @@ TEST(ContainerNamesTest, CheckSmallBuffer) {
|
||||||
// Note that the comparisons need at least 12 bytes, so make sure the buffer is
|
// Note that the comparisons need at least 12 bytes, so make sure the buffer is
|
||||||
// at least that size.
|
// at least that size.
|
||||||
const char kAmrBuffer[12] = "#!AMR";
|
const char kAmrBuffer[12] = "#!AMR";
|
||||||
uint8 kAsfBuffer[] = { 0x30, 0x26, 0xb2, 0x75, 0x8e, 0x66, 0xcf, 0x11, 0xa6,
|
uint8_t kAsfBuffer[] = {0x30, 0x26, 0xb2, 0x75, 0x8e, 0x66, 0xcf, 0x11,
|
||||||
0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c };
|
0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c};
|
||||||
const char kAss1Buffer[] = "[Script Info]";
|
const char kAss1Buffer[] = "[Script Info]";
|
||||||
const char kAss2Buffer[] = BYTE_ORDER_MARK "[Script Info]";
|
const char kAss2Buffer[] = BYTE_ORDER_MARK "[Script Info]";
|
||||||
uint8 kCafBuffer[] = { 'c', 'a', 'f', 'f', 0, 1, 0, 0, 'd', 'e', 's', 'c', 0, 0,
|
uint8_t kCafBuffer[] = {
|
||||||
0, 0, 0, 0, 0, 32, 64, 229, 136, 128, 0, 0, 0, 0, 'a',
|
'c', 'a', 'f', 'f', 0, 1, 0, 0, 'd', 'e', 's', 'c', 0, 0, 0, 0, 0, 0, 0,
|
||||||
'a', 'c', ' ', 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0,
|
32, 64, 229, 136, 128, 0, 0, 0, 0, 'a', 'a', 'c', ' ', 0, 0, 0, 2, 0, 0,
|
||||||
0, 2, 0, 0, 0, 0 };
|
0, 0, 0, 0, 4, 0, 0, 0, 0, 2, 0, 0, 0, 0};
|
||||||
const char kDtshdBuffer[12] = "DTSHDHDR";
|
const char kDtshdBuffer[12] = "DTSHDHDR";
|
||||||
const char kDxaBuffer[16] = "DEXA";
|
const char kDxaBuffer[16] = "DEXA";
|
||||||
const char kFlacBuffer[12] = "fLaC";
|
const char kFlacBuffer[12] = "fLaC";
|
||||||
uint8 kFlvBuffer[12] = { 'F', 'L', 'V', 0, 0, 0, 0, 1, 0, 0, 0, 0 };
|
uint8_t kFlvBuffer[12] = {'F', 'L', 'V', 0, 0, 0, 0, 1, 0, 0, 0, 0};
|
||||||
uint8 kIrcamBuffer[] = { 0x64, 0xa3, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1 };
|
uint8_t kIrcamBuffer[] = {0x64, 0xa3, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1};
|
||||||
const char kRm1Buffer[12] = ".RMF\0\0";
|
const char kRm1Buffer[12] = ".RMF\0\0";
|
||||||
const char kRm2Buffer[12] = ".ra\xfd";
|
const char kRm2Buffer[12] = ".ra\xfd";
|
||||||
uint8 kWtvBuffer[] = { 0xb7, 0xd8, 0x00, 0x20, 0x37, 0x49, 0xda, 0x11, 0xa6,
|
uint8_t kWtvBuffer[] = {0xb7, 0xd8, 0x00, 0x20, 0x37, 0x49, 0xda, 0x11,
|
||||||
0x4e, 0x00, 0x07, 0xe9, 0x5e, 0xad, 0x8d };
|
0xa6, 0x4e, 0x00, 0x07, 0xe9, 0x5e, 0xad, 0x8d};
|
||||||
uint8 kBug263073Buffer[] = {
|
uint8_t kBug263073Buffer[] = {
|
||||||
0x00, 0x00, 0x00, 0x18, 0x66, 0x74, 0x79, 0x70, 0x6d, 0x70, 0x34, 0x32,
|
0x00, 0x00, 0x00, 0x18, 0x66, 0x74, 0x79, 0x70, 0x6d, 0x70, 0x34,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x69, 0x73, 0x6f, 0x6d, 0x6d, 0x70, 0x34, 0x32,
|
0x32, 0x00, 0x00, 0x00, 0x00, 0x69, 0x73, 0x6f, 0x6d, 0x6d, 0x70,
|
||||||
0x00, 0x00, 0x00, 0x01, 0x6d, 0x64, 0x61, 0x74, 0x00, 0x00, 0x00, 0x00,
|
0x34, 0x32, 0x00, 0x00, 0x00, 0x01, 0x6d, 0x64, 0x61, 0x74, 0x00,
|
||||||
0xaa, 0x2e, 0x22, 0xcf, 0x00, 0x00, 0x00, 0x37, 0x67, 0x64, 0x00, 0x28,
|
0x00, 0x00, 0x00, 0xaa, 0x2e, 0x22, 0xcf, 0x00, 0x00, 0x00, 0x37,
|
||||||
0xac, 0x2c, 0xa4, 0x01, 0xe0, 0x08, 0x9f, 0x97, 0x01, 0x52, 0x02, 0x02,
|
0x67, 0x64, 0x00, 0x28, 0xac, 0x2c, 0xa4, 0x01, 0xe0, 0x08, 0x9f,
|
||||||
0x02, 0x80, 0x00, 0x01};
|
0x97, 0x01, 0x52, 0x02, 0x02, 0x02, 0x80, 0x00, 0x01};
|
||||||
|
|
||||||
// Test that containers that start with fixed strings are handled correctly.
|
// Test that containers that start with fixed strings are handled correctly.
|
||||||
// This is to verify that the TAG matches the first 4 characters of the string.
|
// This is to verify that the TAG matches the first 4 characters of the string.
|
||||||
|
@ -108,14 +108,14 @@ void TestFile(MediaContainerName expected, const base::FilePath& filename) {
|
||||||
// Windows implementation of ReadFile fails if file smaller than desired size,
|
// Windows implementation of ReadFile fails if file smaller than desired size,
|
||||||
// so use file length if file less than 8192 bytes (http://crbug.com/243885).
|
// so use file length if file less than 8192 bytes (http://crbug.com/243885).
|
||||||
int read_size = sizeof(buffer);
|
int read_size = sizeof(buffer);
|
||||||
int64 actual_size;
|
int64_t actual_size;
|
||||||
if (base::GetFileSize(filename, &actual_size) && actual_size < read_size)
|
if (base::GetFileSize(filename, &actual_size) && actual_size < read_size)
|
||||||
read_size = actual_size;
|
read_size = actual_size;
|
||||||
int read = base::ReadFile(filename, buffer, read_size);
|
int read = base::ReadFile(filename, buffer, read_size);
|
||||||
|
|
||||||
// Now verify the type.
|
// Now verify the type.
|
||||||
EXPECT_EQ(expected,
|
EXPECT_EQ(expected,
|
||||||
DetermineContainer(reinterpret_cast<const uint8*>(buffer), read))
|
DetermineContainer(reinterpret_cast<const uint8_t*>(buffer), read))
|
||||||
<< "Failure with file " << filename.value();
|
<< "Failure with file " << filename.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
namespace edash_packager {
|
namespace edash_packager {
|
||||||
namespace media {
|
namespace media {
|
||||||
|
|
||||||
DecryptConfig::DecryptConfig(const std::vector<uint8>& key_id,
|
DecryptConfig::DecryptConfig(const std::vector<uint8_t>& key_id,
|
||||||
const std::vector<uint8>& iv,
|
const std::vector<uint8_t>& iv,
|
||||||
const int data_offset,
|
const int data_offset,
|
||||||
const std::vector<SubsampleEntry>& subsamples)
|
const std::vector<SubsampleEntry>& subsamples)
|
||||||
: key_id_(key_id),
|
: key_id_(key_id),
|
||||||
|
|
|
@ -24,8 +24,8 @@ namespace media {
|
||||||
/// result, and then copying each byte from the decrypted block over the
|
/// result, and then copying each byte from the decrypted block over the
|
||||||
/// corresponding encrypted byte.
|
/// corresponding encrypted byte.
|
||||||
struct SubsampleEntry {
|
struct SubsampleEntry {
|
||||||
uint16 clear_bytes;
|
uint16_t clear_bytes;
|
||||||
uint32 cipher_bytes;
|
uint32_t cipher_bytes;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Contains all the information that a decryptor needs to decrypt a media
|
/// Contains all the information that a decryptor needs to decrypt a media
|
||||||
|
@ -44,22 +44,22 @@ class DecryptConfig {
|
||||||
/// @param subsamples defines the clear and encrypted portions of the sample
|
/// @param subsamples defines the clear and encrypted portions of the sample
|
||||||
/// as described in SubsampleEntry. A decrypted buffer will be equal
|
/// as described in SubsampleEntry. A decrypted buffer will be equal
|
||||||
/// in size to the sum of the subsample sizes.
|
/// in size to the sum of the subsample sizes.
|
||||||
DecryptConfig(const std::vector<uint8>& key_id,
|
DecryptConfig(const std::vector<uint8_t>& key_id,
|
||||||
const std::vector<uint8>& iv,
|
const std::vector<uint8_t>& iv,
|
||||||
const int data_offset,
|
const int data_offset,
|
||||||
const std::vector<SubsampleEntry>& subsamples);
|
const std::vector<SubsampleEntry>& subsamples);
|
||||||
~DecryptConfig();
|
~DecryptConfig();
|
||||||
|
|
||||||
const std::vector<uint8>& key_id() const { return key_id_; }
|
const std::vector<uint8_t>& key_id() const { return key_id_; }
|
||||||
const std::vector<uint8>& iv() const { return iv_; }
|
const std::vector<uint8_t>& iv() const { return iv_; }
|
||||||
int data_offset() const { return data_offset_; }
|
int data_offset() const { return data_offset_; }
|
||||||
const std::vector<SubsampleEntry>& subsamples() const { return subsamples_; }
|
const std::vector<SubsampleEntry>& subsamples() const { return subsamples_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::vector<uint8> key_id_;
|
const std::vector<uint8_t> key_id_;
|
||||||
|
|
||||||
// Initialization vector.
|
// Initialization vector.
|
||||||
const std::vector<uint8> iv_;
|
const std::vector<uint8_t> iv_;
|
||||||
|
|
||||||
// Amount of data to be discarded before applying subsample information.
|
// Amount of data to be discarded before applying subsample information.
|
||||||
const int data_offset_;
|
const int data_offset_;
|
||||||
|
|
|
@ -31,7 +31,8 @@ Demuxer::Demuxer(const std::string& file_name)
|
||||||
: file_name_(file_name),
|
: file_name_(file_name),
|
||||||
media_file_(NULL),
|
media_file_(NULL),
|
||||||
init_event_received_(false),
|
init_event_received_(false),
|
||||||
buffer_(new uint8[kBufSize]) {}
|
buffer_(new uint8_t[kBufSize]) {
|
||||||
|
}
|
||||||
|
|
||||||
Demuxer::~Demuxer() {
|
Demuxer::~Demuxer() {
|
||||||
if (media_file_)
|
if (media_file_)
|
||||||
|
@ -54,7 +55,7 @@ Status Demuxer::Initialize() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine media container.
|
// Determine media container.
|
||||||
int64 bytes_read = media_file_->Read(buffer_.get(), kBufSize);
|
int64_t bytes_read = media_file_->Read(buffer_.get(), kBufSize);
|
||||||
if (bytes_read <= 0)
|
if (bytes_read <= 0)
|
||||||
return Status(error::FILE_FAILURE, "Cannot read file " + file_name_);
|
return Status(error::FILE_FAILURE, "Cannot read file " + file_name_);
|
||||||
MediaContainerName container = DetermineContainer(buffer_.get(), bytes_read);
|
MediaContainerName container = DetermineContainer(buffer_.get(), bytes_read);
|
||||||
|
@ -101,7 +102,7 @@ void Demuxer::ParserInitEvent(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Demuxer::NewSampleEvent(uint32 track_id,
|
bool Demuxer::NewSampleEvent(uint32_t track_id,
|
||||||
const scoped_refptr<MediaSample>& sample) {
|
const scoped_refptr<MediaSample>& sample) {
|
||||||
std::vector<MediaStream*>::iterator it = streams_.begin();
|
std::vector<MediaStream*>::iterator it = streams_.begin();
|
||||||
for (; it != streams_.end(); ++it) {
|
for (; it != streams_.end(); ++it) {
|
||||||
|
@ -146,7 +147,7 @@ Status Demuxer::Parse() {
|
||||||
DCHECK(parser_);
|
DCHECK(parser_);
|
||||||
DCHECK(buffer_);
|
DCHECK(buffer_);
|
||||||
|
|
||||||
int64 bytes_read = media_file_->Read(buffer_.get(), kBufSize);
|
int64_t bytes_read = media_file_->Read(buffer_.get(), kBufSize);
|
||||||
if (bytes_read <= 0) {
|
if (bytes_read <= 0) {
|
||||||
if (media_file_->Eof()) {
|
if (media_file_->Eof()) {
|
||||||
parser_->Flush();
|
parser_->Flush();
|
||||||
|
|
|
@ -64,7 +64,7 @@ class Demuxer {
|
||||||
private:
|
private:
|
||||||
// Parser event handlers.
|
// Parser event handlers.
|
||||||
void ParserInitEvent(const std::vector<scoped_refptr<StreamInfo> >& streams);
|
void ParserInitEvent(const std::vector<scoped_refptr<StreamInfo> >& streams);
|
||||||
bool NewSampleEvent(uint32 track_id,
|
bool NewSampleEvent(uint32_t track_id,
|
||||||
const scoped_refptr<MediaSample>& sample);
|
const scoped_refptr<MediaSample>& sample);
|
||||||
|
|
||||||
std::string file_name_;
|
std::string file_name_;
|
||||||
|
@ -72,7 +72,7 @@ class Demuxer {
|
||||||
bool init_event_received_;
|
bool init_event_received_;
|
||||||
scoped_ptr<MediaParser> parser_;
|
scoped_ptr<MediaParser> parser_;
|
||||||
std::vector<MediaStream*> streams_;
|
std::vector<MediaStream*> streams_;
|
||||||
scoped_ptr<uint8[]> buffer_;
|
scoped_ptr<uint8_t[]> buffer_;
|
||||||
scoped_ptr<KeySource> key_source_;
|
scoped_ptr<KeySource> key_source_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(Demuxer);
|
DISALLOW_COPY_AND_ASSIGN(Demuxer);
|
||||||
|
|
|
@ -19,7 +19,7 @@ FILE* g_rand_source_fp = NULL;
|
||||||
const char kFakePrngDataFile[] = "fake_prng_data.bin";
|
const char kFakePrngDataFile[] = "fake_prng_data.bin";
|
||||||
|
|
||||||
// RAND_bytes and RAND_pseudorand implementation.
|
// RAND_bytes and RAND_pseudorand implementation.
|
||||||
int FakeBytes(uint8* buf, int num) {
|
int FakeBytes(uint8_t* buf, int num) {
|
||||||
DCHECK(buf);
|
DCHECK(buf);
|
||||||
DCHECK(g_rand_source_fp);
|
DCHECK(g_rand_source_fp);
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ SimpleHttpFetcher::SimpleHttpFetcher() : timeout_in_seconds_(0) {
|
||||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleHttpFetcher::SimpleHttpFetcher(uint32 timeout_in_seconds)
|
SimpleHttpFetcher::SimpleHttpFetcher(uint32_t timeout_in_seconds)
|
||||||
: timeout_in_seconds_(timeout_in_seconds) {
|
: timeout_in_seconds_(timeout_in_seconds) {
|
||||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ class SimpleHttpFetcher : public HttpFetcher {
|
||||||
SimpleHttpFetcher();
|
SimpleHttpFetcher();
|
||||||
/// Create a fetcher with timeout.
|
/// Create a fetcher with timeout.
|
||||||
/// @param timeout_in_seconds specifies the timeout in seconds.
|
/// @param timeout_in_seconds specifies the timeout in seconds.
|
||||||
SimpleHttpFetcher(uint32 timeout_in_seconds);
|
SimpleHttpFetcher(uint32_t timeout_in_seconds);
|
||||||
virtual ~SimpleHttpFetcher();
|
virtual ~SimpleHttpFetcher();
|
||||||
|
|
||||||
/// @name HttpFetcher implementation overrides.
|
/// @name HttpFetcher implementation overrides.
|
||||||
|
@ -72,7 +72,7 @@ class SimpleHttpFetcher : public HttpFetcher {
|
||||||
Status FetchInternal(HttpMethod method, const std::string& url,
|
Status FetchInternal(HttpMethod method, const std::string& url,
|
||||||
const std::string& data, std::string* response);
|
const std::string& data, std::string* response);
|
||||||
|
|
||||||
const uint32 timeout_in_seconds_;
|
const uint32_t timeout_in_seconds_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(SimpleHttpFetcher);
|
DISALLOW_COPY_AND_ASSIGN(SimpleHttpFetcher);
|
||||||
};
|
};
|
||||||
|
|
|
@ -70,7 +70,7 @@ TEST(DISABLED_HttpFetcherTest, UrlWithPort) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DISABLED_HttpFetcherTest, SmallTimeout) {
|
TEST(DISABLED_HttpFetcherTest, SmallTimeout) {
|
||||||
const uint32 kTimeoutInSeconds = 1;
|
const uint32_t kTimeoutInSeconds = 1;
|
||||||
SimpleHttpFetcher fetcher(kTimeoutInSeconds);
|
SimpleHttpFetcher fetcher(kTimeoutInSeconds);
|
||||||
std::string response;
|
std::string response;
|
||||||
Status status = fetcher.Post(kTestUrl, kDelayTwoSecs, &response);
|
Status status = fetcher.Post(kTestUrl, kDelayTwoSecs, &response);
|
||||||
|
@ -78,7 +78,7 @@ TEST(DISABLED_HttpFetcherTest, SmallTimeout) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(DISABLED_HttpFetcherTest, BigTimeout) {
|
TEST(DISABLED_HttpFetcherTest, BigTimeout) {
|
||||||
const uint32 kTimeoutInSeconds = 5;
|
const uint32_t kTimeoutInSeconds = 5;
|
||||||
SimpleHttpFetcher fetcher(kTimeoutInSeconds);
|
SimpleHttpFetcher fetcher(kTimeoutInSeconds);
|
||||||
std::string response;
|
std::string response;
|
||||||
Status status = fetcher.Post(kTestUrl, kDelayTwoSecs, &response);
|
Status status = fetcher.Post(kTestUrl, kDelayTwoSecs, &response);
|
||||||
|
|
|
@ -11,9 +11,9 @@
|
||||||
#include "media/base/buffer_writer.h"
|
#include "media/base/buffer_writer.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
const uint8 kWidevineSystemId[] = {0xed, 0xef, 0x8b, 0xa9, 0x79, 0xd6,
|
const uint8_t kWidevineSystemId[] = {0xed, 0xef, 0x8b, 0xa9, 0x79, 0xd6,
|
||||||
0x4a, 0xce, 0xa3, 0xc8, 0x27, 0xdc,
|
0x4a, 0xce, 0xa3, 0xc8, 0x27, 0xdc,
|
||||||
0xd5, 0x1d, 0x21, 0xed};
|
0xd5, 0x1d, 0x21, 0xed};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace edash_packager {
|
namespace edash_packager {
|
||||||
|
@ -24,13 +24,13 @@ EncryptionKey::~EncryptionKey() {}
|
||||||
|
|
||||||
KeySource::~KeySource() {}
|
KeySource::~KeySource() {}
|
||||||
|
|
||||||
Status KeySource::FetchKeys(const std::vector<uint8>& content_id,
|
Status KeySource::FetchKeys(const std::vector<uint8_t>& content_id,
|
||||||
const std::string& policy) {
|
const std::string& policy) {
|
||||||
// Do nothing for fixed key decryption.
|
// Do nothing for fixed key decryption.
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status KeySource::FetchKeys(const std::vector<uint8>& pssh_data) {
|
Status KeySource::FetchKeys(const std::vector<uint8_t>& pssh_data) {
|
||||||
// Do nothing for fixed key decryption.
|
// Do nothing for fixed key decryption.
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ Status KeySource::GetKey(TrackType track_type, EncryptionKey* key) {
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status KeySource::GetKey(const std::vector<uint8>& key_id,
|
Status KeySource::GetKey(const std::vector<uint8_t>& key_id,
|
||||||
EncryptionKey* key) {
|
EncryptionKey* key) {
|
||||||
DCHECK(key);
|
DCHECK(key);
|
||||||
DCHECK(encryption_key_);
|
DCHECK(encryption_key_);
|
||||||
|
@ -55,7 +55,7 @@ Status KeySource::GetKey(const std::vector<uint8>& key_id,
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status KeySource::GetCryptoPeriodKey(uint32 crypto_period_index,
|
Status KeySource::GetCryptoPeriodKey(uint32_t crypto_period_index,
|
||||||
TrackType track_type,
|
TrackType track_type,
|
||||||
EncryptionKey* key) {
|
EncryptionKey* key) {
|
||||||
NOTIMPLEMENTED();
|
NOTIMPLEMENTED();
|
||||||
|
@ -79,7 +79,7 @@ scoped_ptr<KeySource> KeySource::CreateFromHexStrings(
|
||||||
return scoped_ptr<KeySource>();
|
return scoped_ptr<KeySource>();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8> pssh_data;
|
std::vector<uint8_t> pssh_data;
|
||||||
if (!pssh_data_hex.empty() &&
|
if (!pssh_data_hex.empty() &&
|
||||||
!base::HexStringToBytes(pssh_data_hex, &pssh_data)) {
|
!base::HexStringToBytes(pssh_data_hex, &pssh_data)) {
|
||||||
LOG(ERROR) << "Cannot parse pssh_hex " << pssh_data_hex;
|
LOG(ERROR) << "Cannot parse pssh_hex " << pssh_data_hex;
|
||||||
|
@ -124,13 +124,13 @@ std::string KeySource::TrackTypeToString(TrackType track_type) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8> KeySource::PsshBoxFromPsshData(
|
std::vector<uint8_t> KeySource::PsshBoxFromPsshData(
|
||||||
const std::vector<uint8>& pssh_data) {
|
const std::vector<uint8_t>& pssh_data) {
|
||||||
const uint8 kPsshFourCC[] = {'p', 's', 's', 'h'};
|
const uint8_t kPsshFourCC[] = {'p', 's', 's', 'h'};
|
||||||
const uint32 kVersionAndFlags = 0;
|
const uint32_t kVersionAndFlags = 0;
|
||||||
|
|
||||||
const uint32 pssh_data_size = pssh_data.size();
|
const uint32_t pssh_data_size = pssh_data.size();
|
||||||
const uint32 total_size =
|
const uint32_t total_size =
|
||||||
sizeof(total_size) + sizeof(kPsshFourCC) + sizeof(kVersionAndFlags) +
|
sizeof(total_size) + sizeof(kPsshFourCC) + sizeof(kVersionAndFlags) +
|
||||||
sizeof(kWidevineSystemId) + sizeof(pssh_data_size) + pssh_data_size;
|
sizeof(kWidevineSystemId) + sizeof(pssh_data_size) + pssh_data_size;
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ std::vector<uint8> KeySource::PsshBoxFromPsshData(
|
||||||
writer.AppendArray(kWidevineSystemId, sizeof(kWidevineSystemId));
|
writer.AppendArray(kWidevineSystemId, sizeof(kWidevineSystemId));
|
||||||
writer.AppendInt(pssh_data_size);
|
writer.AppendInt(pssh_data_size);
|
||||||
writer.AppendVector(pssh_data);
|
writer.AppendVector(pssh_data);
|
||||||
return std::vector<uint8>(writer.Buffer(), writer.Buffer() + writer.Size());
|
return std::vector<uint8_t>(writer.Buffer(), writer.Buffer() + writer.Size());
|
||||||
}
|
}
|
||||||
|
|
||||||
KeySource::KeySource() {}
|
KeySource::KeySource() {}
|
||||||
|
|
|
@ -19,10 +19,10 @@ struct EncryptionKey {
|
||||||
EncryptionKey();
|
EncryptionKey();
|
||||||
~EncryptionKey();
|
~EncryptionKey();
|
||||||
|
|
||||||
std::vector<uint8> key_id;
|
std::vector<uint8_t> key_id;
|
||||||
std::vector<uint8> key;
|
std::vector<uint8_t> key;
|
||||||
std::vector<uint8> pssh;
|
std::vector<uint8_t> pssh;
|
||||||
std::vector<uint8> iv;
|
std::vector<uint8_t> iv;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// KeySource is responsible for encryption key acquisition.
|
/// KeySource is responsible for encryption key acquisition.
|
||||||
|
@ -42,14 +42,14 @@ class KeySource {
|
||||||
/// @param content_id the unique id identify the content.
|
/// @param content_id the unique id identify the content.
|
||||||
/// @param policy specifies the DRM content rights.
|
/// @param policy specifies the DRM content rights.
|
||||||
/// @return OK on success, an error status otherwise.
|
/// @return OK on success, an error status otherwise.
|
||||||
virtual Status FetchKeys(const std::vector<uint8>& content_id,
|
virtual Status FetchKeys(const std::vector<uint8_t>& content_id,
|
||||||
const std::string& policy);
|
const std::string& policy);
|
||||||
|
|
||||||
/// Fetch keys for CENC from the key server.
|
/// Fetch keys for CENC from the key server.
|
||||||
/// @param pssh_data is the Data portion of the PSSH box for the content
|
/// @param pssh_data is the Data portion of the PSSH box for the content
|
||||||
/// to be decrypted.
|
/// to be decrypted.
|
||||||
/// @return OK on success, an error status otherwise.
|
/// @return OK on success, an error status otherwise.
|
||||||
virtual Status FetchKeys(const std::vector<uint8>& pssh_data);
|
virtual Status FetchKeys(const std::vector<uint8_t>& pssh_data);
|
||||||
|
|
||||||
/// Get encryption key of the specified track type.
|
/// Get encryption key of the specified track type.
|
||||||
/// @param track_type is the type of track for which retrieving the key.
|
/// @param track_type is the type of track for which retrieving the key.
|
||||||
|
@ -63,7 +63,7 @@ class KeySource {
|
||||||
/// @param key is a pointer to the EncryptionKey which will hold the retrieved
|
/// @param key is a pointer to the EncryptionKey which will hold the retrieved
|
||||||
/// key. Owner retains ownership, and may not be NULL.
|
/// key. Owner retains ownership, and may not be NULL.
|
||||||
/// @return OK on success, or an error status otherwise.
|
/// @return OK on success, or an error status otherwise.
|
||||||
virtual Status GetKey(const std::vector<uint8>& key_id, EncryptionKey* key);
|
virtual Status GetKey(const std::vector<uint8_t>& key_id, EncryptionKey* key);
|
||||||
|
|
||||||
/// Get encryption key of the specified track type at the specified index.
|
/// Get encryption key of the specified track type at the specified index.
|
||||||
/// @param crypto_period_index is the sequence number of the key rotation
|
/// @param crypto_period_index is the sequence number of the key rotation
|
||||||
|
@ -72,7 +72,7 @@ class KeySource {
|
||||||
/// @param key is a pointer to the EncryptionKey which will hold the retrieved
|
/// @param key is a pointer to the EncryptionKey which will hold the retrieved
|
||||||
/// key. Owner retains ownership, and may not be NULL.
|
/// key. Owner retains ownership, and may not be NULL.
|
||||||
/// @return OK on success, an error status otherwise.
|
/// @return OK on success, an error status otherwise.
|
||||||
virtual Status GetCryptoPeriodKey(uint32 crypto_period_index,
|
virtual Status GetCryptoPeriodKey(uint32_t crypto_period_index,
|
||||||
TrackType track_type,
|
TrackType track_type,
|
||||||
EncryptionKey* key);
|
EncryptionKey* key);
|
||||||
|
|
||||||
|
@ -101,8 +101,8 @@ class KeySource {
|
||||||
|
|
||||||
/// @return the raw bytes of the pssh box with system ID and box header
|
/// @return the raw bytes of the pssh box with system ID and box header
|
||||||
/// included.
|
/// included.
|
||||||
static std::vector<uint8> PsshBoxFromPsshData(
|
static std::vector<uint8_t> PsshBoxFromPsshData(
|
||||||
const std::vector<uint8>& pssh_data);
|
const std::vector<uint8_t>& pssh_data);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
explicit KeySource(scoped_ptr<EncryptionKey> encryption_key);
|
explicit KeySource(scoped_ptr<EncryptionKey> encryption_key);
|
||||||
|
|
|
@ -38,8 +38,8 @@ class MediaParser {
|
||||||
/// @param media_sample is the new media sample.
|
/// @param media_sample is the new media sample.
|
||||||
/// @return true if the sample is accepted, false if something was wrong
|
/// @return true if the sample is accepted, false if something was wrong
|
||||||
/// with the sample and a parsing error should be signaled.
|
/// with the sample and a parsing error should be signaled.
|
||||||
typedef base::Callback<
|
typedef base::Callback<bool(uint32_t track_id,
|
||||||
bool(uint32 track_id, const scoped_refptr<MediaSample>& media_sample)>
|
const scoped_refptr<MediaSample>& media_sample)>
|
||||||
NewSampleCB;
|
NewSampleCB;
|
||||||
|
|
||||||
/// Initialize the parser with necessary callbacks. Must be called before any
|
/// Initialize the parser with necessary callbacks. Must be called before any
|
||||||
|
@ -59,7 +59,7 @@ class MediaParser {
|
||||||
|
|
||||||
/// Should be called when there is new data to parse.
|
/// Should be called when there is new data to parse.
|
||||||
/// @return true if successful.
|
/// @return true if successful.
|
||||||
virtual bool Parse(const uint8* buf, int size) = 0;
|
virtual bool Parse(const uint8_t* buf, int size) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_COPY_AND_ASSIGN(MediaParser);
|
DISALLOW_COPY_AND_ASSIGN(MediaParser);
|
||||||
|
|
|
@ -14,9 +14,9 @@
|
||||||
namespace edash_packager {
|
namespace edash_packager {
|
||||||
namespace media {
|
namespace media {
|
||||||
|
|
||||||
MediaSample::MediaSample(const uint8* data,
|
MediaSample::MediaSample(const uint8_t* data,
|
||||||
size_t size,
|
size_t size,
|
||||||
const uint8* side_data,
|
const uint8_t* side_data,
|
||||||
size_t side_data_size,
|
size_t side_data_size,
|
||||||
bool is_key_frame)
|
bool is_key_frame)
|
||||||
: dts_(0), pts_(0), duration_(0), is_key_frame_(is_key_frame) {
|
: dts_(0), pts_(0), duration_(0), is_key_frame_(is_key_frame) {
|
||||||
|
@ -38,7 +38,7 @@ MediaSample::MediaSample() : dts_(0), pts_(0),
|
||||||
MediaSample::~MediaSample() {}
|
MediaSample::~MediaSample() {}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
scoped_refptr<MediaSample> MediaSample::CopyFrom(const uint8* data,
|
scoped_refptr<MediaSample> MediaSample::CopyFrom(const uint8_t* data,
|
||||||
size_t data_size,
|
size_t data_size,
|
||||||
bool is_key_frame) {
|
bool is_key_frame) {
|
||||||
// If you hit this CHECK you likely have a bug in a demuxer. Go fix it.
|
// If you hit this CHECK you likely have a bug in a demuxer. Go fix it.
|
||||||
|
@ -48,9 +48,9 @@ scoped_refptr<MediaSample> MediaSample::CopyFrom(const uint8* data,
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
scoped_refptr<MediaSample> MediaSample::CopyFrom(const uint8* data,
|
scoped_refptr<MediaSample> MediaSample::CopyFrom(const uint8_t* data,
|
||||||
size_t data_size,
|
size_t data_size,
|
||||||
const uint8* side_data,
|
const uint8_t* side_data,
|
||||||
size_t side_data_size,
|
size_t side_data_size,
|
||||||
bool is_key_frame) {
|
bool is_key_frame) {
|
||||||
// If you hit this CHECK you likely have a bug in a demuxer. Go fix it.
|
// If you hit this CHECK you likely have a bug in a demuxer. Go fix it.
|
||||||
|
|
|
@ -26,7 +26,7 @@ class MediaSample : public base::RefCountedThreadSafe<MediaSample> {
|
||||||
/// Must not be NULL.
|
/// Must not be NULL.
|
||||||
/// @param size indicates sample size in bytes. Must not be negative.
|
/// @param size indicates sample size in bytes. Must not be negative.
|
||||||
/// @param is_key_frame indicates whether the sample is a key frame.
|
/// @param is_key_frame indicates whether the sample is a key frame.
|
||||||
static scoped_refptr<MediaSample> CopyFrom(const uint8* data,
|
static scoped_refptr<MediaSample> CopyFrom(const uint8_t* data,
|
||||||
size_t size,
|
size_t size,
|
||||||
bool is_key_frame);
|
bool is_key_frame);
|
||||||
|
|
||||||
|
@ -40,9 +40,9 @@ class MediaSample : public base::RefCountedThreadSafe<MediaSample> {
|
||||||
/// @param side_data_size indicates additional sample data size in bytes.
|
/// @param side_data_size indicates additional sample data size in bytes.
|
||||||
/// Must not be negative.
|
/// Must not be negative.
|
||||||
/// @param is_key_frame indicates whether the sample is a key frame.
|
/// @param is_key_frame indicates whether the sample is a key frame.
|
||||||
static scoped_refptr<MediaSample> CopyFrom(const uint8* data,
|
static scoped_refptr<MediaSample> CopyFrom(const uint8_t* data,
|
||||||
size_t size,
|
size_t size,
|
||||||
const uint8* side_data,
|
const uint8_t* side_data,
|
||||||
size_t side_data_size,
|
size_t side_data_size,
|
||||||
bool is_key_frame);
|
bool is_key_frame);
|
||||||
|
|
||||||
|
@ -54,30 +54,26 @@ class MediaSample : public base::RefCountedThreadSafe<MediaSample> {
|
||||||
/// is disallowed.
|
/// is disallowed.
|
||||||
static scoped_refptr<MediaSample> CreateEOSBuffer();
|
static scoped_refptr<MediaSample> CreateEOSBuffer();
|
||||||
|
|
||||||
int64 dts() const {
|
int64_t dts() const {
|
||||||
DCHECK(!end_of_stream());
|
DCHECK(!end_of_stream());
|
||||||
return dts_;
|
return dts_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_dts(int64 dts) {
|
void set_dts(int64_t dts) { dts_ = dts; }
|
||||||
dts_ = dts;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64 pts() const {
|
int64_t pts() const {
|
||||||
DCHECK(!end_of_stream());
|
DCHECK(!end_of_stream());
|
||||||
return pts_;
|
return pts_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_pts(int64 pts) {
|
void set_pts(int64_t pts) { pts_ = pts; }
|
||||||
pts_ = pts;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64 duration() const {
|
int64_t duration() const {
|
||||||
DCHECK(!end_of_stream());
|
DCHECK(!end_of_stream());
|
||||||
return duration_;
|
return duration_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_duration(int64 duration) {
|
void set_duration(int64_t duration) {
|
||||||
DCHECK(!end_of_stream());
|
DCHECK(!end_of_stream());
|
||||||
duration_ = duration;
|
duration_ = duration;
|
||||||
}
|
}
|
||||||
|
@ -87,12 +83,12 @@ class MediaSample : public base::RefCountedThreadSafe<MediaSample> {
|
||||||
return is_key_frame_;
|
return is_key_frame_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8* data() const {
|
const uint8_t* data() const {
|
||||||
DCHECK(!end_of_stream());
|
DCHECK(!end_of_stream());
|
||||||
return &data_[0];
|
return &data_[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8* writable_data() {
|
uint8_t* writable_data() {
|
||||||
DCHECK(!end_of_stream());
|
DCHECK(!end_of_stream());
|
||||||
return &data_[0];
|
return &data_[0];
|
||||||
}
|
}
|
||||||
|
@ -102,7 +98,7 @@ class MediaSample : public base::RefCountedThreadSafe<MediaSample> {
|
||||||
return data_.size();
|
return data_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8* side_data() const {
|
const uint8_t* side_data() const {
|
||||||
DCHECK(!end_of_stream());
|
DCHECK(!end_of_stream());
|
||||||
return &side_data_[0];
|
return &side_data_[0];
|
||||||
}
|
}
|
||||||
|
@ -112,7 +108,7 @@ class MediaSample : public base::RefCountedThreadSafe<MediaSample> {
|
||||||
return side_data_.size();
|
return side_data_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_data(const uint8* data, const size_t data_size) {
|
void set_data(const uint8_t* data, const size_t data_size) {
|
||||||
data_.assign(data, data + data_size);
|
data_.assign(data, data + data_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,27 +128,27 @@ class MediaSample : public base::RefCountedThreadSafe<MediaSample> {
|
||||||
// Create a MediaSample. Buffer will be padded and aligned as necessary.
|
// Create a MediaSample. Buffer will be padded and aligned as necessary.
|
||||||
// |data|,|side_data| can be NULL, which indicates an empty sample.
|
// |data|,|side_data| can be NULL, which indicates an empty sample.
|
||||||
// |size|,|side_data_size| should not be negative.
|
// |size|,|side_data_size| should not be negative.
|
||||||
MediaSample(const uint8* data,
|
MediaSample(const uint8_t* data,
|
||||||
size_t size,
|
size_t size,
|
||||||
const uint8* side_data,
|
const uint8_t* side_data,
|
||||||
size_t side_data_size,
|
size_t side_data_size,
|
||||||
bool is_key_frame);
|
bool is_key_frame);
|
||||||
MediaSample();
|
MediaSample();
|
||||||
virtual ~MediaSample();
|
virtual ~MediaSample();
|
||||||
|
|
||||||
// Decoding time stamp.
|
// Decoding time stamp.
|
||||||
int64 dts_;
|
int64_t dts_;
|
||||||
// Presentation time stamp.
|
// Presentation time stamp.
|
||||||
int64 pts_;
|
int64_t pts_;
|
||||||
int64 duration_;
|
int64_t duration_;
|
||||||
bool is_key_frame_;
|
bool is_key_frame_;
|
||||||
|
|
||||||
// Main buffer data.
|
// Main buffer data.
|
||||||
std::vector<uint8> data_;
|
std::vector<uint8_t> data_;
|
||||||
// Contain additional buffers to complete the main one. Needed by WebM
|
// Contain additional buffers to complete the main one. Needed by WebM
|
||||||
// http://www.matroska.org/technical/specs/index.html BlockAdditional[A5].
|
// http://www.matroska.org/technical/specs/index.html BlockAdditional[A5].
|
||||||
// Not used by mp4 and other containers.
|
// Not used by mp4 and other containers.
|
||||||
std::vector<uint8> side_data_;
|
std::vector<uint8_t> side_data_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(MediaSample);
|
DISALLOW_COPY_AND_ASSIGN(MediaSample);
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,7 +25,7 @@ Muxer::Muxer(const MuxerOptions& options)
|
||||||
Muxer::~Muxer() {}
|
Muxer::~Muxer() {}
|
||||||
|
|
||||||
void Muxer::SetKeySource(KeySource* encryption_key_source,
|
void Muxer::SetKeySource(KeySource* encryption_key_source,
|
||||||
uint32 max_sd_pixels,
|
uint32_t max_sd_pixels,
|
||||||
double clear_lead_in_seconds,
|
double clear_lead_in_seconds,
|
||||||
double crypto_period_duration_in_seconds) {
|
double crypto_period_duration_in_seconds) {
|
||||||
DCHECK(encryption_key_source);
|
DCHECK(encryption_key_source);
|
||||||
|
@ -54,7 +54,7 @@ Status Muxer::Run() {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 current_stream_id = 0;
|
uint32_t current_stream_id = 0;
|
||||||
while (status.ok()) {
|
while (status.ok()) {
|
||||||
scoped_refptr<MediaSample> sample;
|
scoped_refptr<MediaSample> sample;
|
||||||
status = streams_[current_stream_id]->PullSample(&sample);
|
status = streams_[current_stream_id]->PullSample(&sample);
|
||||||
|
|
|
@ -47,7 +47,7 @@ class Muxer {
|
||||||
/// in seconds. A positive value means key rotation is enabled, the
|
/// in seconds. A positive value means key rotation is enabled, the
|
||||||
/// key source must support key rotation in this case.
|
/// key source must support key rotation in this case.
|
||||||
void SetKeySource(KeySource* encryption_key_source,
|
void SetKeySource(KeySource* encryption_key_source,
|
||||||
uint32 max_sd_pixels,
|
uint32_t max_sd_pixels,
|
||||||
double clear_lead_in_seconds,
|
double clear_lead_in_seconds,
|
||||||
double crypto_period_duration_in_seconds);
|
double crypto_period_duration_in_seconds);
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ class Muxer {
|
||||||
KeySource* encryption_key_source() {
|
KeySource* encryption_key_source() {
|
||||||
return encryption_key_source_;
|
return encryption_key_source_;
|
||||||
}
|
}
|
||||||
uint32 max_sd_pixels() const { return max_sd_pixels_; }
|
uint32_t max_sd_pixels() const { return max_sd_pixels_; }
|
||||||
double clear_lead_in_seconds() const { return clear_lead_in_seconds_; }
|
double clear_lead_in_seconds() const { return clear_lead_in_seconds_; }
|
||||||
double crypto_period_duration_in_seconds() const {
|
double crypto_period_duration_in_seconds() const {
|
||||||
return crypto_period_duration_in_seconds_;
|
return crypto_period_duration_in_seconds_;
|
||||||
|
@ -107,7 +107,7 @@ class Muxer {
|
||||||
bool initialized_;
|
bool initialized_;
|
||||||
std::vector<MediaStream*> streams_;
|
std::vector<MediaStream*> streams_;
|
||||||
KeySource* encryption_key_source_;
|
KeySource* encryption_key_source_;
|
||||||
uint32 max_sd_pixels_;
|
uint32_t max_sd_pixels_;
|
||||||
double clear_lead_in_seconds_;
|
double clear_lead_in_seconds_;
|
||||||
double crypto_period_duration_in_seconds_;
|
double crypto_period_duration_in_seconds_;
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ struct MuxerOptions {
|
||||||
|
|
||||||
/// User-specified bit rate for the media stream. If zero, the muxer will
|
/// User-specified bit rate for the media stream. If zero, the muxer will
|
||||||
/// attempt to estimate.
|
/// attempt to estimate.
|
||||||
uint32 bandwidth;
|
uint32_t bandwidth;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace media
|
} // namespace media
|
||||||
|
|
|
@ -99,9 +99,9 @@ bool ValidateSegmentTemplate(const std::string& segment_template) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetSegmentName(const std::string& segment_template,
|
std::string GetSegmentName(const std::string& segment_template,
|
||||||
uint64 segment_start_time,
|
uint64_t segment_start_time,
|
||||||
uint32 segment_index,
|
uint32_t segment_index,
|
||||||
uint32 bandwidth) {
|
uint32_t bandwidth) {
|
||||||
DCHECK(ValidateSegmentTemplate(segment_template));
|
DCHECK(ValidateSegmentTemplate(segment_template));
|
||||||
|
|
||||||
std::vector<std::string> splits;
|
std::vector<std::string> splits;
|
||||||
|
@ -131,23 +131,23 @@ std::string GetSegmentName(const std::string& segment_template,
|
||||||
if (format_pos != std::string::npos) {
|
if (format_pos != std::string::npos) {
|
||||||
format_tag = splits[i].substr(format_pos);
|
format_tag = splits[i].substr(format_pos);
|
||||||
DCHECK(ValidateFormatTag(format_tag));
|
DCHECK(ValidateFormatTag(format_tag));
|
||||||
// Replace %d formatting to correctly format uint64.
|
// Replace %d formatting to correctly format uint64_t.
|
||||||
format_tag = format_tag.substr(0, format_tag.size() - 1) + PRIu64;
|
format_tag = format_tag.substr(0, format_tag.size() - 1) + PRIu64;
|
||||||
} else {
|
} else {
|
||||||
// Default format tag "%01d", modified to format uint64 correctly.
|
// Default format tag "%01d", modified to format uint64_t correctly.
|
||||||
format_tag = "%01" PRIu64;
|
format_tag = "%01" PRIu64;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (identifier == "Number") {
|
if (identifier == "Number") {
|
||||||
// SegmentNumber starts from 1.
|
// SegmentNumber starts from 1.
|
||||||
segment_name += base::StringPrintf(
|
segment_name += base::StringPrintf(
|
||||||
format_tag.c_str(), static_cast<uint64>(segment_index + 1));
|
format_tag.c_str(), static_cast<uint64_t>(segment_index + 1));
|
||||||
} else if (identifier == "Time") {
|
} else if (identifier == "Time") {
|
||||||
segment_name +=
|
segment_name +=
|
||||||
base::StringPrintf(format_tag.c_str(), segment_start_time);
|
base::StringPrintf(format_tag.c_str(), segment_start_time);
|
||||||
} else if (identifier == "Bandwidth") {
|
} else if (identifier == "Bandwidth") {
|
||||||
segment_name += base::StringPrintf(
|
segment_name += base::StringPrintf(format_tag.c_str(),
|
||||||
format_tag.c_str(), static_cast<uint64>(bandwidth));
|
static_cast<uint64_t>(bandwidth));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return segment_name;
|
return segment_name;
|
||||||
|
|
|
@ -31,9 +31,9 @@ bool ValidateSegmentTemplate(const std::string& segment_template);
|
||||||
/// @param bandwidth represents the bit rate, in bits/sec, of the stream.
|
/// @param bandwidth represents the bit rate, in bits/sec, of the stream.
|
||||||
/// @return The segment name with identifier substituted.
|
/// @return The segment name with identifier substituted.
|
||||||
std::string GetSegmentName(const std::string& segment_template,
|
std::string GetSegmentName(const std::string& segment_template,
|
||||||
uint64 segment_start_time,
|
uint64_t segment_start_time,
|
||||||
uint32 segment_index,
|
uint32_t segment_index,
|
||||||
uint32 bandwidth);
|
uint32_t bandwidth);
|
||||||
|
|
||||||
} // namespace media
|
} // namespace media
|
||||||
} // namespace edash_packager
|
} // namespace edash_packager
|
||||||
|
|
|
@ -61,9 +61,9 @@ TEST(MuxerUtilTest, ValidateSegmentTemplateWithFormatTag) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MuxerUtilTest, GetSegmentName) {
|
TEST(MuxerUtilTest, GetSegmentName) {
|
||||||
const uint64 kSegmentStartTime = 180180;
|
const uint64_t kSegmentStartTime = 180180;
|
||||||
const uint32 kSegmentIndex = 11;
|
const uint32_t kSegmentIndex = 11;
|
||||||
const uint32 kBandwidth = 1234;
|
const uint32_t kBandwidth = 1234;
|
||||||
EXPECT_EQ("12", GetSegmentName("$Number$",
|
EXPECT_EQ("12", GetSegmentName("$Number$",
|
||||||
kSegmentStartTime,
|
kSegmentStartTime,
|
||||||
kSegmentIndex,
|
kSegmentIndex,
|
||||||
|
@ -118,9 +118,9 @@ TEST(MuxerUtilTest, GetSegmentName) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MuxerUtilTest, GetSegmentNameWithIndexZero) {
|
TEST(MuxerUtilTest, GetSegmentNameWithIndexZero) {
|
||||||
const uint64 kSegmentStartTime = 0;
|
const uint64_t kSegmentStartTime = 0;
|
||||||
const uint32 kSegmentIndex = 0;
|
const uint32_t kSegmentIndex = 0;
|
||||||
const uint32 kBandwidth = 0;
|
const uint32_t kBandwidth = 0;
|
||||||
EXPECT_EQ("1", GetSegmentName("$Number$",
|
EXPECT_EQ("1", GetSegmentName("$Number$",
|
||||||
kSegmentStartTime,
|
kSegmentStartTime,
|
||||||
kSegmentIndex,
|
kSegmentIndex,
|
||||||
|
@ -143,9 +143,9 @@ TEST(MuxerUtilTest, GetSegmentNameWithIndexZero) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(MuxerUtilTest, GetSegmentNameLargeTime) {
|
TEST(MuxerUtilTest, GetSegmentNameLargeTime) {
|
||||||
const uint64 kSegmentStartTime = 1601599839840ULL;
|
const uint64_t kSegmentStartTime = 1601599839840ULL;
|
||||||
const uint32 kSegmentIndex = 8888888;
|
const uint32_t kSegmentIndex = 8888888;
|
||||||
const uint32 kBandwidth = 444444;
|
const uint32_t kBandwidth = 444444;
|
||||||
EXPECT_EQ("1601599839840",
|
EXPECT_EQ("1601599839840",
|
||||||
GetSegmentName("$Time$",
|
GetSegmentName("$Time$",
|
||||||
kSegmentStartTime,
|
kSegmentStartTime,
|
||||||
|
|
|
@ -7,24 +7,24 @@
|
||||||
namespace edash_packager {
|
namespace edash_packager {
|
||||||
namespace media {
|
namespace media {
|
||||||
|
|
||||||
uint32
|
uint32_t ntohlFromBuffer(const unsigned char* buf) {
|
||||||
ntohlFromBuffer(const unsigned char * buf) {
|
return (static_cast<uint32_t>(buf[0]) << 24) |
|
||||||
return (static_cast<uint32>(buf[0])<<24) | (static_cast<uint32>(buf[1])<<16)
|
(static_cast<uint32_t>(buf[1]) << 16) |
|
||||||
| (static_cast<uint32>(buf[2])<<8) | (static_cast<uint32>(buf[3]));
|
(static_cast<uint32_t>(buf[2]) << 8) | (static_cast<uint32_t>(buf[3]));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16
|
uint16_t ntohsFromBuffer(const unsigned char* buf) {
|
||||||
ntohsFromBuffer( const unsigned char * buf) {
|
return (static_cast<uint16_t>(buf[0]) << 8) | (static_cast<uint16_t>(buf[1]));
|
||||||
return (static_cast<uint16>(buf[0])<<8) | (static_cast<uint16>(buf[1]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64
|
uint64_t ntohllFromBuffer(const unsigned char* buf) {
|
||||||
ntohllFromBuffer( const unsigned char * buf ) {
|
return (static_cast<uint64_t>(buf[0]) << 56) |
|
||||||
return (static_cast<uint64>(buf[0])<<56)| (static_cast<uint64>(buf[1])<<48)
|
(static_cast<uint64_t>(buf[1]) << 48) |
|
||||||
| (static_cast<uint64>(buf[2])<<40)| (static_cast<uint64>(buf[3])<<32)
|
(static_cast<uint64_t>(buf[2]) << 40) |
|
||||||
| (static_cast<uint64>(buf[4])<<24)| (static_cast<uint64>(buf[5])<<16)
|
(static_cast<uint64_t>(buf[3]) << 32) |
|
||||||
| (static_cast<uint64>(buf[6])<<8) | (static_cast<uint64>(buf[7]));
|
(static_cast<uint64_t>(buf[4]) << 24) |
|
||||||
|
(static_cast<uint64_t>(buf[5]) << 16) |
|
||||||
|
(static_cast<uint64_t>(buf[6]) << 8) | (static_cast<uint64_t>(buf[7]));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace media
|
} // namespace media
|
||||||
|
|
|
@ -11,9 +11,9 @@
|
||||||
namespace edash_packager {
|
namespace edash_packager {
|
||||||
namespace media {
|
namespace media {
|
||||||
|
|
||||||
uint32 ntohlFromBuffer(const unsigned char * buf);
|
uint32_t ntohlFromBuffer(const unsigned char* buf);
|
||||||
uint16 ntohsFromBuffer(const unsigned char * buf);
|
uint16_t ntohsFromBuffer(const unsigned char* buf);
|
||||||
uint64 ntohllFromBuffer(const unsigned char * buf);
|
uint64_t ntohllFromBuffer(const unsigned char* buf);
|
||||||
|
|
||||||
} // namespace media
|
} // namespace media
|
||||||
} // namespace edash_packager
|
} // namespace edash_packager
|
||||||
|
|
|
@ -20,13 +20,13 @@ void OffsetByteQueue::Reset() {
|
||||||
head_ = 0;
|
head_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffsetByteQueue::Push(const uint8* buf, int size) {
|
void OffsetByteQueue::Push(const uint8_t* buf, int size) {
|
||||||
queue_.Push(buf, size);
|
queue_.Push(buf, size);
|
||||||
Sync();
|
Sync();
|
||||||
DVLOG(4) << "Buffer pushed. head=" << head() << " tail=" << tail();
|
DVLOG(4) << "Buffer pushed. head=" << head() << " tail=" << tail();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffsetByteQueue::Peek(const uint8** buf, int* size) {
|
void OffsetByteQueue::Peek(const uint8_t** buf, int* size) {
|
||||||
*buf = size_ > 0 ? buf_ : NULL;
|
*buf = size_ > 0 ? buf_ : NULL;
|
||||||
*size = size_;
|
*size = size_;
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ void OffsetByteQueue::Pop(int count) {
|
||||||
Sync();
|
Sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffsetByteQueue::PeekAt(int64 offset, const uint8** buf, int* size) {
|
void OffsetByteQueue::PeekAt(int64_t offset, const uint8_t** buf, int* size) {
|
||||||
DCHECK(offset >= head());
|
DCHECK(offset >= head());
|
||||||
if (offset < head() || offset >= tail()) {
|
if (offset < head() || offset >= tail()) {
|
||||||
*buf = NULL;
|
*buf = NULL;
|
||||||
|
@ -48,7 +48,7 @@ void OffsetByteQueue::PeekAt(int64 offset, const uint8** buf, int* size) {
|
||||||
*size = tail() - offset;
|
*size = tail() - offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OffsetByteQueue::Trim(int64 max_offset) {
|
bool OffsetByteQueue::Trim(int64_t max_offset) {
|
||||||
if (max_offset < head_) return true;
|
if (max_offset < head_) return true;
|
||||||
if (max_offset > tail()) {
|
if (max_offset > tail()) {
|
||||||
Pop(size_);
|
Pop(size_);
|
||||||
|
|
|
@ -23,8 +23,8 @@ class OffsetByteQueue {
|
||||||
/// @name These work like their underlying ByteQueue counterparts.
|
/// @name These work like their underlying ByteQueue counterparts.
|
||||||
/// @{
|
/// @{
|
||||||
void Reset();
|
void Reset();
|
||||||
void Push(const uint8* buf, int size);
|
void Push(const uint8_t* buf, int size);
|
||||||
void Peek(const uint8** buf, int* size);
|
void Peek(const uint8_t** buf, int* size);
|
||||||
void Pop(int count);
|
void Pop(int count);
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ class OffsetByteQueue {
|
||||||
/// It is an error if the offset is before the current head. It's not an error
|
/// It is an error if the offset is before the current head. It's not an error
|
||||||
/// if the current offset is beyond tail(), but you will of course get back
|
/// if the current offset is beyond tail(), but you will of course get back
|
||||||
/// a null @a buf and a @a size of zero.
|
/// a null @a buf and a @a size of zero.
|
||||||
void PeekAt(int64 offset, const uint8** buf, int* size);
|
void PeekAt(int64_t offset, const uint8_t** buf, int* size);
|
||||||
|
|
||||||
/// Mark the bytes up to (but not including) @a max_offset as ready for
|
/// Mark the bytes up to (but not including) @a max_offset as ready for
|
||||||
/// deletion. This is relatively inexpensive, but will not necessarily reduce
|
/// deletion. This is relatively inexpensive, but will not necessarily reduce
|
||||||
|
@ -45,22 +45,22 @@ class OffsetByteQueue {
|
||||||
/// head.
|
/// head.
|
||||||
/// @return false if @a max_offset > tail() (although all bytes currently
|
/// @return false if @a max_offset > tail() (although all bytes currently
|
||||||
/// buffered are still cleared).
|
/// buffered are still cleared).
|
||||||
bool Trim(int64 max_offset);
|
bool Trim(int64_t max_offset);
|
||||||
|
|
||||||
/// @return The head position, in terms of the file's absolute offset.
|
/// @return The head position, in terms of the file's absolute offset.
|
||||||
int64 head() { return head_; }
|
int64_t head() { return head_; }
|
||||||
/// @return The tail position (exclusive), in terms of the file's absolute
|
/// @return The tail position (exclusive), in terms of the file's absolute
|
||||||
/// offset.
|
/// offset.
|
||||||
int64 tail() { return head_ + size_; }
|
int64_t tail() { return head_ + size_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Synchronize |buf_| and |size_| with |queue_|.
|
// Synchronize |buf_| and |size_| with |queue_|.
|
||||||
void Sync();
|
void Sync();
|
||||||
|
|
||||||
ByteQueue queue_;
|
ByteQueue queue_;
|
||||||
const uint8* buf_;
|
const uint8_t* buf_;
|
||||||
int size_;
|
int size_;
|
||||||
int64 head_;
|
int64_t head_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(OffsetByteQueue);
|
DISALLOW_COPY_AND_ASSIGN(OffsetByteQueue);
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace media {
|
||||||
class OffsetByteQueueTest : public testing::Test {
|
class OffsetByteQueueTest : public testing::Test {
|
||||||
public:
|
public:
|
||||||
virtual void SetUp() OVERRIDE {
|
virtual void SetUp() OVERRIDE {
|
||||||
uint8 buf[256];
|
uint8_t buf[256];
|
||||||
for (int i = 0; i < 256; i++) {
|
for (int i = 0; i < 256; i++) {
|
||||||
buf[i] = i;
|
buf[i] = i;
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ TEST_F(OffsetByteQueueTest, SetUp) {
|
||||||
EXPECT_EQ(384, queue_->head());
|
EXPECT_EQ(384, queue_->head());
|
||||||
EXPECT_EQ(512, queue_->tail());
|
EXPECT_EQ(512, queue_->tail());
|
||||||
|
|
||||||
const uint8* buf;
|
const uint8_t* buf;
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
queue_->Peek(&buf, &size);
|
queue_->Peek(&buf, &size);
|
||||||
|
@ -46,7 +46,7 @@ TEST_F(OffsetByteQueueTest, SetUp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(OffsetByteQueueTest, PeekAt) {
|
TEST_F(OffsetByteQueueTest, PeekAt) {
|
||||||
const uint8* buf;
|
const uint8_t* buf;
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
queue_->PeekAt(400, &buf, &size);
|
queue_->PeekAt(400, &buf, &size);
|
||||||
|
@ -68,7 +68,7 @@ TEST_F(OffsetByteQueueTest, Trim) {
|
||||||
EXPECT_EQ(400, queue_->head());
|
EXPECT_EQ(400, queue_->head());
|
||||||
EXPECT_EQ(512, queue_->tail());
|
EXPECT_EQ(512, queue_->tail());
|
||||||
|
|
||||||
const uint8* buf;
|
const uint8_t* buf;
|
||||||
int size;
|
int size;
|
||||||
queue_->PeekAt(400, &buf, &size);
|
queue_->PeekAt(400, &buf, &size);
|
||||||
EXPECT_EQ(queue_->tail() - 400, size);
|
EXPECT_EQ(queue_->tail() - 400, size);
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace edash_packager {
|
||||||
namespace media {
|
namespace media {
|
||||||
|
|
||||||
static const size_t kUnlimitedCapacity = 0u;
|
static const size_t kUnlimitedCapacity = 0u;
|
||||||
static const int64 kInfiniteTimeout = -1;
|
static const int64_t kInfiniteTimeout = -1;
|
||||||
|
|
||||||
/// A thread safe producer consumer queue implementation. It allows the standard
|
/// A thread safe producer consumer queue implementation. It allows the standard
|
||||||
/// push and pop operations. It also maintains a monotonically-increasing
|
/// push and pop operations. It also maintains a monotonically-increasing
|
||||||
|
@ -48,7 +48,7 @@ class ProducerConsumerQueue {
|
||||||
/// return immediately. A negative value means waiting indefinitely.
|
/// return immediately. A negative value means waiting indefinitely.
|
||||||
/// @return OK if the element was pushed successfully, STOPPED if Stop has
|
/// @return OK if the element was pushed successfully, STOPPED if Stop has
|
||||||
/// has been called, TIME_OUT if times out.
|
/// has been called, TIME_OUT if times out.
|
||||||
Status Push(const T& element, int64 timeout_ms);
|
Status Push(const T& element, int64_t timeout_ms);
|
||||||
|
|
||||||
/// Pop an element from the front of the queue. If the queue is empty, block
|
/// Pop an element from the front of the queue. If the queue is empty, block
|
||||||
/// for an element to be available to be consumed or time out or stopped.
|
/// for an element to be available to be consumed or time out or stopped.
|
||||||
|
@ -57,7 +57,7 @@ class ProducerConsumerQueue {
|
||||||
/// return immediately. A negative value means waiting indefinitely.
|
/// return immediately. A negative value means waiting indefinitely.
|
||||||
/// @return STOPPED if Stop has been called and the queue is completely empty,
|
/// @return STOPPED if Stop has been called and the queue is completely empty,
|
||||||
/// TIME_OUT if times out, OK otherwise.
|
/// TIME_OUT if times out, OK otherwise.
|
||||||
Status Pop(T* element, int64 timeout_ms);
|
Status Pop(T* element, int64_t timeout_ms);
|
||||||
|
|
||||||
/// Peek at the element at the specified position from the queue. If the
|
/// Peek at the element at the specified position from the queue. If the
|
||||||
/// element is not available yet, block until it to be available or time out
|
/// element is not available yet, block until it to be available or time out
|
||||||
|
@ -71,7 +71,7 @@ class ProducerConsumerQueue {
|
||||||
/// @return STOPPED if Stop has been called and @a pos is out of range,
|
/// @return STOPPED if Stop has been called and @a pos is out of range,
|
||||||
/// INVALID_ARGUMENT if the pos < Head(), TIME_OUT if times out,
|
/// INVALID_ARGUMENT if the pos < Head(), TIME_OUT if times out,
|
||||||
/// OK otherwise.
|
/// OK otherwise.
|
||||||
Status Peek(size_t pos, T* element, int64 timeout_ms);
|
Status Peek(size_t pos, T* element, int64_t timeout_ms);
|
||||||
|
|
||||||
/// Terminate Pop and Peek requests once the queue drains entirely.
|
/// Terminate Pop and Peek requests once the queue drains entirely.
|
||||||
/// Also terminate all waiting and future Push requests immediately.
|
/// Also terminate all waiting and future Push requests immediately.
|
||||||
|
@ -158,7 +158,7 @@ template <class T>
|
||||||
ProducerConsumerQueue<T>::~ProducerConsumerQueue() {}
|
ProducerConsumerQueue<T>::~ProducerConsumerQueue() {}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
Status ProducerConsumerQueue<T>::Push(const T& element, int64 timeout_ms) {
|
Status ProducerConsumerQueue<T>::Push(const T& element, int64_t timeout_ms) {
|
||||||
base::AutoLock l(lock_);
|
base::AutoLock l(lock_);
|
||||||
bool woken = false;
|
bool woken = false;
|
||||||
|
|
||||||
|
@ -207,7 +207,7 @@ Status ProducerConsumerQueue<T>::Push(const T& element, int64 timeout_ms) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
Status ProducerConsumerQueue<T>::Pop(T* element, int64 timeout_ms) {
|
Status ProducerConsumerQueue<T>::Pop(T* element, int64_t timeout_ms) {
|
||||||
base::AutoLock l(lock_);
|
base::AutoLock l(lock_);
|
||||||
bool woken = false;
|
bool woken = false;
|
||||||
|
|
||||||
|
@ -251,7 +251,7 @@ Status ProducerConsumerQueue<T>::Pop(T* element, int64 timeout_ms) {
|
||||||
template <class T>
|
template <class T>
|
||||||
Status ProducerConsumerQueue<T>::Peek(size_t pos,
|
Status ProducerConsumerQueue<T>::Peek(size_t pos,
|
||||||
T* element,
|
T* element,
|
||||||
int64 timeout_ms) {
|
int64_t timeout_ms) {
|
||||||
base::AutoLock l(lock_);
|
base::AutoLock l(lock_);
|
||||||
if (pos < head_pos_) {
|
if (pos < head_pos_) {
|
||||||
return Status(
|
return Status(
|
||||||
|
|
|
@ -14,12 +14,12 @@
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
const size_t kCapacity = 10u;
|
const size_t kCapacity = 10u;
|
||||||
const int64 kTimeout = 100; // 0.1s.
|
const int64_t kTimeout = 100; // 0.1s.
|
||||||
|
|
||||||
// Check that the |delta| is approximately |time_in_milliseconds|.
|
// Check that the |delta| is approximately |time_in_milliseconds|.
|
||||||
bool CheckTimeApproxEqual(int64 time_in_milliseconds,
|
bool CheckTimeApproxEqual(int64_t time_in_milliseconds,
|
||||||
const base::TimeDelta& delta) {
|
const base::TimeDelta& delta) {
|
||||||
const int64 kOverhead = 10; // 0.01s.
|
const int64_t kOverhead = 10; // 0.01s.
|
||||||
return delta.InMilliseconds() >= time_in_milliseconds &&
|
return delta.InMilliseconds() >= time_in_milliseconds &&
|
||||||
delta.InMilliseconds() <= time_in_milliseconds + kOverhead;
|
delta.InMilliseconds() <= time_in_milliseconds + kOverhead;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,12 +28,12 @@ AesRequestSigner::~AesRequestSigner() {}
|
||||||
AesRequestSigner* AesRequestSigner::CreateSigner(const std::string& signer_name,
|
AesRequestSigner* AesRequestSigner::CreateSigner(const std::string& signer_name,
|
||||||
const std::string& aes_key_hex,
|
const std::string& aes_key_hex,
|
||||||
const std::string& iv_hex) {
|
const std::string& iv_hex) {
|
||||||
std::vector<uint8> aes_key;
|
std::vector<uint8_t> aes_key;
|
||||||
if (!base::HexStringToBytes(aes_key_hex, &aes_key)) {
|
if (!base::HexStringToBytes(aes_key_hex, &aes_key)) {
|
||||||
LOG(ERROR) << "Failed to convert hex string to bytes: " << aes_key_hex;
|
LOG(ERROR) << "Failed to convert hex string to bytes: " << aes_key_hex;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
std::vector<uint8> iv;
|
std::vector<uint8_t> iv;
|
||||||
if (!base::HexStringToBytes(iv_hex, &iv)) {
|
if (!base::HexStringToBytes(iv_hex, &iv)) {
|
||||||
LOG(ERROR) << "Failed to convert hex string to bytes: " << iv_hex;
|
LOG(ERROR) << "Failed to convert hex string to bytes: " << iv_hex;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -113,8 +113,8 @@ bool RsaPrivateKey::Decrypt(const std::string& encrypted_message,
|
||||||
decrypted_message->resize(rsa_size);
|
decrypted_message->resize(rsa_size);
|
||||||
int decrypted_size = RSA_private_decrypt(
|
int decrypted_size = RSA_private_decrypt(
|
||||||
rsa_size,
|
rsa_size,
|
||||||
reinterpret_cast<const uint8*>(encrypted_message.data()),
|
reinterpret_cast<const uint8_t*>(encrypted_message.data()),
|
||||||
reinterpret_cast<uint8*>(string_as_array(decrypted_message)),
|
reinterpret_cast<uint8_t*>(string_as_array(decrypted_message)),
|
||||||
rsa_key_,
|
rsa_key_,
|
||||||
RSA_PKCS1_OAEP_PADDING);
|
RSA_PKCS1_OAEP_PADDING);
|
||||||
|
|
||||||
|
@ -139,13 +139,13 @@ bool RsaPrivateKey::GenerateSignature(const std::string& message,
|
||||||
|
|
||||||
// Add PSS padding.
|
// Add PSS padding.
|
||||||
size_t rsa_size = RSA_size(rsa_key_);
|
size_t rsa_size = RSA_size(rsa_key_);
|
||||||
std::vector<uint8> padded_digest(rsa_size);
|
std::vector<uint8_t> padded_digest(rsa_size);
|
||||||
if (!RSA_padding_add_PKCS1_PSS(
|
if (!RSA_padding_add_PKCS1_PSS(
|
||||||
rsa_key_,
|
rsa_key_,
|
||||||
&padded_digest[0],
|
&padded_digest[0],
|
||||||
reinterpret_cast<uint8*>(string_as_array(&message_digest)),
|
reinterpret_cast<uint8_t*>(string_as_array(&message_digest)),
|
||||||
EVP_sha1(),
|
EVP_sha1(),
|
||||||
kPssSaltLength)) {
|
kPssSaltLength)) {
|
||||||
LOG(ERROR) << "RSA padding failure: " << ERR_error_string(ERR_get_error(),
|
LOG(ERROR) << "RSA padding failure: " << ERR_error_string(ERR_get_error(),
|
||||||
NULL);
|
NULL);
|
||||||
return false;
|
return false;
|
||||||
|
@ -153,12 +153,12 @@ bool RsaPrivateKey::GenerateSignature(const std::string& message,
|
||||||
|
|
||||||
// Encrypt PSS padded digest.
|
// Encrypt PSS padded digest.
|
||||||
signature->resize(rsa_size);
|
signature->resize(rsa_size);
|
||||||
int signature_size =
|
int signature_size = RSA_private_encrypt(
|
||||||
RSA_private_encrypt(padded_digest.size(),
|
padded_digest.size(),
|
||||||
&padded_digest[0],
|
&padded_digest[0],
|
||||||
reinterpret_cast<uint8*>(string_as_array(signature)),
|
reinterpret_cast<uint8_t*>(string_as_array(signature)),
|
||||||
rsa_key_,
|
rsa_key_,
|
||||||
RSA_NO_PADDING);
|
RSA_NO_PADDING);
|
||||||
|
|
||||||
if (signature_size != static_cast<int>(rsa_size)) {
|
if (signature_size != static_cast<int>(rsa_size)) {
|
||||||
LOG(ERROR) << "RSA private encrypt failure: " << ERR_error_string(
|
LOG(ERROR) << "RSA private encrypt failure: " << ERR_error_string(
|
||||||
|
@ -193,8 +193,8 @@ bool RsaPublicKey::Encrypt(const std::string& clear_message,
|
||||||
encrypted_message->resize(rsa_size);
|
encrypted_message->resize(rsa_size);
|
||||||
int encrypted_size = RSA_public_encrypt(
|
int encrypted_size = RSA_public_encrypt(
|
||||||
clear_message.size(),
|
clear_message.size(),
|
||||||
reinterpret_cast<const uint8*>(clear_message.data()),
|
reinterpret_cast<const uint8_t*>(clear_message.data()),
|
||||||
reinterpret_cast<uint8*>(string_as_array(encrypted_message)),
|
reinterpret_cast<uint8_t*>(string_as_array(encrypted_message)),
|
||||||
rsa_key_,
|
rsa_key_,
|
||||||
RSA_PKCS1_OAEP_PADDING);
|
RSA_PKCS1_OAEP_PADDING);
|
||||||
|
|
||||||
|
@ -221,10 +221,10 @@ bool RsaPublicKey::VerifySignature(const std::string& message,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decrypt the signature.
|
// Decrypt the signature.
|
||||||
std::vector<uint8> padded_digest(signature.size());
|
std::vector<uint8_t> padded_digest(signature.size());
|
||||||
int decrypted_size =
|
int decrypted_size =
|
||||||
RSA_public_decrypt(signature.size(),
|
RSA_public_decrypt(signature.size(),
|
||||||
reinterpret_cast<const uint8*>(signature.data()),
|
reinterpret_cast<const uint8_t*>(signature.data()),
|
||||||
&padded_digest[0],
|
&padded_digest[0],
|
||||||
rsa_key_,
|
rsa_key_,
|
||||||
RSA_NO_PADDING);
|
RSA_NO_PADDING);
|
||||||
|
@ -240,7 +240,7 @@ bool RsaPublicKey::VerifySignature(const std::string& message,
|
||||||
// Verify PSS padding.
|
// Verify PSS padding.
|
||||||
return RSA_verify_PKCS1_PSS(
|
return RSA_verify_PKCS1_PSS(
|
||||||
rsa_key_,
|
rsa_key_,
|
||||||
reinterpret_cast<const uint8*>(message_digest.data()),
|
reinterpret_cast<const uint8_t*>(message_digest.data()),
|
||||||
EVP_sha1(),
|
EVP_sha1(),
|
||||||
&padded_digest[0],
|
&padded_digest[0],
|
||||||
kPssSaltLength) != 0;
|
kPssSaltLength) != 0;
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include "media/base/rsa_test_data.h"
|
#include "media/base/rsa_test_data.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
const uint8 kTestRsaPrivateKey_3072[] = {
|
const uint8_t kTestRsaPrivateKey_3072[] = {
|
||||||
0x30, 0x82, 0x06, 0xe3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x81, 0x00,
|
0x30, 0x82, 0x06, 0xe3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x81, 0x00,
|
||||||
0xa5, 0x62, 0x07, 0xdf, 0xc8, 0x84, 0x74, 0xe1, 0x2a, 0xb7, 0xbb, 0xc0,
|
0xa5, 0x62, 0x07, 0xdf, 0xc8, 0x84, 0x74, 0xe1, 0x2a, 0xb7, 0xbb, 0xc0,
|
||||||
0x78, 0x76, 0xbe, 0x13, 0x3b, 0xe6, 0x2c, 0x09, 0x9d, 0x35, 0x3f, 0xf3,
|
0x78, 0x76, 0xbe, 0x13, 0x3b, 0xe6, 0x2c, 0x09, 0x9d, 0x35, 0x3f, 0xf3,
|
||||||
|
@ -157,7 +157,7 @@ const uint8 kTestRsaPrivateKey_3072[] = {
|
||||||
0x0f, 0xed, 0x55, 0xb5, 0x49, 0xd6, 0x94, 0x59, 0xee, 0xcc, 0x1b, 0x5a,
|
0x0f, 0xed, 0x55, 0xb5, 0x49, 0xd6, 0x94, 0x59, 0xee, 0xcc, 0x1b, 0x5a,
|
||||||
0x00, 0x3d, 0xcd};
|
0x00, 0x3d, 0xcd};
|
||||||
|
|
||||||
const uint8 kTestRsaPublicKey_3072[] = {
|
const uint8_t kTestRsaPublicKey_3072[] = {
|
||||||
0x30, 0x82, 0x01, 0x8a, 0x02, 0x82, 0x01, 0x81, 0x00, 0xa5, 0x62, 0x07,
|
0x30, 0x82, 0x01, 0x8a, 0x02, 0x82, 0x01, 0x81, 0x00, 0xa5, 0x62, 0x07,
|
||||||
0xdf, 0xc8, 0x84, 0x74, 0xe1, 0x2a, 0xb7, 0xbb, 0xc0, 0x78, 0x76, 0xbe,
|
0xdf, 0xc8, 0x84, 0x74, 0xe1, 0x2a, 0xb7, 0xbb, 0xc0, 0x78, 0x76, 0xbe,
|
||||||
0x13, 0x3b, 0xe6, 0x2c, 0x09, 0x9d, 0x35, 0x3f, 0xf3, 0x0f, 0xe9, 0x61,
|
0x13, 0x3b, 0xe6, 0x2c, 0x09, 0x9d, 0x35, 0x3f, 0xf3, 0x0f, 0xe9, 0x61,
|
||||||
|
@ -193,7 +193,7 @@ const uint8 kTestRsaPublicKey_3072[] = {
|
||||||
0x2e, 0x23, 0x23, 0x60, 0x0b, 0x83, 0x9c, 0xc2, 0x87, 0x02, 0x03, 0x01,
|
0x2e, 0x23, 0x23, 0x60, 0x0b, 0x83, 0x9c, 0xc2, 0x87, 0x02, 0x03, 0x01,
|
||||||
0x00, 0x01};
|
0x00, 0x01};
|
||||||
|
|
||||||
const uint8 kTestRsaPrivateKey_2048[] = {
|
const uint8_t kTestRsaPrivateKey_2048[] = {
|
||||||
0x30, 0x82, 0x04, 0xa2, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00,
|
0x30, 0x82, 0x04, 0xa2, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00,
|
||||||
0xa7, 0x00, 0x36, 0x60, 0x65, 0xdc, 0xbd, 0x54, 0x5a, 0x2a, 0x40, 0xb4,
|
0xa7, 0x00, 0x36, 0x60, 0x65, 0xdc, 0xbd, 0x54, 0x5a, 0x2a, 0x40, 0xb4,
|
||||||
0xe1, 0x15, 0x94, 0x58, 0x11, 0x4f, 0x94, 0x58, 0xdd, 0xde, 0xa7, 0x1f,
|
0xe1, 0x15, 0x94, 0x58, 0x11, 0x4f, 0x94, 0x58, 0xdd, 0xde, 0xa7, 0x1f,
|
||||||
|
@ -295,7 +295,7 @@ const uint8 kTestRsaPrivateKey_2048[] = {
|
||||||
0xf7, 0xc1, 0x22, 0x36, 0xd9, 0x18, 0x56, 0xfe, 0x39, 0x28, 0x33, 0xe0,
|
0xf7, 0xc1, 0x22, 0x36, 0xd9, 0x18, 0x56, 0xfe, 0x39, 0x28, 0x33, 0xe0,
|
||||||
0xdb, 0x03};
|
0xdb, 0x03};
|
||||||
|
|
||||||
const uint8 kTestRsaPublicKey_2048[] = {
|
const uint8_t kTestRsaPublicKey_2048[] = {
|
||||||
0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa7, 0x00, 0x36,
|
0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa7, 0x00, 0x36,
|
||||||
0x60, 0x65, 0xdc, 0xbd, 0x54, 0x5a, 0x2a, 0x40, 0xb4, 0xe1, 0x15, 0x94,
|
0x60, 0x65, 0xdc, 0xbd, 0x54, 0x5a, 0x2a, 0x40, 0xb4, 0xe1, 0x15, 0x94,
|
||||||
0x58, 0x11, 0x4f, 0x94, 0x58, 0xdd, 0xde, 0xa7, 0x1f, 0x3c, 0x2c, 0xe0,
|
0x58, 0x11, 0x4f, 0x94, 0x58, 0xdd, 0xde, 0xa7, 0x1f, 0x3c, 0x2c, 0xe0,
|
||||||
|
@ -324,7 +324,7 @@ const char kTestMessage[] =
|
||||||
"A fool thinks himself to be wise, but a"
|
"A fool thinks himself to be wise, but a"
|
||||||
" wise man knows himself to be a fool.";
|
" wise man knows himself to be a fool.";
|
||||||
|
|
||||||
const uint8 kTestEncryptedMessage_3072[] = {
|
const uint8_t kTestEncryptedMessage_3072[] = {
|
||||||
0x4e, 0x85, 0x01, 0x65, 0x1c, 0xb2, 0xe6, 0x39, 0xb9, 0x6e, 0x93, 0x6a,
|
0x4e, 0x85, 0x01, 0x65, 0x1c, 0xb2, 0xe6, 0x39, 0xb9, 0x6e, 0x93, 0x6a,
|
||||||
0x18, 0xa4, 0xa6, 0xb2, 0x86, 0x3d, 0x8e, 0x23, 0x34, 0x68, 0xa9, 0x74,
|
0x18, 0xa4, 0xa6, 0xb2, 0x86, 0x3d, 0x8e, 0x23, 0x34, 0x68, 0xa9, 0x74,
|
||||||
0x78, 0x0e, 0x6f, 0x94, 0xb3, 0x4f, 0x14, 0xc0, 0x88, 0x0a, 0xec, 0x64,
|
0x78, 0x0e, 0x6f, 0x94, 0xb3, 0x4f, 0x14, 0xc0, 0x88, 0x0a, 0xec, 0x64,
|
||||||
|
@ -359,7 +359,7 @@ const uint8 kTestEncryptedMessage_3072[] = {
|
||||||
0x34, 0xd5, 0x1a, 0x62, 0x9c, 0xb2, 0x9d, 0x8b, 0xe9, 0x49, 0x48, 0x1d};
|
0x34, 0xd5, 0x1a, 0x62, 0x9c, 0xb2, 0x9d, 0x8b, 0xe9, 0x49, 0x48, 0x1d};
|
||||||
|
|
||||||
// Self-generated test vector. Used to verify algorithm stability.
|
// Self-generated test vector. Used to verify algorithm stability.
|
||||||
const uint8 kTestEncryptedMessage_2048[] = {
|
const uint8_t kTestEncryptedMessage_2048[] = {
|
||||||
0x73, 0x37, 0xa5, 0xe3, 0x73, 0xbb, 0xa7, 0xbf, 0xb1, 0xfc, 0x98, 0x6c,
|
0x73, 0x37, 0xa5, 0xe3, 0x73, 0xbb, 0xa7, 0xbf, 0xb1, 0xfc, 0x98, 0x6c,
|
||||||
0xd2, 0x20, 0xe2, 0x79, 0xea, 0x90, 0x41, 0xcf, 0x2b, 0xe0, 0x22, 0x0f,
|
0xd2, 0x20, 0xe2, 0x79, 0xea, 0x90, 0x41, 0xcf, 0x2b, 0xe0, 0x22, 0x0f,
|
||||||
0xe3, 0x6e, 0x2e, 0x61, 0x7d, 0xe5, 0xc7, 0x5a, 0x46, 0x87, 0xed, 0x35,
|
0xe3, 0x6e, 0x2e, 0x61, 0x7d, 0xe5, 0xc7, 0x5a, 0x46, 0x87, 0xed, 0x35,
|
||||||
|
@ -383,7 +383,7 @@ const uint8 kTestEncryptedMessage_2048[] = {
|
||||||
0xee, 0x0e, 0x96, 0xcf, 0xcf, 0xee, 0xfa, 0xf9, 0xcc, 0x73, 0xd5, 0x7c,
|
0xee, 0x0e, 0x96, 0xcf, 0xcf, 0xee, 0xfa, 0xf9, 0xcc, 0x73, 0xd5, 0x7c,
|
||||||
0xf3, 0xbe, 0x9a, 0xb3};
|
0xf3, 0xbe, 0x9a, 0xb3};
|
||||||
|
|
||||||
const uint8 kTestSignature_3072[] = {
|
const uint8_t kTestSignature_3072[] = {
|
||||||
0x80, 0xfd, 0x25, 0x0d, 0x3a, 0xac, 0x37, 0x58, 0x66, 0x62, 0x18, 0xb0,
|
0x80, 0xfd, 0x25, 0x0d, 0x3a, 0xac, 0x37, 0x58, 0x66, 0x62, 0x18, 0xb0,
|
||||||
0x48, 0x0b, 0x24, 0x27, 0x63, 0x54, 0x49, 0x44, 0x9b, 0x80, 0xc3, 0xec,
|
0x48, 0x0b, 0x24, 0x27, 0x63, 0x54, 0x49, 0x44, 0x9b, 0x80, 0xc3, 0xec,
|
||||||
0xb2, 0xec, 0xad, 0xde, 0x1a, 0x19, 0x04, 0xed, 0xe3, 0xbb, 0x51, 0xc4,
|
0xb2, 0xec, 0xad, 0xde, 0x1a, 0x19, 0x04, 0xed, 0xe3, 0xbb, 0x51, 0xc4,
|
||||||
|
@ -417,7 +417,7 @@ const uint8 kTestSignature_3072[] = {
|
||||||
0xdd, 0xa1, 0xd9, 0xe7, 0x03, 0x30, 0x44, 0x3b, 0xbf, 0x51, 0xee, 0x74,
|
0xdd, 0xa1, 0xd9, 0xe7, 0x03, 0x30, 0x44, 0x3b, 0xbf, 0x51, 0xee, 0x74,
|
||||||
0xf3, 0xd6, 0xfe, 0xf4, 0x36, 0x28, 0xf8, 0x35, 0x1a, 0xcd, 0x88, 0xec};
|
0xf3, 0xd6, 0xfe, 0xf4, 0x36, 0x28, 0xf8, 0x35, 0x1a, 0xcd, 0x88, 0xec};
|
||||||
|
|
||||||
const uint8 kTestSignature_2048[] = {
|
const uint8_t kTestSignature_2048[] = {
|
||||||
0x6b, 0x8e, 0x01, 0x11, 0xc3, 0x8e, 0x1a, 0xf7, 0xd1, 0x91, 0x72, 0xe7,
|
0x6b, 0x8e, 0x01, 0x11, 0xc3, 0x8e, 0x1a, 0xf7, 0xd1, 0x91, 0x72, 0xe7,
|
||||||
0xf2, 0x3e, 0x6f, 0xfd, 0x34, 0xfe, 0x11, 0x8f, 0x03, 0xc0, 0x01, 0xa5,
|
0xf2, 0x3e, 0x6f, 0xfd, 0x34, 0xfe, 0x11, 0x8f, 0x03, 0xc0, 0x01, 0xa5,
|
||||||
0x87, 0xbf, 0xab, 0x92, 0x46, 0x4a, 0x33, 0xf6, 0xb1, 0x37, 0xdb, 0x5a,
|
0x87, 0xbf, 0xab, 0x92, 0x46, 0x4a, 0x33, 0xf6, 0xb1, 0x37, 0xdb, 0x5a,
|
||||||
|
|
|
@ -16,11 +16,11 @@ namespace media {
|
||||||
|
|
||||||
StreamInfo::StreamInfo(StreamType stream_type,
|
StreamInfo::StreamInfo(StreamType stream_type,
|
||||||
int track_id,
|
int track_id,
|
||||||
uint32 time_scale,
|
uint32_t time_scale,
|
||||||
uint64 duration,
|
uint64_t duration,
|
||||||
const std::string& codec_string,
|
const std::string& codec_string,
|
||||||
const std::string& language,
|
const std::string& language,
|
||||||
const uint8* extra_data,
|
const uint8_t* extra_data,
|
||||||
size_t extra_data_size,
|
size_t extra_data_size,
|
||||||
bool is_encrypted)
|
bool is_encrypted)
|
||||||
: stream_type_(stream_type),
|
: stream_type_(stream_type),
|
||||||
|
@ -30,7 +30,6 @@ StreamInfo::StreamInfo(StreamType stream_type,
|
||||||
codec_string_(codec_string),
|
codec_string_(codec_string),
|
||||||
language_(language),
|
language_(language),
|
||||||
is_encrypted_(is_encrypted) {
|
is_encrypted_(is_encrypted) {
|
||||||
|
|
||||||
if (extra_data_size > 0) {
|
if (extra_data_size > 0) {
|
||||||
extra_data_.assign(extra_data, extra_data + extra_data_size);
|
extra_data_.assign(extra_data, extra_data + extra_data_size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,11 +26,11 @@ class StreamInfo : public base::RefCountedThreadSafe<StreamInfo> {
|
||||||
public:
|
public:
|
||||||
StreamInfo(StreamType stream_type,
|
StreamInfo(StreamType stream_type,
|
||||||
int track_id,
|
int track_id,
|
||||||
uint32 time_scale,
|
uint32_t time_scale,
|
||||||
uint64 duration,
|
uint64_t duration,
|
||||||
const std::string& codec_string,
|
const std::string& codec_string,
|
||||||
const std::string& language,
|
const std::string& language,
|
||||||
const uint8* extra_data,
|
const uint8_t* extra_data,
|
||||||
size_t extra_data_size,
|
size_t extra_data_size,
|
||||||
bool is_encrypted);
|
bool is_encrypted);
|
||||||
|
|
||||||
|
@ -42,19 +42,19 @@ class StreamInfo : public base::RefCountedThreadSafe<StreamInfo> {
|
||||||
virtual std::string ToString() const;
|
virtual std::string ToString() const;
|
||||||
|
|
||||||
StreamType stream_type() const { return stream_type_; }
|
StreamType stream_type() const { return stream_type_; }
|
||||||
uint32 track_id() const { return track_id_; }
|
uint32_t track_id() const { return track_id_; }
|
||||||
uint32 time_scale() const { return time_scale_; }
|
uint32_t time_scale() const { return time_scale_; }
|
||||||
uint64 duration() const { return duration_; }
|
uint64_t duration() const { return duration_; }
|
||||||
const std::string& codec_string() const { return codec_string_; }
|
const std::string& codec_string() const { return codec_string_; }
|
||||||
const std::string& language() const { return language_; }
|
const std::string& language() const { return language_; }
|
||||||
|
|
||||||
bool is_encrypted() const { return is_encrypted_; }
|
bool is_encrypted() const { return is_encrypted_; }
|
||||||
|
|
||||||
const std::vector<uint8>& extra_data() const { return extra_data_; }
|
const std::vector<uint8_t>& extra_data() const { return extra_data_; }
|
||||||
|
|
||||||
void set_duration(int duration) { duration_ = duration; }
|
void set_duration(int duration) { duration_ = duration; }
|
||||||
|
|
||||||
void set_extra_data(const std::vector<uint8>& data) { extra_data_ = data; }
|
void set_extra_data(const std::vector<uint8_t>& data) { extra_data_ = data; }
|
||||||
|
|
||||||
void set_codec_string(const std::string& codec_string) {
|
void set_codec_string(const std::string& codec_string) {
|
||||||
codec_string_ = codec_string;
|
codec_string_ = codec_string;
|
||||||
|
@ -67,11 +67,11 @@ class StreamInfo : public base::RefCountedThreadSafe<StreamInfo> {
|
||||||
private:
|
private:
|
||||||
// Whether the stream is Audio or Video.
|
// Whether the stream is Audio or Video.
|
||||||
StreamType stream_type_;
|
StreamType stream_type_;
|
||||||
uint32 track_id_;
|
uint32_t track_id_;
|
||||||
// The actual time is calculated as time / time_scale_ in seconds.
|
// The actual time is calculated as time / time_scale_ in seconds.
|
||||||
uint32 time_scale_;
|
uint32_t time_scale_;
|
||||||
// Duration base on time_scale.
|
// Duration base on time_scale.
|
||||||
uint64 duration_;
|
uint64_t duration_;
|
||||||
std::string codec_string_;
|
std::string codec_string_;
|
||||||
std::string language_;
|
std::string language_;
|
||||||
// Whether the stream is potentially encrypted.
|
// Whether the stream is potentially encrypted.
|
||||||
|
@ -80,7 +80,7 @@ class StreamInfo : public base::RefCountedThreadSafe<StreamInfo> {
|
||||||
bool is_encrypted_;
|
bool is_encrypted_;
|
||||||
// Optional byte data required for some audio/video decoders such as Vorbis
|
// Optional byte data required for some audio/video decoders such as Vorbis
|
||||||
// codebooks.
|
// codebooks.
|
||||||
std::vector<uint8> extra_data_;
|
std::vector<uint8_t> extra_data_;
|
||||||
|
|
||||||
// Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler
|
// Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler
|
||||||
// generated copy constructor and assignment operator. Since the extra data is
|
// generated copy constructor and assignment operator. Since the extra data is
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
namespace edash_packager {
|
namespace edash_packager {
|
||||||
namespace media {
|
namespace media {
|
||||||
|
|
||||||
const int64 kNoTimestamp = kint64min;
|
const int64_t kNoTimestamp = kint64min;
|
||||||
const int64 kInfiniteDuration = kint64max;
|
const int64_t kInfiniteDuration = kint64max;
|
||||||
|
|
||||||
} // namespace media
|
} // namespace media
|
||||||
} // namespace edash_packager
|
} // namespace edash_packager
|
||||||
|
|
|
@ -39,15 +39,15 @@ std::string VideoCodecToString(VideoCodec video_codec) {
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
VideoStreamInfo::VideoStreamInfo(int track_id,
|
VideoStreamInfo::VideoStreamInfo(int track_id,
|
||||||
uint32 time_scale,
|
uint32_t time_scale,
|
||||||
uint64 duration,
|
uint64_t duration,
|
||||||
VideoCodec codec,
|
VideoCodec codec,
|
||||||
const std::string& codec_string,
|
const std::string& codec_string,
|
||||||
const std::string& language,
|
const std::string& language,
|
||||||
uint16 width,
|
uint16_t width,
|
||||||
uint16 height,
|
uint16_t height,
|
||||||
uint8 nalu_length_size,
|
uint8_t nalu_length_size,
|
||||||
const uint8* extra_data,
|
const uint8_t* extra_data,
|
||||||
size_t extra_data_size,
|
size_t extra_data_size,
|
||||||
bool is_encrypted)
|
bool is_encrypted)
|
||||||
: StreamInfo(kStreamVideo,
|
: StreamInfo(kStreamVideo,
|
||||||
|
@ -62,7 +62,8 @@ VideoStreamInfo::VideoStreamInfo(int track_id,
|
||||||
codec_(codec),
|
codec_(codec),
|
||||||
width_(width),
|
width_(width),
|
||||||
height_(height),
|
height_(height),
|
||||||
nalu_length_size_(nalu_length_size) {}
|
nalu_length_size_(nalu_length_size) {
|
||||||
|
}
|
||||||
|
|
||||||
VideoStreamInfo::~VideoStreamInfo() {}
|
VideoStreamInfo::~VideoStreamInfo() {}
|
||||||
|
|
||||||
|
@ -84,16 +85,16 @@ std::string VideoStreamInfo::ToString() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string VideoStreamInfo::GetCodecString(VideoCodec codec,
|
std::string VideoStreamInfo::GetCodecString(VideoCodec codec,
|
||||||
uint8 profile,
|
uint8_t profile,
|
||||||
uint8 compatible_profiles,
|
uint8_t compatible_profiles,
|
||||||
uint8 level) {
|
uint8_t level) {
|
||||||
switch (codec) {
|
switch (codec) {
|
||||||
case kCodecVP8:
|
case kCodecVP8:
|
||||||
return "vp8";
|
return "vp8";
|
||||||
case kCodecVP9:
|
case kCodecVP9:
|
||||||
return "vp9";
|
return "vp9";
|
||||||
case kCodecH264: {
|
case kCodecH264: {
|
||||||
const uint8 bytes[] = {profile, compatible_profiles, level};
|
const uint8_t bytes[] = {profile, compatible_profiles, level};
|
||||||
return "avc1." +
|
return "avc1." +
|
||||||
StringToLowerASCII(base::HexEncode(bytes, arraysize(bytes)));
|
StringToLowerASCII(base::HexEncode(bytes, arraysize(bytes)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,15 +29,15 @@ class VideoStreamInfo : public StreamInfo {
|
||||||
public:
|
public:
|
||||||
/// Construct an initialized video stream info object.
|
/// Construct an initialized video stream info object.
|
||||||
VideoStreamInfo(int track_id,
|
VideoStreamInfo(int track_id,
|
||||||
uint32 time_scale,
|
uint32_t time_scale,
|
||||||
uint64 duration,
|
uint64_t duration,
|
||||||
VideoCodec codec,
|
VideoCodec codec,
|
||||||
const std::string& codec_string,
|
const std::string& codec_string,
|
||||||
const std::string& language,
|
const std::string& language,
|
||||||
uint16 width,
|
uint16_t width,
|
||||||
uint16 height,
|
uint16_t height,
|
||||||
uint8 nalu_length_size,
|
uint8_t nalu_length_size,
|
||||||
const uint8* extra_data,
|
const uint8_t* extra_data,
|
||||||
size_t extra_data_size,
|
size_t extra_data_size,
|
||||||
bool is_encrypted);
|
bool is_encrypted);
|
||||||
|
|
||||||
|
@ -48,28 +48,28 @@ class VideoStreamInfo : public StreamInfo {
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
VideoCodec codec() const { return codec_; }
|
VideoCodec codec() const { return codec_; }
|
||||||
uint16 width() const { return width_; }
|
uint16_t width() const { return width_; }
|
||||||
uint16 height() const { return height_; }
|
uint16_t height() const { return height_; }
|
||||||
uint8 nalu_length_size() const { return nalu_length_size_; }
|
uint8_t nalu_length_size() const { return nalu_length_size_; }
|
||||||
|
|
||||||
/// @param profile,compatible_profiles,level are only used by H.264 codec.
|
/// @param profile,compatible_profiles,level are only used by H.264 codec.
|
||||||
/// @return The codec string.
|
/// @return The codec string.
|
||||||
static std::string GetCodecString(VideoCodec codec,
|
static std::string GetCodecString(VideoCodec codec,
|
||||||
uint8 profile,
|
uint8_t profile,
|
||||||
uint8 compatible_profiles,
|
uint8_t compatible_profiles,
|
||||||
uint8 level);
|
uint8_t level);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual ~VideoStreamInfo();
|
virtual ~VideoStreamInfo();
|
||||||
|
|
||||||
VideoCodec codec_;
|
VideoCodec codec_;
|
||||||
uint16 width_;
|
uint16_t width_;
|
||||||
uint16 height_;
|
uint16_t height_;
|
||||||
|
|
||||||
// Specifies the normalized size of the NAL unit length field. Can be 1, 2 or
|
// Specifies the normalized size of the NAL unit length field. Can be 1, 2 or
|
||||||
// 4 bytes, or 0 if the size if unknown or the stream is not a AVC stream
|
// 4 bytes, or 0 if the size if unknown or the stream is not a AVC stream
|
||||||
// (H.264).
|
// (H.264).
|
||||||
uint8 nalu_length_size_;
|
uint8_t nalu_length_size_;
|
||||||
|
|
||||||
// Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler
|
// Not using DISALLOW_COPY_AND_ASSIGN here intentionally to allow the compiler
|
||||||
// generated copy constructor and assignment operator. Since the extra data is
|
// generated copy constructor and assignment operator. Since the extra data is
|
||||||
|
|
|
@ -46,7 +46,7 @@ const int kGetKeyTimeoutInSeconds = 5 * 60; // 5 minutes.
|
||||||
const int kHttpTimeoutInSeconds = 60; // 1 minute.
|
const int kHttpTimeoutInSeconds = 60; // 1 minute.
|
||||||
|
|
||||||
bool Base64StringToBytes(const std::string& base64_string,
|
bool Base64StringToBytes(const std::string& base64_string,
|
||||||
std::vector<uint8>* bytes) {
|
std::vector<uint8_t>* bytes) {
|
||||||
DCHECK(bytes);
|
DCHECK(bytes);
|
||||||
std::string str;
|
std::string str;
|
||||||
if (!base::Base64Decode(base64_string, &str))
|
if (!base::Base64Decode(base64_string, &str))
|
||||||
|
@ -55,7 +55,7 @@ bool Base64StringToBytes(const std::string& base64_string,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BytesToBase64String(const std::vector<uint8>& bytes,
|
void BytesToBase64String(const std::vector<uint8_t>& bytes,
|
||||||
std::string* base64_string) {
|
std::string* base64_string) {
|
||||||
DCHECK(base64_string);
|
DCHECK(base64_string);
|
||||||
base::Base64Encode(base::StringPiece(reinterpret_cast<const char*>
|
base::Base64Encode(base::StringPiece(reinterpret_cast<const char*>
|
||||||
|
@ -64,7 +64,7 @@ void BytesToBase64String(const std::vector<uint8>& bytes,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetKeyFromTrack(const base::DictionaryValue& track_dict,
|
bool GetKeyFromTrack(const base::DictionaryValue& track_dict,
|
||||||
std::vector<uint8>* key) {
|
std::vector<uint8_t>* key) {
|
||||||
DCHECK(key);
|
DCHECK(key);
|
||||||
std::string key_base64_string;
|
std::string key_base64_string;
|
||||||
RCHECK(track_dict.GetString("key", &key_base64_string));
|
RCHECK(track_dict.GetString("key", &key_base64_string));
|
||||||
|
@ -74,7 +74,7 @@ bool GetKeyFromTrack(const base::DictionaryValue& track_dict,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetKeyIdFromTrack(const base::DictionaryValue& track_dict,
|
bool GetKeyIdFromTrack(const base::DictionaryValue& track_dict,
|
||||||
std::vector<uint8>* key_id) {
|
std::vector<uint8_t>* key_id) {
|
||||||
DCHECK(key_id);
|
DCHECK(key_id);
|
||||||
std::string key_id_base64_string;
|
std::string key_id_base64_string;
|
||||||
RCHECK(track_dict.GetString("key_id", &key_id_base64_string));
|
RCHECK(track_dict.GetString("key_id", &key_id_base64_string));
|
||||||
|
@ -84,7 +84,7 @@ bool GetKeyIdFromTrack(const base::DictionaryValue& track_dict,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetPsshDataFromTrack(const base::DictionaryValue& track_dict,
|
bool GetPsshDataFromTrack(const base::DictionaryValue& track_dict,
|
||||||
std::vector<uint8>* pssh_data) {
|
std::vector<uint8_t>* pssh_data) {
|
||||||
DCHECK(pssh_data);
|
DCHECK(pssh_data);
|
||||||
|
|
||||||
const base::ListValue* pssh_list;
|
const base::ListValue* pssh_list;
|
||||||
|
@ -164,7 +164,7 @@ WidevineKeySource::~WidevineKeySource() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Status WidevineKeySource::FetchKeys(const std::vector<uint8>& content_id,
|
Status WidevineKeySource::FetchKeys(const std::vector<uint8_t>& content_id,
|
||||||
const std::string& policy) {
|
const std::string& policy) {
|
||||||
base::AutoLock scoped_lock(lock_);
|
base::AutoLock scoped_lock(lock_);
|
||||||
request_dict_.Clear();
|
request_dict_.Clear();
|
||||||
|
@ -175,8 +175,7 @@ Status WidevineKeySource::FetchKeys(const std::vector<uint8>& content_id,
|
||||||
return FetchKeysCommon(false);
|
return FetchKeysCommon(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status WidevineKeySource::FetchKeys(
|
Status WidevineKeySource::FetchKeys(const std::vector<uint8_t>& pssh_data) {
|
||||||
const std::vector<uint8>& pssh_data) {
|
|
||||||
base::AutoLock scoped_lock(lock_);
|
base::AutoLock scoped_lock(lock_);
|
||||||
request_dict_.Clear();
|
request_dict_.Clear();
|
||||||
std::string pssh_data_base64_string;
|
std::string pssh_data_base64_string;
|
||||||
|
@ -185,7 +184,7 @@ Status WidevineKeySource::FetchKeys(
|
||||||
return FetchKeysCommon(false);
|
return FetchKeysCommon(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status WidevineKeySource::FetchKeys(uint32 asset_id) {
|
Status WidevineKeySource::FetchKeys(uint32_t asset_id) {
|
||||||
base::AutoLock scoped_lock(lock_);
|
base::AutoLock scoped_lock(lock_);
|
||||||
request_dict_.Clear();
|
request_dict_.Clear();
|
||||||
request_dict_.SetInteger("asset_id", asset_id);
|
request_dict_.SetInteger("asset_id", asset_id);
|
||||||
|
@ -214,7 +213,7 @@ Status WidevineKeySource::GetKey(TrackType track_type,
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status WidevineKeySource::GetKey(const std::vector<uint8>& key_id,
|
Status WidevineKeySource::GetKey(const std::vector<uint8_t>& key_id,
|
||||||
EncryptionKey* key) {
|
EncryptionKey* key) {
|
||||||
DCHECK(key);
|
DCHECK(key);
|
||||||
for (std::map<TrackType, EncryptionKey*>::iterator iter =
|
for (std::map<TrackType, EncryptionKey*>::iterator iter =
|
||||||
|
@ -230,10 +229,9 @@ Status WidevineKeySource::GetKey(const std::vector<uint8>& key_id,
|
||||||
"Cannot find key with specified key ID");
|
"Cannot find key with specified key ID");
|
||||||
}
|
}
|
||||||
|
|
||||||
Status WidevineKeySource::GetCryptoPeriodKey(
|
Status WidevineKeySource::GetCryptoPeriodKey(uint32_t crypto_period_index,
|
||||||
uint32 crypto_period_index,
|
TrackType track_type,
|
||||||
TrackType track_type,
|
EncryptionKey* key) {
|
||||||
EncryptionKey* key) {
|
|
||||||
DCHECK(key_production_thread_.HasBeenStarted());
|
DCHECK(key_production_thread_.HasBeenStarted());
|
||||||
// TODO(kqyang): This is not elegant. Consider refactoring later.
|
// TODO(kqyang): This is not elegant. Consider refactoring later.
|
||||||
{
|
{
|
||||||
|
@ -257,10 +255,9 @@ void WidevineKeySource::set_http_fetcher(
|
||||||
http_fetcher_ = http_fetcher.Pass();
|
http_fetcher_ = http_fetcher.Pass();
|
||||||
}
|
}
|
||||||
|
|
||||||
Status WidevineKeySource::GetKeyInternal(
|
Status WidevineKeySource::GetKeyInternal(uint32_t crypto_period_index,
|
||||||
uint32 crypto_period_index,
|
TrackType track_type,
|
||||||
TrackType track_type,
|
EncryptionKey* key) {
|
||||||
EncryptionKey* key) {
|
|
||||||
DCHECK(key_pool_);
|
DCHECK(key_pool_);
|
||||||
DCHECK(key);
|
DCHECK(key);
|
||||||
DCHECK_LE(track_type, NUM_VALID_TRACK_TYPES);
|
DCHECK_LE(track_type, NUM_VALID_TRACK_TYPES);
|
||||||
|
@ -307,7 +304,7 @@ void WidevineKeySource::FetchKeysTask() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Status WidevineKeySource::FetchKeysInternal(bool enable_key_rotation,
|
Status WidevineKeySource::FetchKeysInternal(bool enable_key_rotation,
|
||||||
uint32 first_crypto_period_index,
|
uint32_t first_crypto_period_index,
|
||||||
bool widevine_classic) {
|
bool widevine_classic) {
|
||||||
std::string request;
|
std::string request;
|
||||||
FillRequest(enable_key_rotation,
|
FillRequest(enable_key_rotation,
|
||||||
|
@ -321,7 +318,7 @@ Status WidevineKeySource::FetchKeysInternal(bool enable_key_rotation,
|
||||||
VLOG(1) << "Message: " << message;
|
VLOG(1) << "Message: " << message;
|
||||||
|
|
||||||
std::string raw_response;
|
std::string raw_response;
|
||||||
int64 sleep_duration = kFirstRetryDelayMilliseconds;
|
int64_t sleep_duration = kFirstRetryDelayMilliseconds;
|
||||||
|
|
||||||
// Perform client side retries if seeing server transient error to workaround
|
// Perform client side retries if seeing server transient error to workaround
|
||||||
// server limitation.
|
// server limitation.
|
||||||
|
@ -364,7 +361,7 @@ Status WidevineKeySource::FetchKeysInternal(bool enable_key_rotation,
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidevineKeySource::FillRequest(bool enable_key_rotation,
|
void WidevineKeySource::FillRequest(bool enable_key_rotation,
|
||||||
uint32 first_crypto_period_index,
|
uint32_t first_crypto_period_index,
|
||||||
std::string* request) {
|
std::string* request) {
|
||||||
DCHECK(request);
|
DCHECK(request);
|
||||||
DCHECK(!request_dict_.empty());
|
DCHECK(!request_dict_.empty());
|
||||||
|
@ -516,7 +513,7 @@ bool WidevineKeySource::ExtractEncryptionKey(
|
||||||
if (!GetKeyIdFromTrack(*track_dict, &encryption_key->key_id))
|
if (!GetKeyIdFromTrack(*track_dict, &encryption_key->key_id))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::vector<uint8> pssh_data;
|
std::vector<uint8_t> pssh_data;
|
||||||
if (!GetPsshDataFromTrack(*track_dict, &pssh_data))
|
if (!GetPsshDataFromTrack(*track_dict, &pssh_data))
|
||||||
return false;
|
return false;
|
||||||
encryption_key->pssh = PsshBoxFromPsshData(pssh_data);
|
encryption_key->pssh = PsshBoxFromPsshData(pssh_data);
|
||||||
|
|
|
@ -34,15 +34,15 @@ class WidevineKeySource : public KeySource {
|
||||||
|
|
||||||
/// @name KeySource implementation overrides.
|
/// @name KeySource implementation overrides.
|
||||||
/// @{
|
/// @{
|
||||||
virtual Status FetchKeys(const std::vector<uint8>& content_id,
|
virtual Status FetchKeys(const std::vector<uint8_t>& content_id,
|
||||||
const std::string& policy) OVERRIDE;
|
const std::string& policy) OVERRIDE;
|
||||||
virtual Status FetchKeys(const std::vector<uint8>& pssh_data) OVERRIDE;
|
virtual Status FetchKeys(const std::vector<uint8_t>& pssh_data) OVERRIDE;
|
||||||
Status FetchKeys(uint32 asset_id);
|
Status FetchKeys(uint32_t asset_id);
|
||||||
|
|
||||||
virtual Status GetKey(TrackType track_type, EncryptionKey* key) OVERRIDE;
|
virtual Status GetKey(TrackType track_type, EncryptionKey* key) OVERRIDE;
|
||||||
virtual Status GetKey(const std::vector<uint8>& key_id,
|
virtual Status GetKey(const std::vector<uint8_t>& key_id,
|
||||||
EncryptionKey* key) OVERRIDE;
|
EncryptionKey* key) OVERRIDE;
|
||||||
virtual Status GetCryptoPeriodKey(uint32 crypto_period_index,
|
virtual Status GetCryptoPeriodKey(uint32_t crypto_period_index,
|
||||||
TrackType track_type,
|
TrackType track_type,
|
||||||
EncryptionKey* key) OVERRIDE;
|
EncryptionKey* key) OVERRIDE;
|
||||||
/// @}
|
/// @}
|
||||||
|
@ -58,7 +58,7 @@ class WidevineKeySource : public KeySource {
|
||||||
EncryptionKeyQueue;
|
EncryptionKeyQueue;
|
||||||
|
|
||||||
// Internal routine for getting keys.
|
// Internal routine for getting keys.
|
||||||
Status GetKeyInternal(uint32 crypto_period_index,
|
Status GetKeyInternal(uint32_t crypto_period_index,
|
||||||
TrackType track_type,
|
TrackType track_type,
|
||||||
EncryptionKey* key);
|
EncryptionKey* key);
|
||||||
|
|
||||||
|
@ -70,13 +70,13 @@ class WidevineKeySource : public KeySource {
|
||||||
|
|
||||||
// Fetch keys from server.
|
// Fetch keys from server.
|
||||||
Status FetchKeysInternal(bool enable_key_rotation,
|
Status FetchKeysInternal(bool enable_key_rotation,
|
||||||
uint32 first_crypto_period_index,
|
uint32_t first_crypto_period_index,
|
||||||
bool widevine_classic);
|
bool widevine_classic);
|
||||||
|
|
||||||
// Fill |request| with necessary fields for Widevine encryption request.
|
// Fill |request| with necessary fields for Widevine encryption request.
|
||||||
// |request| should not be NULL.
|
// |request| should not be NULL.
|
||||||
void FillRequest(bool enable_key_rotation,
|
void FillRequest(bool enable_key_rotation,
|
||||||
uint32 first_crypto_period_index,
|
uint32_t first_crypto_period_index,
|
||||||
std::string* request);
|
std::string* request);
|
||||||
// Sign and properly format |request|.
|
// Sign and properly format |request|.
|
||||||
// |signed_request| should not be NULL. Return OK on success.
|
// |signed_request| should not be NULL. Return OK on success.
|
||||||
|
@ -103,11 +103,11 @@ class WidevineKeySource : public KeySource {
|
||||||
scoped_ptr<RequestSigner> signer_;
|
scoped_ptr<RequestSigner> signer_;
|
||||||
base::DictionaryValue request_dict_;
|
base::DictionaryValue request_dict_;
|
||||||
|
|
||||||
const uint32 crypto_period_count_;
|
const uint32_t crypto_period_count_;
|
||||||
base::Lock lock_;
|
base::Lock lock_;
|
||||||
bool key_production_started_;
|
bool key_production_started_;
|
||||||
base::WaitableEvent start_key_production_;
|
base::WaitableEvent start_key_production_;
|
||||||
uint32 first_crypto_period_index_;
|
uint32_t first_crypto_period_index_;
|
||||||
ClosureThread key_production_thread_;
|
ClosureThread key_production_thread_;
|
||||||
scoped_ptr<EncryptionKeyQueue> key_pool_;
|
scoped_ptr<EncryptionKeyQueue> key_pool_;
|
||||||
EncryptionKeyMap encryption_key_map_; // For non key rotation request.
|
EncryptionKeyMap encryption_key_map_; // For non key rotation request.
|
||||||
|
|
|
@ -44,7 +44,7 @@ const char kClassicTrackFormat[] = "{\"type\":\"%s\",\"key\":\"%s\"}";
|
||||||
const char kLicenseResponseFormat[] = "{\"status\":\"%s\",\"tracks\":[%s]}";
|
const char kLicenseResponseFormat[] = "{\"status\":\"%s\",\"tracks\":[%s]}";
|
||||||
const char kHttpResponseFormat[] = "{\"response\":\"%s\"}";
|
const char kHttpResponseFormat[] = "{\"response\":\"%s\"}";
|
||||||
const char kRequestPsshData[] = "PSSH data";
|
const char kRequestPsshData[] = "PSSH data";
|
||||||
const uint32 kClassicAssetId = 1234;
|
const uint32_t kClassicAssetId = 1234;
|
||||||
|
|
||||||
std::string Base64Encode(const std::string& input) {
|
std::string Base64Encode(const std::string& input) {
|
||||||
std::string output;
|
std::string output;
|
||||||
|
@ -52,7 +52,7 @@ std::string Base64Encode(const std::string& input) {
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ToString(const std::vector<uint8> v) {
|
std::string ToString(const std::vector<uint8_t> v) {
|
||||||
return std::string(v.begin(), v.end());
|
return std::string(v.begin(), v.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,9 +150,9 @@ class WidevineKeySourceTest : public ::testing::Test {
|
||||||
mock_http_fetcher_(new MockHttpFetcher()) {}
|
mock_http_fetcher_(new MockHttpFetcher()) {}
|
||||||
|
|
||||||
virtual void SetUp() OVERRIDE {
|
virtual void SetUp() OVERRIDE {
|
||||||
content_id_.assign(reinterpret_cast<const uint8*>(kContentId),
|
content_id_.assign(
|
||||||
reinterpret_cast<const uint8*>(kContentId) +
|
reinterpret_cast<const uint8_t*>(kContentId),
|
||||||
strlen(kContentId));
|
reinterpret_cast<const uint8_t*>(kContentId) + strlen(kContentId));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -183,7 +183,7 @@ class WidevineKeySourceTest : public ::testing::Test {
|
||||||
scoped_ptr<MockRequestSigner> mock_request_signer_;
|
scoped_ptr<MockRequestSigner> mock_request_signer_;
|
||||||
scoped_ptr<MockHttpFetcher> mock_http_fetcher_;
|
scoped_ptr<MockHttpFetcher> mock_http_fetcher_;
|
||||||
scoped_ptr<WidevineKeySource> widevine_key_source_;
|
scoped_ptr<WidevineKeySource> widevine_key_source_;
|
||||||
std::vector<uint8> content_id_;
|
std::vector<uint8_t> content_id_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_COPY_AND_ASSIGN(WidevineKeySourceTest);
|
DISALLOW_COPY_AND_ASSIGN(WidevineKeySourceTest);
|
||||||
|
@ -274,9 +274,9 @@ TEST_F(WidevineKeySourceTest, LicenseStatusCencWithPsshDataOK) {
|
||||||
.WillOnce(DoAll(SetArgPointee<2>(mock_response), Return(Status::OK)));
|
.WillOnce(DoAll(SetArgPointee<2>(mock_response), Return(Status::OK)));
|
||||||
|
|
||||||
CreateWidevineKeySource();
|
CreateWidevineKeySource();
|
||||||
std::vector<uint8> pssh_data(
|
std::vector<uint8_t> pssh_data(
|
||||||
reinterpret_cast<const uint8*>(kRequestPsshData),
|
reinterpret_cast<const uint8_t*>(kRequestPsshData),
|
||||||
reinterpret_cast<const uint8*>(kRequestPsshData) + strlen(kContentId));
|
reinterpret_cast<const uint8_t*>(kRequestPsshData) + strlen(kContentId));
|
||||||
ASSERT_OK(widevine_key_source_->FetchKeys(pssh_data));
|
ASSERT_OK(widevine_key_source_->FetchKeys(pssh_data));
|
||||||
VerifyKeys(false);
|
VerifyKeys(false);
|
||||||
}
|
}
|
||||||
|
@ -366,16 +366,17 @@ const char kCryptoPeriodTrackFormat[] =
|
||||||
"\"%s\",\"pssh\":[{\"drm_type\":\"WIDEVINE\",\"data\":\"\"}], "
|
"\"%s\",\"pssh\":[{\"drm_type\":\"WIDEVINE\",\"data\":\"\"}], "
|
||||||
"\"crypto_period_index\":%u}";
|
"\"crypto_period_index\":%u}";
|
||||||
|
|
||||||
std::string GetMockKey(const std::string& track_type, uint32 index) {
|
std::string GetMockKey(const std::string& track_type, uint32_t index) {
|
||||||
return "MockKey" + track_type + "@" + base::UintToString(index);
|
return "MockKey" + track_type + "@" + base::UintToString(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenerateMockKeyRotationLicenseResponse(
|
std::string GenerateMockKeyRotationLicenseResponse(
|
||||||
uint32 initial_crypto_period_index, uint32 crypto_period_count) {
|
uint32_t initial_crypto_period_index,
|
||||||
|
uint32_t crypto_period_count) {
|
||||||
const std::string kTrackTypes[] = {"SD", "HD", "AUDIO"};
|
const std::string kTrackTypes[] = {"SD", "HD", "AUDIO"};
|
||||||
std::string tracks;
|
std::string tracks;
|
||||||
for (uint32 index = initial_crypto_period_index;
|
for (uint32_t index = initial_crypto_period_index;
|
||||||
index < initial_crypto_period_index + crypto_period_count;
|
index < initial_crypto_period_index + crypto_period_count;
|
||||||
++index) {
|
++index) {
|
||||||
for (size_t i = 0; i < 3; ++i) {
|
for (size_t i = 0; i < 3; ++i) {
|
||||||
if (!tracks.empty())
|
if (!tracks.empty())
|
||||||
|
@ -393,13 +394,13 @@ std::string GenerateMockKeyRotationLicenseResponse(
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
TEST_F(WidevineKeySourceTest, KeyRotationTest) {
|
TEST_F(WidevineKeySourceTest, KeyRotationTest) {
|
||||||
const uint32 kFirstCryptoPeriodIndex = 8;
|
const uint32_t kFirstCryptoPeriodIndex = 8;
|
||||||
const uint32 kCryptoPeriodCount = 10;
|
const uint32_t kCryptoPeriodCount = 10;
|
||||||
// Array of indexes to be checked.
|
// Array of indexes to be checked.
|
||||||
const uint32 kCryptoPeriodIndexes[] = {kFirstCryptoPeriodIndex, 17, 37,
|
const uint32_t kCryptoPeriodIndexes[] = {
|
||||||
38, 36, 39};
|
kFirstCryptoPeriodIndex, 17, 37, 38, 36, 39};
|
||||||
// Derived from kCryptoPeriodIndexes: ceiling((39 - 8 ) / 10).
|
// Derived from kCryptoPeriodIndexes: ceiling((39 - 8 ) / 10).
|
||||||
const uint32 kCryptoIterations = 4;
|
const uint32_t kCryptoIterations = 4;
|
||||||
|
|
||||||
// Generate expectations in sequence.
|
// Generate expectations in sequence.
|
||||||
InSequence dummy;
|
InSequence dummy;
|
||||||
|
@ -412,8 +413,8 @@ TEST_F(WidevineKeySourceTest, KeyRotationTest) {
|
||||||
EXPECT_CALL(*mock_http_fetcher_, Post(_, _, _))
|
EXPECT_CALL(*mock_http_fetcher_, Post(_, _, _))
|
||||||
.WillOnce(DoAll(SetArgPointee<2>(mock_response), Return(Status::OK)));
|
.WillOnce(DoAll(SetArgPointee<2>(mock_response), Return(Status::OK)));
|
||||||
|
|
||||||
for (uint32 i = 0; i < kCryptoIterations; ++i) {
|
for (uint32_t i = 0; i < kCryptoIterations; ++i) {
|
||||||
uint32 first_crypto_period_index =
|
uint32_t first_crypto_period_index =
|
||||||
kFirstCryptoPeriodIndex - 1 + i * kCryptoPeriodCount;
|
kFirstCryptoPeriodIndex - 1 + i * kCryptoPeriodCount;
|
||||||
std::string expected_message =
|
std::string expected_message =
|
||||||
base::StringPrintf(kCryptoPeriodRequestMessageFormat,
|
base::StringPrintf(kCryptoPeriodRequestMessageFormat,
|
||||||
|
|
|
@ -36,7 +36,7 @@ void MpdNotifyMuxerListener::SetContentProtectionSchemeIdUri(
|
||||||
void MpdNotifyMuxerListener::OnMediaStart(
|
void MpdNotifyMuxerListener::OnMediaStart(
|
||||||
const MuxerOptions& muxer_options,
|
const MuxerOptions& muxer_options,
|
||||||
const std::vector<StreamInfo*>& stream_infos,
|
const std::vector<StreamInfo*>& stream_infos,
|
||||||
uint32 time_scale,
|
uint32_t time_scale,
|
||||||
ContainerType container_type,
|
ContainerType container_type,
|
||||||
bool is_encrypted) {
|
bool is_encrypted) {
|
||||||
scoped_ptr<MediaInfo> media_info(new MediaInfo());
|
scoped_ptr<MediaInfo> media_info(new MediaInfo());
|
||||||
|
@ -66,13 +66,13 @@ void MpdNotifyMuxerListener::OnMediaStart(
|
||||||
}
|
}
|
||||||
|
|
||||||
void MpdNotifyMuxerListener::OnMediaEnd(bool has_init_range,
|
void MpdNotifyMuxerListener::OnMediaEnd(bool has_init_range,
|
||||||
uint64 init_range_start,
|
uint64_t init_range_start,
|
||||||
uint64 init_range_end,
|
uint64_t init_range_end,
|
||||||
bool has_index_range,
|
bool has_index_range,
|
||||||
uint64 index_range_start,
|
uint64_t index_range_start,
|
||||||
uint64 index_range_end,
|
uint64_t index_range_end,
|
||||||
float duration_seconds,
|
float duration_seconds,
|
||||||
uint64 file_size) {
|
uint64_t file_size) {
|
||||||
if (mpd_notifier_->dash_profile() == kLiveProfile) return;
|
if (mpd_notifier_->dash_profile() == kLiveProfile) return;
|
||||||
|
|
||||||
DCHECK(media_info_);
|
DCHECK(media_info_);
|
||||||
|
@ -89,14 +89,14 @@ void MpdNotifyMuxerListener::OnMediaEnd(bool has_init_range,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 id; // Result unused.
|
uint32_t id; // Result unused.
|
||||||
// TODO(kqyang): Check return result.
|
// TODO(kqyang): Check return result.
|
||||||
mpd_notifier_->NotifyNewContainer(*media_info_, &id);
|
mpd_notifier_->NotifyNewContainer(*media_info_, &id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MpdNotifyMuxerListener::OnNewSegment(uint64 start_time,
|
void MpdNotifyMuxerListener::OnNewSegment(uint64_t start_time,
|
||||||
uint64 duration,
|
uint64_t duration,
|
||||||
uint64 segment_file_size) {
|
uint64_t segment_file_size) {
|
||||||
if (mpd_notifier_->dash_profile() != kLiveProfile) return;
|
if (mpd_notifier_->dash_profile() != kLiveProfile) return;
|
||||||
// TODO(kqyang): Check return result.
|
// TODO(kqyang): Check return result.
|
||||||
mpd_notifier_->NotifyNewSegment(
|
mpd_notifier_->NotifyNewSegment(
|
||||||
|
|
|
@ -39,27 +39,27 @@ class MpdNotifyMuxerListener : public MuxerListener {
|
||||||
/// @{
|
/// @{
|
||||||
virtual void OnMediaStart(const MuxerOptions& muxer_options,
|
virtual void OnMediaStart(const MuxerOptions& muxer_options,
|
||||||
const std::vector<StreamInfo*>& stream_infos,
|
const std::vector<StreamInfo*>& stream_infos,
|
||||||
uint32 time_scale,
|
uint32_t time_scale,
|
||||||
ContainerType container_type,
|
ContainerType container_type,
|
||||||
bool is_encrypted) OVERRIDE;
|
bool is_encrypted) OVERRIDE;
|
||||||
|
|
||||||
virtual void OnMediaEnd(bool has_init_range,
|
virtual void OnMediaEnd(bool has_init_range,
|
||||||
uint64 init_range_start,
|
uint64_t init_range_start,
|
||||||
uint64 init_range_end,
|
uint64_t init_range_end,
|
||||||
bool has_index_range,
|
bool has_index_range,
|
||||||
uint64 index_range_start,
|
uint64_t index_range_start,
|
||||||
uint64 index_range_end,
|
uint64_t index_range_end,
|
||||||
float duration_seconds,
|
float duration_seconds,
|
||||||
uint64 file_size) OVERRIDE;
|
uint64_t file_size) OVERRIDE;
|
||||||
|
|
||||||
virtual void OnNewSegment(uint64 start_time,
|
virtual void OnNewSegment(uint64_t start_time,
|
||||||
uint64 duration,
|
uint64_t duration,
|
||||||
uint64 segment_file_size) OVERRIDE;
|
uint64_t segment_file_size) OVERRIDE;
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MpdNotifier* const mpd_notifier_;
|
MpdNotifier* const mpd_notifier_;
|
||||||
uint32 notification_id_;
|
uint32_t notification_id_;
|
||||||
scoped_ptr<MediaInfo> media_info_;
|
scoped_ptr<MediaInfo> media_info_;
|
||||||
std::string scheme_id_uri_;
|
std::string scheme_id_uri_;
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ class MuxerListener {
|
||||||
// specified in |stream_infos|.
|
// specified in |stream_infos|.
|
||||||
virtual void OnMediaStart(const MuxerOptions& muxer_options,
|
virtual void OnMediaStart(const MuxerOptions& muxer_options,
|
||||||
const std::vector<StreamInfo*>& stream_infos,
|
const std::vector<StreamInfo*>& stream_infos,
|
||||||
uint32 time_scale,
|
uint32_t time_scale,
|
||||||
ContainerType container_type,
|
ContainerType container_type,
|
||||||
bool is_encrypted) = 0;
|
bool is_encrypted) = 0;
|
||||||
|
|
||||||
|
@ -54,22 +54,23 @@ class MuxerListener {
|
||||||
// Media length of |duration_seconds|.
|
// Media length of |duration_seconds|.
|
||||||
// |file_size| of the media in bytes.
|
// |file_size| of the media in bytes.
|
||||||
virtual void OnMediaEnd(bool has_init_range,
|
virtual void OnMediaEnd(bool has_init_range,
|
||||||
uint64 init_range_start,
|
uint64_t init_range_start,
|
||||||
uint64 init_range_end,
|
uint64_t init_range_end,
|
||||||
bool has_index_range,
|
bool has_index_range,
|
||||||
uint64 index_range_start,
|
uint64_t index_range_start,
|
||||||
uint64 index_range_end,
|
uint64_t index_range_end,
|
||||||
float duration_seconds,
|
float duration_seconds,
|
||||||
uint64 file_size) = 0;
|
uint64_t file_size) = 0;
|
||||||
|
|
||||||
// Called when a segment has been muxed and the file has been written.
|
// Called when a segment has been muxed and the file has been written.
|
||||||
// Note: For video on demand (VOD), this would be for subsegments.
|
// Note: For video on demand (VOD), this would be for subsegments.
|
||||||
// |start_time| and |duration| are relative to time scale specified
|
// |start_time| and |duration| are relative to time scale specified
|
||||||
// OnMediaStart().
|
// OnMediaStart().
|
||||||
// |segment_file_size| in bytes.
|
// |segment_file_size| in bytes.
|
||||||
virtual void OnNewSegment(uint64 start_time,
|
virtual void OnNewSegment(uint64_t start_time,
|
||||||
uint64 duration,
|
uint64_t duration,
|
||||||
uint64 segment_file_size) = 0;
|
uint64_t segment_file_size) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MuxerListener() {};
|
MuxerListener() {};
|
||||||
};
|
};
|
||||||
|
|
|
@ -23,27 +23,27 @@ namespace {
|
||||||
|
|
||||||
// This will return a positive value, given that |file_size| and
|
// This will return a positive value, given that |file_size| and
|
||||||
// |duration_seconds| are positive.
|
// |duration_seconds| are positive.
|
||||||
uint32 EstimateRequiredBandwidth(uint64 file_size, float duration_seconds) {
|
uint32_t EstimateRequiredBandwidth(uint64_t file_size, float duration_seconds) {
|
||||||
const uint64 file_size_bits = file_size * 8;
|
const uint64_t file_size_bits = file_size * 8;
|
||||||
const float bits_per_second = file_size_bits / duration_seconds;
|
const float bits_per_second = file_size_bits / duration_seconds;
|
||||||
|
|
||||||
// Note that casting |bits_per_second| to an integer might make it 0. Take the
|
// Note that casting |bits_per_second| to an integer might make it 0. Take the
|
||||||
// ceiling and make sure that it returns a positive value.
|
// ceiling and make sure that it returns a positive value.
|
||||||
return static_cast<uint32>(ceil(bits_per_second));
|
return static_cast<uint32_t>(ceil(bits_per_second));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetRange(uint64 begin, uint64 end, Range* range) {
|
void SetRange(uint64_t begin, uint64_t end, Range* range) {
|
||||||
DCHECK(range);
|
DCHECK(range);
|
||||||
range->set_begin(begin);
|
range->set_begin(begin);
|
||||||
range->set_end(end);
|
range->set_end(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetMediaInfoRanges(bool has_init_range,
|
void SetMediaInfoRanges(bool has_init_range,
|
||||||
uint64 init_range_start,
|
uint64_t init_range_start,
|
||||||
uint64 init_range_end,
|
uint64_t init_range_end,
|
||||||
bool has_index_range,
|
bool has_index_range,
|
||||||
uint64 index_range_start,
|
uint64_t index_range_start,
|
||||||
uint64 index_range_end,
|
uint64_t index_range_end,
|
||||||
MediaInfo* media_info) {
|
MediaInfo* media_info) {
|
||||||
if (has_init_range) {
|
if (has_init_range) {
|
||||||
SetRange(
|
SetRange(
|
||||||
|
@ -87,7 +87,7 @@ void AddVideoInfo(const VideoStreamInfo* video_stream_info,
|
||||||
video_info->set_height(video_stream_info->height());
|
video_info->set_height(video_stream_info->height());
|
||||||
video_info->set_time_scale(video_stream_info->time_scale());
|
video_info->set_time_scale(video_stream_info->time_scale());
|
||||||
|
|
||||||
const std::vector<uint8>& extra_data = video_stream_info->extra_data();
|
const std::vector<uint8_t>& extra_data = video_stream_info->extra_data();
|
||||||
if (!extra_data.empty()) {
|
if (!extra_data.empty()) {
|
||||||
video_info->set_decoder_config(&extra_data[0], extra_data.size());
|
video_info->set_decoder_config(&extra_data[0], extra_data.size());
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ void AddAudioInfo(const AudioStreamInfo* audio_stream_info,
|
||||||
audio_info->set_language(language);
|
audio_info->set_language(language);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<uint8>& extra_data = audio_stream_info->extra_data();
|
const std::vector<uint8_t>& extra_data = audio_stream_info->extra_data();
|
||||||
if (!extra_data.empty()) {
|
if (!extra_data.empty()) {
|
||||||
audio_info->set_decoder_config(&extra_data[0], extra_data.size());
|
audio_info->set_decoder_config(&extra_data[0], extra_data.size());
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ void SetMediaInfoMuxerOptions(const MuxerOptions& muxer_options,
|
||||||
|
|
||||||
bool GenerateMediaInfo(const MuxerOptions& muxer_options,
|
bool GenerateMediaInfo(const MuxerOptions& muxer_options,
|
||||||
const std::vector<StreamInfo*>& stream_infos,
|
const std::vector<StreamInfo*>& stream_infos,
|
||||||
uint32 reference_time_scale,
|
uint32_t reference_time_scale,
|
||||||
MuxerListener::ContainerType container_type,
|
MuxerListener::ContainerType container_type,
|
||||||
MediaInfo* media_info) {
|
MediaInfo* media_info) {
|
||||||
DCHECK(media_info);
|
DCHECK(media_info);
|
||||||
|
@ -168,13 +168,13 @@ bool GenerateMediaInfo(const MuxerOptions& muxer_options,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SetVodInformation(bool has_init_range,
|
bool SetVodInformation(bool has_init_range,
|
||||||
uint64 init_range_start,
|
uint64_t init_range_start,
|
||||||
uint64 init_range_end,
|
uint64_t init_range_end,
|
||||||
bool has_index_range,
|
bool has_index_range,
|
||||||
uint64 index_range_start,
|
uint64_t index_range_start,
|
||||||
uint64 index_range_end,
|
uint64_t index_range_end,
|
||||||
float duration_seconds,
|
float duration_seconds,
|
||||||
uint64 file_size,
|
uint64_t file_size,
|
||||||
MediaInfo* media_info) {
|
MediaInfo* media_info) {
|
||||||
DCHECK(media_info);
|
DCHECK(media_info);
|
||||||
if (file_size == 0) {
|
if (file_size == 0) {
|
||||||
|
|
|
@ -29,20 +29,20 @@ namespace internal {
|
||||||
/// @return true on success, false otherwise.
|
/// @return true on success, false otherwise.
|
||||||
bool GenerateMediaInfo(const MuxerOptions& muxer_options,
|
bool GenerateMediaInfo(const MuxerOptions& muxer_options,
|
||||||
const std::vector<StreamInfo*>& stream_infos,
|
const std::vector<StreamInfo*>& stream_infos,
|
||||||
uint32 reference_time_scale_,
|
uint32_t reference_time_scale_,
|
||||||
MuxerListener::ContainerType container_type,
|
MuxerListener::ContainerType container_type,
|
||||||
MediaInfo* media_info);
|
MediaInfo* media_info);
|
||||||
|
|
||||||
/// @param[in,out] media_info points to the MediaInfo object to be filled.
|
/// @param[in,out] media_info points to the MediaInfo object to be filled.
|
||||||
/// @return true on success, false otherwise.
|
/// @return true on success, false otherwise.
|
||||||
bool SetVodInformation(bool has_init_range,
|
bool SetVodInformation(bool has_init_range,
|
||||||
uint64 init_range_start,
|
uint64_t init_range_start,
|
||||||
uint64 init_range_end,
|
uint64_t init_range_end,
|
||||||
bool has_index_range,
|
bool has_index_range,
|
||||||
uint64 index_range_start,
|
uint64_t index_range_start,
|
||||||
uint64 index_range_end,
|
uint64_t index_range_end,
|
||||||
float duration_seconds,
|
float duration_seconds,
|
||||||
uint64 file_size,
|
uint64_t file_size,
|
||||||
MediaInfo* media_info);
|
MediaInfo* media_info);
|
||||||
|
|
||||||
/// @param container_type specifies container type. A default ContentProtection
|
/// @param container_type specifies container type. A default ContentProtection
|
||||||
|
|
|
@ -33,7 +33,7 @@ void VodMediaInfoDumpMuxerListener::SetContentProtectionSchemeIdUri(
|
||||||
void VodMediaInfoDumpMuxerListener::OnMediaStart(
|
void VodMediaInfoDumpMuxerListener::OnMediaStart(
|
||||||
const MuxerOptions& muxer_options,
|
const MuxerOptions& muxer_options,
|
||||||
const std::vector<StreamInfo*>& stream_infos,
|
const std::vector<StreamInfo*>& stream_infos,
|
||||||
uint32 time_scale,
|
uint32_t time_scale,
|
||||||
ContainerType container_type,
|
ContainerType container_type,
|
||||||
bool is_encrypted) {
|
bool is_encrypted) {
|
||||||
DCHECK(muxer_options.single_segment);
|
DCHECK(muxer_options.single_segment);
|
||||||
|
@ -57,13 +57,13 @@ void VodMediaInfoDumpMuxerListener::OnMediaStart(
|
||||||
}
|
}
|
||||||
|
|
||||||
void VodMediaInfoDumpMuxerListener::OnMediaEnd(bool has_init_range,
|
void VodMediaInfoDumpMuxerListener::OnMediaEnd(bool has_init_range,
|
||||||
uint64 init_range_start,
|
uint64_t init_range_start,
|
||||||
uint64 init_range_end,
|
uint64_t init_range_end,
|
||||||
bool has_index_range,
|
bool has_index_range,
|
||||||
uint64 index_range_start,
|
uint64_t index_range_start,
|
||||||
uint64 index_range_end,
|
uint64_t index_range_end,
|
||||||
float duration_seconds,
|
float duration_seconds,
|
||||||
uint64 file_size) {
|
uint64_t file_size) {
|
||||||
DCHECK(media_info_);
|
DCHECK(media_info_);
|
||||||
if (!internal::SetVodInformation(has_init_range,
|
if (!internal::SetVodInformation(has_init_range,
|
||||||
init_range_start,
|
init_range_start,
|
||||||
|
@ -80,9 +80,9 @@ void VodMediaInfoDumpMuxerListener::OnMediaEnd(bool has_init_range,
|
||||||
SerializeMediaInfoToFile();
|
SerializeMediaInfoToFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VodMediaInfoDumpMuxerListener::OnNewSegment(uint64 start_time,
|
void VodMediaInfoDumpMuxerListener::OnNewSegment(uint64_t start_time,
|
||||||
uint64 duration,
|
uint64_t duration,
|
||||||
uint64 segment_file_size) {
|
uint64_t segment_file_size) {
|
||||||
NOTIMPLEMENTED();
|
NOTIMPLEMENTED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,22 +39,22 @@ class VodMediaInfoDumpMuxerListener : public MuxerListener {
|
||||||
/// @{
|
/// @{
|
||||||
virtual void OnMediaStart(const MuxerOptions& muxer_options,
|
virtual void OnMediaStart(const MuxerOptions& muxer_options,
|
||||||
const std::vector<StreamInfo*>& stream_infos,
|
const std::vector<StreamInfo*>& stream_infos,
|
||||||
uint32 time_scale,
|
uint32_t time_scale,
|
||||||
ContainerType container_type,
|
ContainerType container_type,
|
||||||
bool is_encrypted) OVERRIDE;
|
bool is_encrypted) OVERRIDE;
|
||||||
|
|
||||||
virtual void OnMediaEnd(bool has_init_range,
|
virtual void OnMediaEnd(bool has_init_range,
|
||||||
uint64 init_range_start,
|
uint64_t init_range_start,
|
||||||
uint64 init_range_end,
|
uint64_t init_range_end,
|
||||||
bool has_index_range,
|
bool has_index_range,
|
||||||
uint64 index_range_start,
|
uint64_t index_range_start,
|
||||||
uint64 index_range_end,
|
uint64_t index_range_end,
|
||||||
float duration_seconds,
|
float duration_seconds,
|
||||||
uint64 file_size) OVERRIDE;
|
uint64_t file_size) OVERRIDE;
|
||||||
|
|
||||||
virtual void OnNewSegment(uint64 start_time,
|
virtual void OnNewSegment(uint64_t start_time,
|
||||||
uint64 duration,
|
uint64_t duration,
|
||||||
uint64 segment_file_size) OVERRIDE;
|
uint64_t segment_file_size) OVERRIDE;
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -29,28 +29,28 @@ namespace event {
|
||||||
namespace {
|
namespace {
|
||||||
struct VideoStreamInfoParameters {
|
struct VideoStreamInfoParameters {
|
||||||
int track_id;
|
int track_id;
|
||||||
uint32 time_scale;
|
uint32_t time_scale;
|
||||||
uint64 duration;
|
uint64_t duration;
|
||||||
VideoCodec codec;
|
VideoCodec codec;
|
||||||
std::string codec_string;
|
std::string codec_string;
|
||||||
std::string language;
|
std::string language;
|
||||||
uint16 width;
|
uint16_t width;
|
||||||
uint16 height;
|
uint16_t height;
|
||||||
uint8 nalu_length_size;
|
uint8_t nalu_length_size;
|
||||||
std::vector<uint8> extra_data;
|
std::vector<uint8_t> extra_data;
|
||||||
bool is_encrypted;
|
bool is_encrypted;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Note that this does not have vector of StreamInfo pointer.
|
// Note that this does not have vector of StreamInfo pointer.
|
||||||
struct OnMediaEndParameters {
|
struct OnMediaEndParameters {
|
||||||
bool has_init_range;
|
bool has_init_range;
|
||||||
uint64 init_range_start;
|
uint64_t init_range_start;
|
||||||
uint64 init_range_end;
|
uint64_t init_range_end;
|
||||||
bool has_index_range;
|
bool has_index_range;
|
||||||
uint64 index_range_start;
|
uint64_t index_range_start;
|
||||||
uint64 index_range_end;
|
uint64_t index_range_end;
|
||||||
float duration_seconds;
|
float duration_seconds;
|
||||||
uint64 file_size;
|
uint64_t file_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
scoped_refptr<StreamInfo> CreateVideoStreamInfo(
|
scoped_refptr<StreamInfo> CreateVideoStreamInfo(
|
||||||
|
@ -72,17 +72,17 @@ scoped_refptr<StreamInfo> CreateVideoStreamInfo(
|
||||||
|
|
||||||
VideoStreamInfoParameters GetDefaultVideoStreamInfoParams() {
|
VideoStreamInfoParameters GetDefaultVideoStreamInfoParams() {
|
||||||
const int kTrackId = 0;
|
const int kTrackId = 0;
|
||||||
const uint32 kTimeScale = 10;
|
const uint32_t kTimeScale = 10;
|
||||||
const uint64 kVideoStreamDuration = 200;
|
const uint64_t kVideoStreamDuration = 200;
|
||||||
const VideoCodec kH264Codec = kCodecH264;
|
const VideoCodec kH264Codec = kCodecH264;
|
||||||
const uint8 kH264Profile = 1;
|
const uint8_t kH264Profile = 1;
|
||||||
const uint8 kH264CompatibleProfile = 1;
|
const uint8_t kH264CompatibleProfile = 1;
|
||||||
const uint8 kH264Level = 1;
|
const uint8_t kH264Level = 1;
|
||||||
const char* kLanuageUndefined = "und";
|
const char* kLanuageUndefined = "und";
|
||||||
const uint16 kWidth = 720;
|
const uint16_t kWidth = 720;
|
||||||
const uint16 kHeight = 480;
|
const uint16_t kHeight = 480;
|
||||||
const uint8 kNaluLengthSize = 1;
|
const uint8_t kNaluLengthSize = 1;
|
||||||
const std::vector<uint8> kExtraData;
|
const std::vector<uint8_t> kExtraData;
|
||||||
const bool kEncryptedFlag = false;
|
const bool kEncryptedFlag = false;
|
||||||
|
|
||||||
VideoStreamInfoParameters param = {
|
VideoStreamInfoParameters param = {
|
||||||
|
@ -98,13 +98,13 @@ OnMediaEndParameters GetDefaultOnMediaEndParams() {
|
||||||
// Values for {init, index} range {start, end} are arbitrary, but makes sure
|
// Values for {init, index} range {start, end} are arbitrary, but makes sure
|
||||||
// that it is monotonically increasing and contiguous.
|
// that it is monotonically increasing and contiguous.
|
||||||
const bool kHasInitRange = true;
|
const bool kHasInitRange = true;
|
||||||
const uint64 kInitRangeStart = 0;
|
const uint64_t kInitRangeStart = 0;
|
||||||
const uint64 kInitRangeEnd = kInitRangeStart + 120;
|
const uint64_t kInitRangeEnd = kInitRangeStart + 120;
|
||||||
const uint64 kHasIndexRange = true;
|
const uint64_t kHasIndexRange = true;
|
||||||
const uint64 kIndexRangeStart = kInitRangeEnd + 1;
|
const uint64_t kIndexRangeStart = kInitRangeEnd + 1;
|
||||||
const uint64 kIndexRangeEnd = kIndexRangeStart + 100;
|
const uint64_t kIndexRangeEnd = kIndexRangeStart + 100;
|
||||||
const float kMediaDuration = 10.5f;
|
const float kMediaDuration = 10.5f;
|
||||||
const uint64 kFileSize = 10000;
|
const uint64_t kFileSize = 10000;
|
||||||
OnMediaEndParameters param = {
|
OnMediaEndParameters param = {
|
||||||
kHasInitRange, kInitRangeStart, kInitRangeEnd, kHasIndexRange,
|
kHasInitRange, kInitRangeStart, kInitRangeEnd, kHasIndexRange,
|
||||||
kIndexRangeStart, kIndexRangeEnd, kMediaDuration, kFileSize};
|
kIndexRangeStart, kIndexRangeEnd, kMediaDuration, kFileSize};
|
||||||
|
@ -171,7 +171,7 @@ class VodMediaInfoDumpMuxerListenerTest : public ::testing::Test {
|
||||||
bool enable_encryption) {
|
bool enable_encryption) {
|
||||||
MuxerOptions muxer_options;
|
MuxerOptions muxer_options;
|
||||||
SetDefaultMuxerOptionsValues(&muxer_options);
|
SetDefaultMuxerOptionsValues(&muxer_options);
|
||||||
const uint32 kReferenceTimeScale = 1000;
|
const uint32_t kReferenceTimeScale = 1000;
|
||||||
listener_->OnMediaStart(muxer_options,
|
listener_->OnMediaStart(muxer_options,
|
||||||
stream_infos,
|
stream_infos,
|
||||||
kReferenceTimeScale,
|
kReferenceTimeScale,
|
||||||
|
|
|
@ -66,11 +66,11 @@ File* File::Open(const char* file_name, const char* mode) {
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 File::GetFileSize(const char* file_name) {
|
int64_t File::GetFileSize(const char* file_name) {
|
||||||
File* file = File::Open(file_name, "r");
|
File* file = File::Open(file_name, "r");
|
||||||
if (!file)
|
if (!file)
|
||||||
return -1;
|
return -1;
|
||||||
int64 res = file->Size();
|
int64_t res = file->Size();
|
||||||
file->Close();
|
file->Close();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,7 @@ bool File::ReadFileToString(const char* file_name, std::string* contents) {
|
||||||
const size_t kBufferSize = 0x40000; // 256KB.
|
const size_t kBufferSize = 0x40000; // 256KB.
|
||||||
scoped_ptr<char[]> buf(new char[kBufferSize]);
|
scoped_ptr<char[]> buf(new char[kBufferSize]);
|
||||||
|
|
||||||
int64 len;
|
int64_t len;
|
||||||
while ((len = file->Read(buf.get(), kBufferSize)) > 0)
|
while ((len = file->Read(buf.get(), kBufferSize)) > 0)
|
||||||
contents->append(buf.get(), len);
|
contents->append(buf.get(), len);
|
||||||
|
|
||||||
|
|
|
@ -40,17 +40,17 @@ class File {
|
||||||
/// @param length indicates number of bytes to be read.
|
/// @param length indicates number of bytes to be read.
|
||||||
/// @return Number of bytes read, or a value < 0 on error.
|
/// @return Number of bytes read, or a value < 0 on error.
|
||||||
/// Zero on end-of-file, or if 'length' is zero.
|
/// Zero on end-of-file, or if 'length' is zero.
|
||||||
virtual int64 Read(void* buffer, uint64 length) = 0;
|
virtual int64_t Read(void* buffer, uint64_t length) = 0;
|
||||||
|
|
||||||
/// Write block of data.
|
/// Write block of data.
|
||||||
/// @param buffer points to a block of memory with at least @a length bytes.
|
/// @param buffer points to a block of memory with at least @a length bytes.
|
||||||
/// @param length indicates number of bytes to write.
|
/// @param length indicates number of bytes to write.
|
||||||
/// @return Number of bytes written, or a value < 0 on error.
|
/// @return Number of bytes written, or a value < 0 on error.
|
||||||
virtual int64 Write(const void* buffer, uint64 length) = 0;
|
virtual int64_t Write(const void* buffer, uint64_t length) = 0;
|
||||||
|
|
||||||
/// @return Size of the file in bytes. A return value less than zero
|
/// @return Size of the file in bytes. A return value less than zero
|
||||||
/// indicates a problem getting the size.
|
/// indicates a problem getting the size.
|
||||||
virtual int64 Size() = 0;
|
virtual int64_t Size() = 0;
|
||||||
|
|
||||||
/// Flush the file so that recently written data will survive an
|
/// Flush the file so that recently written data will survive an
|
||||||
/// application crash (but not necessarily an OS crash). For
|
/// application crash (but not necessarily an OS crash). For
|
||||||
|
@ -71,7 +71,7 @@ class File {
|
||||||
|
|
||||||
/// @return The size of a file in bytes on success, a value < 0 otherwise.
|
/// @return The size of a file in bytes on success, a value < 0 otherwise.
|
||||||
/// The file will be opened and closed in the process.
|
/// The file will be opened and closed in the process.
|
||||||
static int64 GetFileSize(const char* file_name);
|
static int64_t GetFileSize(const char* file_name);
|
||||||
|
|
||||||
/// Read the file into string.
|
/// Read the file into string.
|
||||||
/// @param file_name is the file to be read. It should be a valid file.
|
/// @param file_name is the file to be read. It should be a valid file.
|
||||||
|
|
|
@ -25,19 +25,19 @@ bool LocalFile::Close() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 LocalFile::Read(void* buffer, uint64 length) {
|
int64_t LocalFile::Read(void* buffer, uint64_t length) {
|
||||||
DCHECK(buffer != NULL);
|
DCHECK(buffer != NULL);
|
||||||
DCHECK(internal_file_ != NULL);
|
DCHECK(internal_file_ != NULL);
|
||||||
return fread(buffer, sizeof(char), length, internal_file_);
|
return fread(buffer, sizeof(char), length, internal_file_);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 LocalFile::Write(const void* buffer, uint64 length) {
|
int64_t LocalFile::Write(const void* buffer, uint64_t length) {
|
||||||
DCHECK(buffer != NULL);
|
DCHECK(buffer != NULL);
|
||||||
DCHECK(internal_file_ != NULL);
|
DCHECK(internal_file_ != NULL);
|
||||||
return fwrite(buffer, sizeof(char), length, internal_file_);
|
return fwrite(buffer, sizeof(char), length, internal_file_);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 LocalFile::Size() {
|
int64_t LocalFile::Size() {
|
||||||
DCHECK(internal_file_ != NULL);
|
DCHECK(internal_file_ != NULL);
|
||||||
|
|
||||||
// Flush any buffered data, so we get the true file size.
|
// Flush any buffered data, so we get the true file size.
|
||||||
|
@ -46,7 +46,7 @@ int64 LocalFile::Size() {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 file_size;
|
int64_t file_size;
|
||||||
if (!base::GetFileSize(base::FilePath(file_name()), &file_size)) {
|
if (!base::GetFileSize(base::FilePath(file_name()), &file_size)) {
|
||||||
LOG(ERROR) << "Cannot get file size.";
|
LOG(ERROR) << "Cannot get file size.";
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -27,9 +27,9 @@ class LocalFile : public File {
|
||||||
/// @name File implementation overrides.
|
/// @name File implementation overrides.
|
||||||
/// @{
|
/// @{
|
||||||
virtual bool Close() OVERRIDE;
|
virtual bool Close() OVERRIDE;
|
||||||
virtual int64 Read(void* buffer, uint64 length) OVERRIDE;
|
virtual int64_t Read(void* buffer, uint64_t length) OVERRIDE;
|
||||||
virtual int64 Write(const void* buffer, uint64 length) OVERRIDE;
|
virtual int64_t Write(const void* buffer, uint64_t length) OVERRIDE;
|
||||||
virtual int64 Size() OVERRIDE;
|
virtual int64_t Size() OVERRIDE;
|
||||||
virtual bool Flush() OVERRIDE;
|
virtual bool Flush() OVERRIDE;
|
||||||
virtual bool Eof() OVERRIDE;
|
virtual bool Eof() OVERRIDE;
|
||||||
/// @}
|
/// @}
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace {
|
||||||
|
|
||||||
const int kInvalidSocket(-1);
|
const int kInvalidSocket(-1);
|
||||||
|
|
||||||
bool StringToIpv4Address(const std::string& addr_in, uint32* addr_out) {
|
bool StringToIpv4Address(const std::string& addr_in, uint32_t* addr_out) {
|
||||||
DCHECK(addr_out);
|
DCHECK(addr_out);
|
||||||
|
|
||||||
*addr_out = 0;
|
*addr_out = 0;
|
||||||
|
@ -53,8 +53,8 @@ bool StringToIpv4Address(const std::string& addr_in, uint32* addr_out) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool StringToIpv4AddressAndPort(const std::string& addr_and_port,
|
bool StringToIpv4AddressAndPort(const std::string& addr_and_port,
|
||||||
uint32* addr,
|
uint32_t* addr,
|
||||||
uint16* port) {
|
uint16_t* port) {
|
||||||
DCHECK(addr);
|
DCHECK(addr);
|
||||||
DCHECK(port);
|
DCHECK(port);
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ bool StringToIpv4AddressAndPort(const std::string& addr_and_port,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsIpv4MulticastAddress(uint32 addr) {
|
bool IsIpv4MulticastAddress(uint32_t addr) {
|
||||||
return (addr & 0xf0000000) == 0xe0000000;
|
return (addr & 0xf0000000) == 0xe0000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ bool UdpFile::Close() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 UdpFile::Read(void* buffer, uint64 length) {
|
int64_t UdpFile::Read(void* buffer, uint64_t length) {
|
||||||
DCHECK(buffer);
|
DCHECK(buffer);
|
||||||
DCHECK_GE(length, 65535u)
|
DCHECK_GE(length, 65535u)
|
||||||
<< "Buffer may be too small to read entire datagram.";
|
<< "Buffer may be too small to read entire datagram.";
|
||||||
|
@ -102,7 +102,7 @@ int64 UdpFile::Read(void* buffer, uint64 length) {
|
||||||
if (socket_ == kInvalidSocket)
|
if (socket_ == kInvalidSocket)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
int64 result;
|
int64_t result;
|
||||||
do {
|
do {
|
||||||
result = recvfrom(socket_, buffer, length, 0, NULL, 0);
|
result = recvfrom(socket_, buffer, length, 0, NULL, 0);
|
||||||
} while ((result == -1) && (errno == EINTR));
|
} while ((result == -1) && (errno == EINTR));
|
||||||
|
@ -110,12 +110,12 @@ int64 UdpFile::Read(void* buffer, uint64 length) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 UdpFile::Write(const void* buffer, uint64 length) {
|
int64_t UdpFile::Write(const void* buffer, uint64_t length) {
|
||||||
NOTIMPLEMENTED();
|
NOTIMPLEMENTED();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 UdpFile::Size() {
|
int64_t UdpFile::Size() {
|
||||||
if (socket_ == kInvalidSocket)
|
if (socket_ == kInvalidSocket)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -159,8 +159,8 @@ bool UdpFile::Open() {
|
||||||
DCHECK_EQ(kInvalidSocket, socket_);
|
DCHECK_EQ(kInvalidSocket, socket_);
|
||||||
|
|
||||||
// TODO(tinskip): Support IPv6 addresses.
|
// TODO(tinskip): Support IPv6 addresses.
|
||||||
uint32 dest_addr;
|
uint32_t dest_addr;
|
||||||
uint16 dest_port;
|
uint16_t dest_port;
|
||||||
if (!StringToIpv4AddressAndPort(file_name(),
|
if (!StringToIpv4AddressAndPort(file_name(),
|
||||||
&dest_addr,
|
&dest_addr,
|
||||||
&dest_port)) {
|
&dest_port)) {
|
||||||
|
@ -187,7 +187,7 @@ bool UdpFile::Open() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsIpv4MulticastAddress(dest_addr)) {
|
if (IsIpv4MulticastAddress(dest_addr)) {
|
||||||
uint32 if_addr;
|
uint32_t if_addr;
|
||||||
if (!StringToIpv4Address(FLAGS_udp_interface_address, &if_addr)) {
|
if (!StringToIpv4Address(FLAGS_udp_interface_address, &if_addr)) {
|
||||||
LOG(ERROR) << "Malformed IPv4 address for interface.";
|
LOG(ERROR) << "Malformed IPv4 address for interface.";
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -26,9 +26,9 @@ class UdpFile : public File {
|
||||||
/// @name File implementation overrides.
|
/// @name File implementation overrides.
|
||||||
/// @{
|
/// @{
|
||||||
virtual bool Close() OVERRIDE;
|
virtual bool Close() OVERRIDE;
|
||||||
virtual int64 Read(void* buffer, uint64 length) OVERRIDE;
|
virtual int64_t Read(void* buffer, uint64_t length) OVERRIDE;
|
||||||
virtual int64 Write(const void* buffer, uint64 length) OVERRIDE;
|
virtual int64_t Write(const void* buffer, uint64_t length) OVERRIDE;
|
||||||
virtual int64 Size() OVERRIDE;
|
virtual int64_t Size() OVERRIDE;
|
||||||
virtual bool Flush() OVERRIDE;
|
virtual bool Flush() OVERRIDE;
|
||||||
virtual bool Eof() OVERRIDE;
|
virtual bool Eof() OVERRIDE;
|
||||||
/// @}
|
/// @}
|
||||||
|
|
|
@ -18,7 +18,7 @@ H264BitReader::H264BitReader()
|
||||||
|
|
||||||
H264BitReader::~H264BitReader() {}
|
H264BitReader::~H264BitReader() {}
|
||||||
|
|
||||||
bool H264BitReader::Initialize(const uint8* data, off_t size) {
|
bool H264BitReader::Initialize(const uint8_t* data, off_t size) {
|
||||||
DCHECK(data);
|
DCHECK(data);
|
||||||
|
|
||||||
if (size < 1)
|
if (size < 1)
|
||||||
|
|
|
@ -26,7 +26,7 @@ class H264BitReader {
|
||||||
// Initialize the reader to start reading at |data|, |size| being size
|
// Initialize the reader to start reading at |data|, |size| being size
|
||||||
// of |data| in bytes.
|
// of |data| in bytes.
|
||||||
// Return false on insufficient size of stream..
|
// Return false on insufficient size of stream..
|
||||||
bool Initialize(const uint8* data, off_t size);
|
bool Initialize(const uint8_t* data, off_t size);
|
||||||
|
|
||||||
// Read |num_bits| next bits from stream and return in |*out|, first bit
|
// Read |num_bits| next bits from stream and return in |*out|, first bit
|
||||||
// from the stream starting at |num_bits| position in |*out|.
|
// from the stream starting at |num_bits| position in |*out|.
|
||||||
|
@ -50,7 +50,7 @@ class H264BitReader {
|
||||||
bool UpdateCurrByte();
|
bool UpdateCurrByte();
|
||||||
|
|
||||||
// Pointer to the next unread (not in curr_byte_) byte in the stream.
|
// Pointer to the next unread (not in curr_byte_) byte in the stream.
|
||||||
const uint8* data_;
|
const uint8_t* data_;
|
||||||
|
|
||||||
// Bytes left in the stream (without the curr_byte_).
|
// Bytes left in the stream (without the curr_byte_).
|
||||||
off_t bytes_left_;
|
off_t bytes_left_;
|
||||||
|
|
|
@ -24,16 +24,16 @@ H264ByteToUnitStreamConverter::H264ByteToUnitStreamConverter() {}
|
||||||
H264ByteToUnitStreamConverter::~H264ByteToUnitStreamConverter() {}
|
H264ByteToUnitStreamConverter::~H264ByteToUnitStreamConverter() {}
|
||||||
|
|
||||||
bool H264ByteToUnitStreamConverter::ConvertByteStreamToNalUnitStream(
|
bool H264ByteToUnitStreamConverter::ConvertByteStreamToNalUnitStream(
|
||||||
const uint8* input_frame,
|
const uint8_t* input_frame,
|
||||||
size_t input_frame_size,
|
size_t input_frame_size,
|
||||||
std::vector<uint8>* output_frame) {
|
std::vector<uint8_t>* output_frame) {
|
||||||
DCHECK(input_frame);
|
DCHECK(input_frame);
|
||||||
DCHECK(output_frame);
|
DCHECK(output_frame);
|
||||||
|
|
||||||
BufferWriter output_buffer(input_frame_size + kStreamConversionOverhead);
|
BufferWriter output_buffer(input_frame_size + kStreamConversionOverhead);
|
||||||
|
|
||||||
const uint8* input_ptr(input_frame);
|
const uint8_t* input_ptr(input_frame);
|
||||||
const uint8* input_end(input_ptr + input_frame_size);
|
const uint8_t* input_end(input_ptr + input_frame_size);
|
||||||
off_t next_start_code_offset;
|
off_t next_start_code_offset;
|
||||||
off_t next_start_code_size;
|
off_t next_start_code_size;
|
||||||
bool first_nalu(true);
|
bool first_nalu(true);
|
||||||
|
@ -64,17 +64,16 @@ bool H264ByteToUnitStreamConverter::ConvertByteStreamToNalUnitStream(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void H264ByteToUnitStreamConverter::ProcessNalu(
|
void H264ByteToUnitStreamConverter::ProcessNalu(const uint8_t* nalu_ptr,
|
||||||
const uint8* nalu_ptr,
|
size_t nalu_size,
|
||||||
size_t nalu_size,
|
BufferWriter* output_buffer) {
|
||||||
BufferWriter* output_buffer) {
|
|
||||||
DCHECK(nalu_ptr);
|
DCHECK(nalu_ptr);
|
||||||
DCHECK(output_buffer);
|
DCHECK(output_buffer);
|
||||||
|
|
||||||
if (!nalu_size)
|
if (!nalu_size)
|
||||||
return; // Edge case.
|
return; // Edge case.
|
||||||
|
|
||||||
uint8 nalu_type = *nalu_ptr & 0x0f;
|
uint8_t nalu_type = *nalu_ptr & 0x0f;
|
||||||
switch (nalu_type) {
|
switch (nalu_type) {
|
||||||
case H264NALU::kSPS:
|
case H264NALU::kSPS:
|
||||||
// Grab SPS NALU.
|
// Grab SPS NALU.
|
||||||
|
@ -93,12 +92,12 @@ void H264ByteToUnitStreamConverter::ProcessNalu(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append 4-byte length and NAL unit data to the buffer.
|
// Append 4-byte length and NAL unit data to the buffer.
|
||||||
output_buffer->AppendInt(static_cast<uint32>(nalu_size));
|
output_buffer->AppendInt(static_cast<uint32_t>(nalu_size));
|
||||||
output_buffer->AppendArray(nalu_ptr, nalu_size);
|
output_buffer->AppendArray(nalu_ptr, nalu_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool H264ByteToUnitStreamConverter::GetAVCDecoderConfigurationRecord(
|
bool H264ByteToUnitStreamConverter::GetAVCDecoderConfigurationRecord(
|
||||||
std::vector<uint8>* decoder_config) {
|
std::vector<uint8_t>* decoder_config) {
|
||||||
DCHECK(decoder_config);
|
DCHECK(decoder_config);
|
||||||
|
|
||||||
if ((last_sps_.size() < 4) || last_pps_.empty()) {
|
if ((last_sps_.size() < 4) || last_pps_.empty()) {
|
||||||
|
@ -109,20 +108,20 @@ bool H264ByteToUnitStreamConverter::GetAVCDecoderConfigurationRecord(
|
||||||
// Construct an AVCDecoderConfigurationRecord containing a single SPS and a
|
// Construct an AVCDecoderConfigurationRecord containing a single SPS and a
|
||||||
// single PPS NALU. Please refer to ISO/IEC 14496-15 for format specifics.
|
// single PPS NALU. Please refer to ISO/IEC 14496-15 for format specifics.
|
||||||
BufferWriter buffer(last_sps_.size() + last_pps_.size() + 11);
|
BufferWriter buffer(last_sps_.size() + last_pps_.size() + 11);
|
||||||
uint8 version(1);
|
uint8_t version(1);
|
||||||
buffer.AppendInt(version);
|
buffer.AppendInt(version);
|
||||||
buffer.AppendInt(last_sps_[1]);
|
buffer.AppendInt(last_sps_[1]);
|
||||||
buffer.AppendInt(last_sps_[2]);
|
buffer.AppendInt(last_sps_[2]);
|
||||||
buffer.AppendInt(last_sps_[3]);
|
buffer.AppendInt(last_sps_[3]);
|
||||||
uint8 reserved_and_length_size_minus_one(0xff);
|
uint8_t reserved_and_length_size_minus_one(0xff);
|
||||||
buffer.AppendInt(reserved_and_length_size_minus_one);
|
buffer.AppendInt(reserved_and_length_size_minus_one);
|
||||||
uint8 reserved_and_num_sps(0xe1);
|
uint8_t reserved_and_num_sps(0xe1);
|
||||||
buffer.AppendInt(reserved_and_num_sps);
|
buffer.AppendInt(reserved_and_num_sps);
|
||||||
buffer.AppendInt(static_cast<uint16>(last_sps_.size()));
|
buffer.AppendInt(static_cast<uint16_t>(last_sps_.size()));
|
||||||
buffer.AppendVector(last_sps_);
|
buffer.AppendVector(last_sps_);
|
||||||
uint8 num_pps(1);
|
uint8_t num_pps(1);
|
||||||
buffer.AppendInt(num_pps);
|
buffer.AppendInt(num_pps);
|
||||||
buffer.AppendInt(static_cast<uint16>(last_pps_.size()));
|
buffer.AppendInt(static_cast<uint16_t>(last_pps_.size()));
|
||||||
buffer.AppendVector(last_pps_);
|
buffer.AppendVector(last_pps_);
|
||||||
buffer.SwapBuffer(decoder_config);
|
buffer.SwapBuffer(decoder_config);
|
||||||
|
|
||||||
|
|
|
@ -33,24 +33,24 @@ class H264ByteToUnitStreamConverter {
|
||||||
/// @param output_frame is a pointer to a vector which will receive the
|
/// @param output_frame is a pointer to a vector which will receive the
|
||||||
/// converted frame.
|
/// converted frame.
|
||||||
/// @return true if successful, false otherwise.
|
/// @return true if successful, false otherwise.
|
||||||
bool ConvertByteStreamToNalUnitStream(const uint8* input_frame,
|
bool ConvertByteStreamToNalUnitStream(const uint8_t* input_frame,
|
||||||
size_t input_frame_size,
|
size_t input_frame_size,
|
||||||
std::vector<uint8>* output_frame);
|
std::vector<uint8_t>* output_frame);
|
||||||
|
|
||||||
/// Synthesizes an AVCDecoderConfigurationRecord from the SPS and PPS NAL
|
/// Synthesizes an AVCDecoderConfigurationRecord from the SPS and PPS NAL
|
||||||
/// units extracted from the AVC byte stream.
|
/// units extracted from the AVC byte stream.
|
||||||
/// @param decoder_config is a pointer to a vector, which on successful
|
/// @param decoder_config is a pointer to a vector, which on successful
|
||||||
/// return will contain the computed AVCDecoderConfigurationRecord.
|
/// return will contain the computed AVCDecoderConfigurationRecord.
|
||||||
/// @return true if successful, or false otherwise.
|
/// @return true if successful, or false otherwise.
|
||||||
bool GetAVCDecoderConfigurationRecord(std::vector<uint8>* decoder_config);
|
bool GetAVCDecoderConfigurationRecord(std::vector<uint8_t>* decoder_config);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ProcessNalu(const uint8* nalu_ptr,
|
void ProcessNalu(const uint8_t* nalu_ptr,
|
||||||
size_t nalu_size,
|
size_t nalu_size,
|
||||||
BufferWriter* output_buffer);
|
BufferWriter* output_buffer);
|
||||||
|
|
||||||
std::vector<uint8> last_sps_;
|
std::vector<uint8_t> last_sps_;
|
||||||
std::vector<uint8> last_pps_;
|
std::vector<uint8_t> last_pps_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace media
|
} // namespace media
|
||||||
|
|
|
@ -21,41 +21,41 @@ namespace edash_packager {
|
||||||
namespace media {
|
namespace media {
|
||||||
|
|
||||||
TEST(H264ByteToUnitStreamConverter, ConversionSuccess) {
|
TEST(H264ByteToUnitStreamConverter, ConversionSuccess) {
|
||||||
std::vector<uint8> input_frame =
|
std::vector<uint8_t> input_frame =
|
||||||
ReadTestDataFile("avc-byte-stream-frame.h264");
|
ReadTestDataFile("avc-byte-stream-frame.h264");
|
||||||
ASSERT_FALSE(input_frame.empty());
|
ASSERT_FALSE(input_frame.empty());
|
||||||
|
|
||||||
std::vector<uint8> expected_output_frame =
|
std::vector<uint8_t> expected_output_frame =
|
||||||
ReadTestDataFile("avc-unit-stream-frame.h264");
|
ReadTestDataFile("avc-unit-stream-frame.h264");
|
||||||
ASSERT_FALSE(expected_output_frame.empty());
|
ASSERT_FALSE(expected_output_frame.empty());
|
||||||
|
|
||||||
H264ByteToUnitStreamConverter converter;
|
H264ByteToUnitStreamConverter converter;
|
||||||
std::vector<uint8> output_frame;
|
std::vector<uint8_t> output_frame;
|
||||||
ASSERT_TRUE(converter.ConvertByteStreamToNalUnitStream(input_frame.data(),
|
ASSERT_TRUE(converter.ConvertByteStreamToNalUnitStream(input_frame.data(),
|
||||||
input_frame.size(),
|
input_frame.size(),
|
||||||
&output_frame));
|
&output_frame));
|
||||||
EXPECT_EQ(expected_output_frame, output_frame);
|
EXPECT_EQ(expected_output_frame, output_frame);
|
||||||
|
|
||||||
std::vector<uint8> expected_decoder_config;
|
std::vector<uint8_t> expected_decoder_config;
|
||||||
ASSERT_TRUE(base::HexStringToBytes(kExpectedConfigRecord,
|
ASSERT_TRUE(base::HexStringToBytes(kExpectedConfigRecord,
|
||||||
&expected_decoder_config));
|
&expected_decoder_config));
|
||||||
std::vector<uint8> decoder_config;
|
std::vector<uint8_t> decoder_config;
|
||||||
ASSERT_TRUE(converter.GetAVCDecoderConfigurationRecord(&decoder_config));
|
ASSERT_TRUE(converter.GetAVCDecoderConfigurationRecord(&decoder_config));
|
||||||
EXPECT_EQ(expected_decoder_config, decoder_config);
|
EXPECT_EQ(expected_decoder_config, decoder_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(H264ByteToUnitStreamConverter, ConversionFailure) {
|
TEST(H264ByteToUnitStreamConverter, ConversionFailure) {
|
||||||
std::vector<uint8> input_frame(100, 0);
|
std::vector<uint8_t> input_frame(100, 0);
|
||||||
|
|
||||||
H264ByteToUnitStreamConverter converter;
|
H264ByteToUnitStreamConverter converter;
|
||||||
std::vector<uint8> output_frame;
|
std::vector<uint8_t> output_frame;
|
||||||
EXPECT_FALSE(converter.ConvertByteStreamToNalUnitStream(input_frame.data(),
|
EXPECT_FALSE(converter.ConvertByteStreamToNalUnitStream(input_frame.data(),
|
||||||
0,
|
0,
|
||||||
&output_frame));
|
&output_frame));
|
||||||
EXPECT_FALSE(converter.ConvertByteStreamToNalUnitStream(input_frame.data(),
|
EXPECT_FALSE(converter.ConvertByteStreamToNalUnitStream(input_frame.data(),
|
||||||
input_frame.size(),
|
input_frame.size(),
|
||||||
&output_frame));
|
&output_frame));
|
||||||
std::vector<uint8> decoder_config;
|
std::vector<uint8_t> decoder_config;
|
||||||
EXPECT_FALSE(converter.GetAVCDecoderConfigurationRecord(&decoder_config));
|
EXPECT_FALSE(converter.GetAVCDecoderConfigurationRecord(&decoder_config));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,7 +136,7 @@ void H264Parser::Reset() {
|
||||||
bytes_left_ = 0;
|
bytes_left_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void H264Parser::SetStream(const uint8* stream, off_t stream_size) {
|
void H264Parser::SetStream(const uint8_t* stream, off_t stream_size) {
|
||||||
DCHECK(stream);
|
DCHECK(stream);
|
||||||
DCHECK_GT(stream_size, 0);
|
DCHECK_GT(stream_size, 0);
|
||||||
|
|
||||||
|
@ -152,13 +152,15 @@ const H264SPS* H264Parser::GetSPS(int sps_id) {
|
||||||
return active_SPSes_[sps_id];
|
return active_SPSes_[sps_id];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool IsStartCode(const uint8* data) {
|
static inline bool IsStartCode(const uint8_t* data) {
|
||||||
return data[0] == 0x00 && data[1] == 0x00 && data[2] == 0x01;
|
return data[0] == 0x00 && data[1] == 0x00 && data[2] == 0x01;
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool H264Parser::FindStartCode(const uint8* data, off_t data_size,
|
bool H264Parser::FindStartCode(const uint8_t* data,
|
||||||
off_t* offset, off_t* start_code_size) {
|
off_t data_size,
|
||||||
|
off_t* offset,
|
||||||
|
off_t* start_code_size) {
|
||||||
DCHECK_GE(data_size, 0);
|
DCHECK_GE(data_size, 0);
|
||||||
off_t bytes_left = data_size;
|
off_t bytes_left = data_size;
|
||||||
|
|
||||||
|
@ -206,7 +208,7 @@ bool H264Parser::LocateNALU(off_t* nalu_size, off_t* start_code_size) {
|
||||||
stream_ += nalu_start_off;
|
stream_ += nalu_start_off;
|
||||||
bytes_left_ -= nalu_start_off;
|
bytes_left_ -= nalu_start_off;
|
||||||
|
|
||||||
const uint8* nalu_data = stream_ + annexb_start_code_size;
|
const uint8_t* nalu_data = stream_ + annexb_start_code_size;
|
||||||
off_t max_nalu_data_size = bytes_left_ - annexb_start_code_size;
|
off_t max_nalu_data_size = bytes_left_ - annexb_start_code_size;
|
||||||
if (max_nalu_data_size <= 0) {
|
if (max_nalu_data_size <= 0) {
|
||||||
DVLOG(3) << "End of stream";
|
DVLOG(3) << "End of stream";
|
||||||
|
|
|
@ -37,7 +37,7 @@ struct H264NALU {
|
||||||
|
|
||||||
// After (without) start code; we don't own the underlying memory
|
// After (without) start code; we don't own the underlying memory
|
||||||
// and a shallow copy should be made when copying this struct.
|
// and a shallow copy should be made when copying this struct.
|
||||||
const uint8* data;
|
const uint8_t* data;
|
||||||
off_t size; // From after start code to start code of next NALU (or EOS).
|
off_t size; // From after start code to start code of next NALU (or EOS).
|
||||||
|
|
||||||
int nal_ref_idc;
|
int nal_ref_idc;
|
||||||
|
@ -180,7 +180,7 @@ struct H264SliceHeader {
|
||||||
|
|
||||||
bool idr_pic_flag; // from NAL header
|
bool idr_pic_flag; // from NAL header
|
||||||
int nal_ref_idc; // from NAL header
|
int nal_ref_idc; // from NAL header
|
||||||
const uint8* nalu_data; // from NAL header
|
const uint8_t* nalu_data; // from NAL header
|
||||||
off_t nalu_size; // from NAL header
|
off_t nalu_size; // from NAL header
|
||||||
off_t header_bit_size; // calculated
|
off_t header_bit_size; // calculated
|
||||||
|
|
||||||
|
@ -277,8 +277,10 @@ class H264Parser {
|
||||||
// - |*offset| is between 0 and |data_size| included.
|
// - |*offset| is between 0 and |data_size| included.
|
||||||
// It is strictly less than |data_size| if |data_size| > 0.
|
// It is strictly less than |data_size| if |data_size| > 0.
|
||||||
// - |*start_code_size| is either 0, 3 or 4.
|
// - |*start_code_size| is either 0, 3 or 4.
|
||||||
static bool FindStartCode(const uint8* data, off_t data_size,
|
static bool FindStartCode(const uint8_t* data,
|
||||||
off_t* offset, off_t* start_code_size);
|
off_t data_size,
|
||||||
|
off_t* offset,
|
||||||
|
off_t* start_code_size);
|
||||||
|
|
||||||
H264Parser();
|
H264Parser();
|
||||||
~H264Parser();
|
~H264Parser();
|
||||||
|
@ -286,7 +288,7 @@ class H264Parser {
|
||||||
void Reset();
|
void Reset();
|
||||||
// Set current stream pointer to |stream| of |stream_size| in bytes,
|
// Set current stream pointer to |stream| of |stream_size| in bytes,
|
||||||
// |stream| owned by caller.
|
// |stream| owned by caller.
|
||||||
void SetStream(const uint8* stream, off_t stream_size);
|
void SetStream(const uint8_t* stream, off_t stream_size);
|
||||||
|
|
||||||
// Read the stream to find the next NALU, identify it and return
|
// Read the stream to find the next NALU, identify it and return
|
||||||
// that information in |*nalu|. This advances the stream to the beginning
|
// that information in |*nalu|. This advances the stream to the beginning
|
||||||
|
@ -376,7 +378,7 @@ class H264Parser {
|
||||||
Result ParseDecRefPicMarking(H264SliceHeader* shdr);
|
Result ParseDecRefPicMarking(H264SliceHeader* shdr);
|
||||||
|
|
||||||
// Pointer to the current NALU in the stream.
|
// Pointer to the current NALU in the stream.
|
||||||
const uint8* stream_;
|
const uint8_t* stream_;
|
||||||
|
|
||||||
// Bytes left in the stream after the current NALU.
|
// Bytes left in the stream after the current NALU.
|
||||||
off_t bytes_left_;
|
off_t bytes_left_;
|
||||||
|
|
|
@ -20,7 +20,7 @@ AdtsHeader::AdtsHeader()
|
||||||
sampling_frequency_index_(0),
|
sampling_frequency_index_(0),
|
||||||
channel_configuration_(0) {}
|
channel_configuration_(0) {}
|
||||||
|
|
||||||
size_t AdtsHeader::GetAdtsFrameSize(const uint8* data, size_t num_bytes) {
|
size_t AdtsHeader::GetAdtsFrameSize(const uint8_t* data, size_t num_bytes) {
|
||||||
if (num_bytes < 6)
|
if (num_bytes < 6)
|
||||||
return 0;
|
return 0;
|
||||||
return ((static_cast<int>(data[5]) >> 5) |
|
return ((static_cast<int>(data[5]) >> 5) |
|
||||||
|
@ -28,23 +28,22 @@ size_t AdtsHeader::GetAdtsFrameSize(const uint8* data, size_t num_bytes) {
|
||||||
((static_cast<int>(data[3]) & 0x3) << 11));
|
((static_cast<int>(data[3]) & 0x3) << 11));
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t AdtsHeader::GetAdtsHeaderSize(const uint8* data, size_t num_bytes) {
|
size_t AdtsHeader::GetAdtsHeaderSize(const uint8_t* data, size_t num_bytes) {
|
||||||
if (num_bytes < 2)
|
if (num_bytes < 2)
|
||||||
return 0;
|
return 0;
|
||||||
if (data[1] & 0x01)
|
if (data[1] & 0x01)
|
||||||
return kAdtsHeaderMinSize;
|
return kAdtsHeaderMinSize;
|
||||||
return kAdtsHeaderMinSize + sizeof(uint16); // Header + CRC.
|
return kAdtsHeaderMinSize + sizeof(uint16_t); // Header + CRC.
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdtsHeader::Parse(
|
bool AdtsHeader::Parse(const uint8_t* adts_frame, size_t adts_frame_size) {
|
||||||
const uint8* adts_frame, size_t adts_frame_size) {
|
|
||||||
CHECK(adts_frame);
|
CHECK(adts_frame);
|
||||||
|
|
||||||
valid_config_ = false;
|
valid_config_ = false;
|
||||||
|
|
||||||
BitReader frame(adts_frame, adts_frame_size);
|
BitReader frame(adts_frame, adts_frame_size);
|
||||||
// Verify frame starts with sync bits (0xfff).
|
// Verify frame starts with sync bits (0xfff).
|
||||||
uint32 sync;
|
uint32_t sync;
|
||||||
RCHECK(frame.ReadBits(12, &sync));
|
RCHECK(frame.ReadBits(12, &sync));
|
||||||
RCHECK(sync == 0xfff);
|
RCHECK(sync == 0xfff);
|
||||||
// Skip MPEG version and layer.
|
// Skip MPEG version and layer.
|
||||||
|
@ -66,12 +65,12 @@ bool AdtsHeader::Parse(
|
||||||
// Skip originality, home and copyright info.
|
// Skip originality, home and copyright info.
|
||||||
RCHECK(frame.SkipBits(4));
|
RCHECK(frame.SkipBits(4));
|
||||||
// Verify that the frame size matches input parameters.
|
// Verify that the frame size matches input parameters.
|
||||||
uint16 frame_size;
|
uint16_t frame_size;
|
||||||
RCHECK(frame.ReadBits(13, &frame_size));
|
RCHECK(frame.ReadBits(13, &frame_size));
|
||||||
RCHECK(frame_size == adts_frame_size);
|
RCHECK(frame_size == adts_frame_size);
|
||||||
// Skip buffer fullness indicator.
|
// Skip buffer fullness indicator.
|
||||||
RCHECK(frame.SkipBits(11));
|
RCHECK(frame.SkipBits(11));
|
||||||
uint8 num_blocks_minus_1;
|
uint8_t num_blocks_minus_1;
|
||||||
RCHECK(frame.ReadBits(2, &num_blocks_minus_1));
|
RCHECK(frame.ReadBits(2, &num_blocks_minus_1));
|
||||||
if (num_blocks_minus_1) {
|
if (num_blocks_minus_1) {
|
||||||
NOTIMPLEMENTED() << "ADTS frames with more than one data block "
|
NOTIMPLEMENTED() << "ADTS frames with more than one data block "
|
||||||
|
@ -83,8 +82,7 @@ bool AdtsHeader::Parse(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdtsHeader::GetAudioSpecificConfig(
|
bool AdtsHeader::GetAudioSpecificConfig(std::vector<uint8_t>* buffer) const {
|
||||||
std::vector<uint8>* buffer) const {
|
|
||||||
DCHECK(buffer);
|
DCHECK(buffer);
|
||||||
if (!valid_config_)
|
if (!valid_config_)
|
||||||
return false;
|
return false;
|
||||||
|
@ -96,16 +94,16 @@ bool AdtsHeader::GetAudioSpecificConfig(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 AdtsHeader::GetObjectType() const {
|
uint8_t AdtsHeader::GetObjectType() const {
|
||||||
return profile_ + 1;
|
return profile_ + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 AdtsHeader::GetSamplingFrequency() const {
|
uint32_t AdtsHeader::GetSamplingFrequency() const {
|
||||||
DCHECK_LT(sampling_frequency_index_, kAdtsFrequencyTableSize);
|
DCHECK_LT(sampling_frequency_index_, kAdtsFrequencyTableSize);
|
||||||
return kAdtsFrequencyTable[sampling_frequency_index_];
|
return kAdtsFrequencyTable[sampling_frequency_index_];
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 AdtsHeader::GetNumChannels() const {
|
uint8_t AdtsHeader::GetNumChannels() const {
|
||||||
DCHECK_GT(channel_configuration_, 0);
|
DCHECK_GT(channel_configuration_, 0);
|
||||||
DCHECK_LT(channel_configuration_, kAdtsNumChannelsTableSize);
|
DCHECK_LT(channel_configuration_, kAdtsNumChannelsTableSize);
|
||||||
return kAdtsNumChannelsTable[channel_configuration_];
|
return kAdtsNumChannelsTable[channel_configuration_];
|
||||||
|
|
|
@ -27,42 +27,42 @@ class AdtsHeader {
|
||||||
/// @param num_bytes is the number of data bytes at @a data.
|
/// @param num_bytes is the number of data bytes at @a data.
|
||||||
/// @return Size of the ADTS frame (header + payload) if successful, or
|
/// @return Size of the ADTS frame (header + payload) if successful, or
|
||||||
/// zero otherwise.
|
/// zero otherwise.
|
||||||
static size_t GetAdtsFrameSize(const uint8* data, size_t num_bytes);
|
static size_t GetAdtsFrameSize(const uint8_t* data, size_t num_bytes);
|
||||||
|
|
||||||
/// Get the size of the ADTS header from a partial or complete frame.
|
/// Get the size of the ADTS header from a partial or complete frame.
|
||||||
/// @param data is a pointer to the beginning of the ADTS frame.
|
/// @param data is a pointer to the beginning of the ADTS frame.
|
||||||
/// @param num_bytes is the number of data bytes at @a data.
|
/// @param num_bytes is the number of data bytes at @a data.
|
||||||
/// @return Size of the ADTS header if successful, or zero otherwise.
|
/// @return Size of the ADTS header if successful, or zero otherwise.
|
||||||
static size_t GetAdtsHeaderSize(const uint8* data, size_t num_bytes);
|
static size_t GetAdtsHeaderSize(const uint8_t* data, size_t num_bytes);
|
||||||
|
|
||||||
/// Parse an ADTS header, extracting the fields within.
|
/// Parse an ADTS header, extracting the fields within.
|
||||||
/// @param adts_frame is an input parameter pointing to the ADTS header
|
/// @param adts_frame is an input parameter pointing to the ADTS header
|
||||||
/// of an ADTS-framed audio sample.
|
/// of an ADTS-framed audio sample.
|
||||||
/// @param adts_frame_size is the size, in bytes of the input ADTS frame.
|
/// @param adts_frame_size is the size, in bytes of the input ADTS frame.
|
||||||
/// @return true if successful, false otherwise.
|
/// @return true if successful, false otherwise.
|
||||||
bool Parse(const uint8* adts_frame, size_t adts_frame_size);
|
bool Parse(const uint8_t* adts_frame, size_t adts_frame_size);
|
||||||
|
|
||||||
/// Synthesize an AudioSpecificConfig record from the fields within the ADTS
|
/// Synthesize an AudioSpecificConfig record from the fields within the ADTS
|
||||||
/// header.
|
/// header.
|
||||||
/// @param [out] buffer is a pointer to a vector to contain the
|
/// @param [out] buffer is a pointer to a vector to contain the
|
||||||
/// AudioSpecificConfig.
|
/// AudioSpecificConfig.
|
||||||
/// @return true if successful, false otherwise.
|
/// @return true if successful, false otherwise.
|
||||||
bool GetAudioSpecificConfig(std::vector<uint8>* buffer) const;
|
bool GetAudioSpecificConfig(std::vector<uint8_t>* buffer) const;
|
||||||
|
|
||||||
/// @return The audio profile for this ADTS frame.
|
/// @return The audio profile for this ADTS frame.
|
||||||
uint8 GetObjectType() const;
|
uint8_t GetObjectType() const;
|
||||||
|
|
||||||
/// @return The sampling frequency for this ADTS frame.
|
/// @return The sampling frequency for this ADTS frame.
|
||||||
uint32 GetSamplingFrequency() const;
|
uint32_t GetSamplingFrequency() const;
|
||||||
|
|
||||||
/// @return Number of channels for this AAC config.
|
/// @return Number of channels for this AAC config.
|
||||||
uint8 GetNumChannels() const;
|
uint8_t GetNumChannels() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool valid_config_;
|
bool valid_config_;
|
||||||
uint8 profile_;
|
uint8_t profile_;
|
||||||
uint8 sampling_frequency_index_;
|
uint8_t sampling_frequency_index_;
|
||||||
uint8 channel_configuration_;
|
uint8_t channel_configuration_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(AdtsHeader);
|
DISALLOW_COPY_AND_ASSIGN(AdtsHeader);
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,7 +30,7 @@ const char kValidAdtsFrame[] =
|
||||||
"f2112c2202973b00de71bb49f906ed1bc63768dda378c8f9c6ed1bb48f68"
|
"f2112c2202973b00de71bb49f906ed1bc63768dda378c8f9c6ed1bb48f68"
|
||||||
"dda378c9f68dda3768dda3768de323da3768de31bb4e";
|
"dda378c9f68dda3768dda3768de323da3768de31bb4e";
|
||||||
|
|
||||||
const uint8 kExpectedAudioSpecificConfig[] = { 0x12, 0x10 };
|
const uint8_t kExpectedAudioSpecificConfig[] = {0x12, 0x10};
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
|
@ -45,27 +45,26 @@ class AdtsHeaderTest : public testing::Test {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::vector<uint8> adts_frame_;
|
std::vector<uint8_t> adts_frame_;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(AdtsHeaderTest, ParseSuccess) {
|
TEST_F(AdtsHeaderTest, ParseSuccess) {
|
||||||
const uint8 kExpectedObjectType(2);
|
const uint8_t kExpectedObjectType(2);
|
||||||
const uint32 kExpectedSamplingFrequency(44100);
|
const uint32_t kExpectedSamplingFrequency(44100);
|
||||||
const uint8 kExpectedNumChannels(2);
|
const uint8_t kExpectedNumChannels(2);
|
||||||
AdtsHeader adts_header;
|
AdtsHeader adts_header;
|
||||||
EXPECT_TRUE(adts_header.Parse(adts_frame_.data(), adts_frame_.size()));
|
EXPECT_TRUE(adts_header.Parse(adts_frame_.data(), adts_frame_.size()));
|
||||||
EXPECT_EQ(kExpectedObjectType, adts_header.GetObjectType());
|
EXPECT_EQ(kExpectedObjectType, adts_header.GetObjectType());
|
||||||
EXPECT_EQ(kExpectedSamplingFrequency, adts_header.GetSamplingFrequency());
|
EXPECT_EQ(kExpectedSamplingFrequency, adts_header.GetSamplingFrequency());
|
||||||
EXPECT_EQ(kExpectedNumChannels, adts_header.GetNumChannels());
|
EXPECT_EQ(kExpectedNumChannels, adts_header.GetNumChannels());
|
||||||
std::vector<uint8> audio_specific_config;
|
std::vector<uint8_t> audio_specific_config;
|
||||||
ASSERT_TRUE(adts_header.GetAudioSpecificConfig(&audio_specific_config));
|
ASSERT_TRUE(adts_header.GetAudioSpecificConfig(&audio_specific_config));
|
||||||
EXPECT_EQ(arraysize(kExpectedAudioSpecificConfig),
|
EXPECT_EQ(arraysize(kExpectedAudioSpecificConfig),
|
||||||
audio_specific_config.size());
|
audio_specific_config.size());
|
||||||
EXPECT_EQ(
|
EXPECT_EQ(std::vector<uint8_t>(kExpectedAudioSpecificConfig,
|
||||||
std::vector<uint8>(
|
kExpectedAudioSpecificConfig +
|
||||||
kExpectedAudioSpecificConfig,
|
arraysize(kExpectedAudioSpecificConfig)),
|
||||||
kExpectedAudioSpecificConfig + arraysize(kExpectedAudioSpecificConfig)),
|
audio_specific_config);
|
||||||
audio_specific_config);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(AdtsHeaderTest, ParseFailFrameSize) {
|
TEST_F(AdtsHeaderTest, ParseFailFrameSize) {
|
||||||
|
|
|
@ -20,15 +20,18 @@ namespace mp2t {
|
||||||
class EsParser {
|
class EsParser {
|
||||||
public:
|
public:
|
||||||
typedef base::Callback<void(scoped_refptr<StreamInfo>&)> NewStreamInfoCB;
|
typedef base::Callback<void(scoped_refptr<StreamInfo>&)> NewStreamInfoCB;
|
||||||
typedef base::Callback<void(uint32, scoped_refptr<MediaSample>&)> EmitSampleCB;
|
typedef base::Callback<void(uint32_t, scoped_refptr<MediaSample>&)>
|
||||||
|
EmitSampleCB;
|
||||||
|
|
||||||
EsParser(uint32 pid)
|
EsParser(uint32_t pid) : pid_(pid) {}
|
||||||
: pid_(pid) {}
|
|
||||||
virtual ~EsParser() {}
|
virtual ~EsParser() {}
|
||||||
|
|
||||||
// ES parsing.
|
// ES parsing.
|
||||||
// Should use kNoTimestamp when a timestamp is not valid.
|
// Should use kNoTimestamp when a timestamp is not valid.
|
||||||
virtual bool Parse(const uint8* buf, int size, int64 pts, int64 dts) = 0;
|
virtual bool Parse(const uint8_t* buf,
|
||||||
|
int size,
|
||||||
|
int64_t pts,
|
||||||
|
int64_t dts) = 0;
|
||||||
|
|
||||||
// Flush any pending buffer.
|
// Flush any pending buffer.
|
||||||
virtual void Flush() = 0;
|
virtual void Flush() = 0;
|
||||||
|
@ -36,10 +39,10 @@ class EsParser {
|
||||||
// Reset the state of the ES parser.
|
// Reset the state of the ES parser.
|
||||||
virtual void Reset() = 0;
|
virtual void Reset() = 0;
|
||||||
|
|
||||||
uint32 pid() { return pid_; }
|
uint32_t pid() { return pid_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32 pid_;
|
uint32_t pid_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mp2t
|
} // namespace mp2t
|
||||||
|
|
|
@ -22,7 +22,7 @@ namespace media {
|
||||||
|
|
||||||
// Return true if buf corresponds to an ADTS syncword.
|
// Return true if buf corresponds to an ADTS syncword.
|
||||||
// |buf| size must be at least 2.
|
// |buf| size must be at least 2.
|
||||||
static bool isAdtsSyncWord(const uint8* buf) {
|
static bool isAdtsSyncWord(const uint8_t* buf) {
|
||||||
return (buf[0] == 0xff) && ((buf[1] & 0xf6) == 0xf0);
|
return (buf[0] == 0xff) && ((buf[1] & 0xf6) == 0xf0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,9 +33,11 @@ static bool isAdtsSyncWord(const uint8* buf) {
|
||||||
// In every case, the returned value in |new_pos| is such that new_pos >= pos
|
// In every case, the returned value in |new_pos| is such that new_pos >= pos
|
||||||
// |frame_sz| returns the size of the ADTS frame (if found).
|
// |frame_sz| returns the size of the ADTS frame (if found).
|
||||||
// Return whether a syncword was found.
|
// Return whether a syncword was found.
|
||||||
static bool LookForSyncWord(const uint8* raw_es, int raw_es_size,
|
static bool LookForSyncWord(const uint8_t* raw_es,
|
||||||
|
int raw_es_size,
|
||||||
int pos,
|
int pos,
|
||||||
int* new_pos, int* frame_sz) {
|
int* new_pos,
|
||||||
|
int* frame_sz) {
|
||||||
DCHECK_GE(pos, 0);
|
DCHECK_GE(pos, 0);
|
||||||
DCHECK_LE(pos, raw_es_size);
|
DCHECK_LE(pos, raw_es_size);
|
||||||
|
|
||||||
|
@ -52,7 +54,7 @@ static bool LookForSyncWord(const uint8* raw_es, int raw_es_size,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int offset = pos; offset < max_offset; offset++) {
|
for (int offset = pos; offset < max_offset; offset++) {
|
||||||
const uint8* cur_buf = &raw_es[offset];
|
const uint8_t* cur_buf = &raw_es[offset];
|
||||||
|
|
||||||
if (!isAdtsSyncWord(cur_buf))
|
if (!isAdtsSyncWord(cur_buf))
|
||||||
// The first 12 bits must be 1.
|
// The first 12 bits must be 1.
|
||||||
|
@ -85,11 +87,10 @@ static bool LookForSyncWord(const uint8* raw_es, int raw_es_size,
|
||||||
|
|
||||||
namespace mp2t {
|
namespace mp2t {
|
||||||
|
|
||||||
EsParserAdts::EsParserAdts(
|
EsParserAdts::EsParserAdts(uint32_t pid,
|
||||||
uint32 pid,
|
const NewStreamInfoCB& new_stream_info_cb,
|
||||||
const NewStreamInfoCB& new_stream_info_cb,
|
const EmitSampleCB& emit_sample_cb,
|
||||||
const EmitSampleCB& emit_sample_cb,
|
bool sbr_in_mimetype)
|
||||||
bool sbr_in_mimetype)
|
|
||||||
: EsParser(pid),
|
: EsParser(pid),
|
||||||
new_stream_info_cb_(new_stream_info_cb),
|
new_stream_info_cb_(new_stream_info_cb),
|
||||||
emit_sample_cb_(emit_sample_cb),
|
emit_sample_cb_(emit_sample_cb),
|
||||||
|
@ -99,9 +100,12 @@ EsParserAdts::EsParserAdts(
|
||||||
EsParserAdts::~EsParserAdts() {
|
EsParserAdts::~EsParserAdts() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EsParserAdts::Parse(const uint8* buf, int size, int64 pts, int64 dts) {
|
bool EsParserAdts::Parse(const uint8_t* buf,
|
||||||
|
int size,
|
||||||
|
int64_t pts,
|
||||||
|
int64_t dts) {
|
||||||
int raw_es_size;
|
int raw_es_size;
|
||||||
const uint8* raw_es;
|
const uint8_t* raw_es;
|
||||||
|
|
||||||
// The incoming PTS applies to the access unit that comes just after
|
// The incoming PTS applies to the access unit that comes just after
|
||||||
// the beginning of |buf|.
|
// the beginning of |buf|.
|
||||||
|
@ -119,7 +123,7 @@ bool EsParserAdts::Parse(const uint8* buf, int size, int64 pts, int64 dts) {
|
||||||
int frame_size;
|
int frame_size;
|
||||||
while (LookForSyncWord(raw_es, raw_es_size, es_position,
|
while (LookForSyncWord(raw_es, raw_es_size, es_position,
|
||||||
&es_position, &frame_size)) {
|
&es_position, &frame_size)) {
|
||||||
const uint8* frame_ptr = raw_es + es_position;
|
const uint8_t* frame_ptr = raw_es + es_position;
|
||||||
DVLOG(LOG_LEVEL_ES)
|
DVLOG(LOG_LEVEL_ES)
|
||||||
<< "ADTS syncword @ pos=" << es_position
|
<< "ADTS syncword @ pos=" << es_position
|
||||||
<< " frame_size=" << frame_size;
|
<< " frame_size=" << frame_size;
|
||||||
|
@ -146,8 +150,8 @@ bool EsParserAdts::Parse(const uint8* buf, int size, int64 pts, int64 dts) {
|
||||||
pts_list_.pop_front();
|
pts_list_.pop_front();
|
||||||
}
|
}
|
||||||
|
|
||||||
int64 current_pts = audio_timestamp_helper_->GetTimestamp();
|
int64_t current_pts = audio_timestamp_helper_->GetTimestamp();
|
||||||
int64 frame_duration =
|
int64_t frame_duration =
|
||||||
audio_timestamp_helper_->GetFrameDuration(kSamplesPerAACFrame);
|
audio_timestamp_helper_->GetFrameDuration(kSamplesPerAACFrame);
|
||||||
|
|
||||||
// Emit an audio frame.
|
// Emit an audio frame.
|
||||||
|
@ -185,17 +189,16 @@ void EsParserAdts::Reset() {
|
||||||
last_audio_decoder_config_ = scoped_refptr<AudioStreamInfo>();
|
last_audio_decoder_config_ = scoped_refptr<AudioStreamInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EsParserAdts::UpdateAudioConfiguration(const uint8* adts_frame,
|
bool EsParserAdts::UpdateAudioConfiguration(const uint8_t* adts_frame,
|
||||||
size_t adts_frame_size) {
|
size_t adts_frame_size) {
|
||||||
|
const uint8_t kAacSampleSizeBits(16);
|
||||||
const uint8 kAacSampleSizeBits(16);
|
|
||||||
|
|
||||||
AdtsHeader adts_header;
|
AdtsHeader adts_header;
|
||||||
if (!adts_header.Parse(adts_frame, adts_frame_size)) {
|
if (!adts_header.Parse(adts_frame, adts_frame_size)) {
|
||||||
LOG(ERROR) << "Error parsing ADTS frame header.";
|
LOG(ERROR) << "Error parsing ADTS frame header.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::vector<uint8> audio_specific_config;
|
std::vector<uint8_t> audio_specific_config;
|
||||||
if (!adts_header.GetAudioSpecificConfig(&audio_specific_config))
|
if (!adts_header.GetAudioSpecificConfig(&audio_specific_config))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -239,7 +242,7 @@ bool EsParserAdts::UpdateAudioConfiguration(const uint8* adts_frame,
|
||||||
DVLOG(1) << "Object type: " << adts_header.GetObjectType();
|
DVLOG(1) << "Object type: " << adts_header.GetObjectType();
|
||||||
// Reset the timestamp helper to use a new sampling frequency.
|
// Reset the timestamp helper to use a new sampling frequency.
|
||||||
if (audio_timestamp_helper_) {
|
if (audio_timestamp_helper_) {
|
||||||
int64 base_timestamp = audio_timestamp_helper_->GetTimestamp();
|
int64_t base_timestamp = audio_timestamp_helper_->GetTimestamp();
|
||||||
audio_timestamp_helper_.reset(
|
audio_timestamp_helper_.reset(
|
||||||
new AudioTimestampHelper(kMpeg2Timescale, samples_per_second));
|
new AudioTimestampHelper(kMpeg2Timescale, samples_per_second));
|
||||||
audio_timestamp_helper_->SetBaseTimestamp(base_timestamp);
|
audio_timestamp_helper_->SetBaseTimestamp(base_timestamp);
|
||||||
|
|
|
@ -24,28 +24,29 @@ namespace mp2t {
|
||||||
|
|
||||||
class EsParserAdts : public EsParser {
|
class EsParserAdts : public EsParser {
|
||||||
public:
|
public:
|
||||||
EsParserAdts(uint32 pid,
|
EsParserAdts(uint32_t pid,
|
||||||
const NewStreamInfoCB& new_stream_info_cb,
|
const NewStreamInfoCB& new_stream_info_cb,
|
||||||
const EmitSampleCB& emit_sample_cb,
|
const EmitSampleCB& emit_sample_cb,
|
||||||
bool sbr_in_mimetype);
|
bool sbr_in_mimetype);
|
||||||
virtual ~EsParserAdts();
|
virtual ~EsParserAdts();
|
||||||
|
|
||||||
// EsParser implementation.
|
// EsParser implementation.
|
||||||
virtual bool Parse(const uint8* buf, int size,
|
virtual bool Parse(const uint8_t* buf,
|
||||||
int64 pts,
|
int size,
|
||||||
int64 dts) OVERRIDE;
|
int64_t pts,
|
||||||
|
int64_t dts) OVERRIDE;
|
||||||
virtual void Flush() OVERRIDE;
|
virtual void Flush() OVERRIDE;
|
||||||
virtual void Reset() OVERRIDE;
|
virtual void Reset() OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Used to link a PTS with a byte position in the ES stream.
|
// Used to link a PTS with a byte position in the ES stream.
|
||||||
typedef std::pair<int, int64> EsPts;
|
typedef std::pair<int, int64_t> EsPts;
|
||||||
typedef std::list<EsPts> EsPtsList;
|
typedef std::list<EsPts> EsPtsList;
|
||||||
|
|
||||||
// Signal any audio configuration change (if any).
|
// Signal any audio configuration change (if any).
|
||||||
// Return false if the current audio config is not
|
// Return false if the current audio config is not
|
||||||
// a supported ADTS audio config.
|
// a supported ADTS audio config.
|
||||||
bool UpdateAudioConfiguration(const uint8* adts_frame, size_t frame_size);
|
bool UpdateAudioConfiguration(const uint8_t* adts_frame, size_t frame_size);
|
||||||
|
|
||||||
// Discard some bytes from the ES stream.
|
// Discard some bytes from the ES stream.
|
||||||
void DiscardEs(int nbytes);
|
void DiscardEs(int nbytes);
|
||||||
|
|
|
@ -27,10 +27,9 @@ const int kMinAUDSize = 4;
|
||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
EsParserH264::EsParserH264(
|
EsParserH264::EsParserH264(uint32_t pid,
|
||||||
uint32 pid,
|
const NewStreamInfoCB& new_stream_info_cb,
|
||||||
const NewStreamInfoCB& new_stream_info_cb,
|
const EmitSampleCB& emit_sample_cb)
|
||||||
const EmitSampleCB& emit_sample_cb)
|
|
||||||
: EsParser(pid),
|
: EsParser(pid),
|
||||||
new_stream_info_cb_(new_stream_info_cb),
|
new_stream_info_cb_(new_stream_info_cb),
|
||||||
emit_sample_cb_(emit_sample_cb),
|
emit_sample_cb_(emit_sample_cb),
|
||||||
|
@ -47,7 +46,10 @@ EsParserH264::EsParserH264(
|
||||||
EsParserH264::~EsParserH264() {
|
EsParserH264::~EsParserH264() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EsParserH264::Parse(const uint8* buf, int size, int64 pts, int64 dts) {
|
bool EsParserH264::Parse(const uint8_t* buf,
|
||||||
|
int size,
|
||||||
|
int64_t pts,
|
||||||
|
int64_t dts) {
|
||||||
// Note: Parse is invoked each time a PES packet has been reassembled.
|
// Note: Parse is invoked each time a PES packet has been reassembled.
|
||||||
// Unfortunately, a PES packet does not necessarily map
|
// Unfortunately, a PES packet does not necessarily map
|
||||||
// to an h264 access unit, although the HLS recommendation is to use one PES
|
// to an h264 access unit, although the HLS recommendation is to use one PES
|
||||||
|
@ -65,7 +67,7 @@ bool EsParserH264::Parse(const uint8* buf, int size, int64 pts, int64 dts) {
|
||||||
|
|
||||||
// Link the end of the byte queue with the incoming timing descriptor.
|
// Link the end of the byte queue with the incoming timing descriptor.
|
||||||
timing_desc_list_.push_back(
|
timing_desc_list_.push_back(
|
||||||
std::pair<int64, TimingDesc>(es_queue_->tail(), timing_desc));
|
std::pair<int64_t, TimingDesc>(es_queue_->tail(), timing_desc));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the incoming bytes to the ES queue.
|
// Add the incoming bytes to the ES queue.
|
||||||
|
@ -79,7 +81,7 @@ void EsParserH264::Flush() {
|
||||||
if (FindAUD(¤t_access_unit_pos_)) {
|
if (FindAUD(¤t_access_unit_pos_)) {
|
||||||
// Simulate an additional AUD to force emitting the last access unit
|
// Simulate an additional AUD to force emitting the last access unit
|
||||||
// which is assumed to be complete at this point.
|
// which is assumed to be complete at this point.
|
||||||
uint8 aud[] = { 0x00, 0x00, 0x01, 0x09 };
|
uint8_t aud[] = {0x00, 0x00, 0x01, 0x09};
|
||||||
es_queue_->Push(aud, sizeof(aud));
|
es_queue_->Push(aud, sizeof(aud));
|
||||||
ParseInternal();
|
ParseInternal();
|
||||||
}
|
}
|
||||||
|
@ -107,9 +109,9 @@ void EsParserH264::Reset() {
|
||||||
waiting_for_key_frame_ = true;
|
waiting_for_key_frame_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EsParserH264::FindAUD(int64* stream_pos) {
|
bool EsParserH264::FindAUD(int64_t* stream_pos) {
|
||||||
while (true) {
|
while (true) {
|
||||||
const uint8* es;
|
const uint8_t* es;
|
||||||
int size;
|
int size;
|
||||||
es_queue_->PeekAt(*stream_pos, &es, &size);
|
es_queue_->PeekAt(*stream_pos, &es, &size);
|
||||||
|
|
||||||
|
@ -170,10 +172,10 @@ bool EsParserH264::ParseInternal() {
|
||||||
bool is_key_frame = false;
|
bool is_key_frame = false;
|
||||||
int pps_id_for_access_unit = -1;
|
int pps_id_for_access_unit = -1;
|
||||||
|
|
||||||
const uint8* es;
|
const uint8_t* es;
|
||||||
int size;
|
int size;
|
||||||
es_queue_->PeekAt(current_access_unit_pos_, &es, &size);
|
es_queue_->PeekAt(current_access_unit_pos_, &es, &size);
|
||||||
int access_unit_size = base::checked_cast<int, int64>(
|
int access_unit_size = base::checked_cast<int, int64_t>(
|
||||||
next_access_unit_pos_ - current_access_unit_pos_);
|
next_access_unit_pos_ - current_access_unit_pos_);
|
||||||
DCHECK_LE(access_unit_size, size);
|
DCHECK_LE(access_unit_size, size);
|
||||||
h264_parser_->SetStream(es, access_unit_size);
|
h264_parser_->SetStream(es, access_unit_size);
|
||||||
|
@ -254,8 +256,10 @@ bool EsParserH264::ParseInternal() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EsParserH264::EmitFrame(int64 access_unit_pos, int access_unit_size,
|
bool EsParserH264::EmitFrame(int64_t access_unit_pos,
|
||||||
bool is_key_frame, int pps_id) {
|
int access_unit_size,
|
||||||
|
bool is_key_frame,
|
||||||
|
int pps_id) {
|
||||||
// Get the access unit timing info.
|
// Get the access unit timing info.
|
||||||
TimingDesc current_timing_desc = {kNoTimestamp, kNoTimestamp};
|
TimingDesc current_timing_desc = {kNoTimestamp, kNoTimestamp};
|
||||||
while (!timing_desc_list_.empty() &&
|
while (!timing_desc_list_.empty() &&
|
||||||
|
@ -270,12 +274,12 @@ bool EsParserH264::EmitFrame(int64 access_unit_pos, int access_unit_size,
|
||||||
DVLOG(LOG_LEVEL_ES) << "Emit frame: stream_pos=" << current_access_unit_pos_
|
DVLOG(LOG_LEVEL_ES) << "Emit frame: stream_pos=" << current_access_unit_pos_
|
||||||
<< " size=" << access_unit_size;
|
<< " size=" << access_unit_size;
|
||||||
int es_size;
|
int es_size;
|
||||||
const uint8* es;
|
const uint8_t* es;
|
||||||
es_queue_->PeekAt(current_access_unit_pos_, &es, &es_size);
|
es_queue_->PeekAt(current_access_unit_pos_, &es, &es_size);
|
||||||
CHECK_GE(es_size, access_unit_size);
|
CHECK_GE(es_size, access_unit_size);
|
||||||
|
|
||||||
// Convert frame to unit stream format.
|
// Convert frame to unit stream format.
|
||||||
std::vector<uint8> converted_frame;
|
std::vector<uint8_t> converted_frame;
|
||||||
if (!stream_converter_->ConvertByteStreamToNalUnitStream(
|
if (!stream_converter_->ConvertByteStreamToNalUnitStream(
|
||||||
es, access_unit_size, &converted_frame)) {
|
es, access_unit_size, &converted_frame)) {
|
||||||
DLOG(ERROR) << "Failure to convert video frame to unit stream format.";
|
DLOG(ERROR) << "Failure to convert video frame to unit stream format.";
|
||||||
|
@ -320,7 +324,7 @@ bool EsParserH264::EmitFrame(int64 access_unit_pos, int access_unit_size,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EsParserH264::UpdateVideoDecoderConfig(const H264SPS* sps) {
|
bool EsParserH264::UpdateVideoDecoderConfig(const H264SPS* sps) {
|
||||||
std::vector<uint8> decoder_config_record;
|
std::vector<uint8_t> decoder_config_record;
|
||||||
if (!stream_converter_->GetAVCDecoderConfigurationRecord(
|
if (!stream_converter_->GetAVCDecoderConfigurationRecord(
|
||||||
&decoder_config_record)) {
|
&decoder_config_record)) {
|
||||||
DLOG(ERROR) << "Failure to construct an AVCDecoderConfigurationRecord";
|
DLOG(ERROR) << "Failure to construct an AVCDecoderConfigurationRecord";
|
||||||
|
@ -342,8 +346,8 @@ bool EsParserH264::UpdateVideoDecoderConfig(const H264SPS* sps) {
|
||||||
|
|
||||||
// TODO: a MAP unit can be either 16 or 32 pixels.
|
// TODO: a MAP unit can be either 16 or 32 pixels.
|
||||||
// although it's 16 pixels for progressive non MBAFF frames.
|
// although it's 16 pixels for progressive non MBAFF frames.
|
||||||
uint16 width = (sps->pic_width_in_mbs_minus1 + 1) * 16;
|
uint16_t width = (sps->pic_width_in_mbs_minus1 + 1) * 16;
|
||||||
uint16 height = (sps->pic_height_in_map_units_minus1 + 1) * 16;
|
uint16_t height = (sps->pic_height_in_map_units_minus1 + 1) * 16;
|
||||||
|
|
||||||
last_video_decoder_config_ = scoped_refptr<StreamInfo>(
|
last_video_decoder_config_ = scoped_refptr<StreamInfo>(
|
||||||
new VideoStreamInfo(
|
new VideoStreamInfo(
|
||||||
|
|
|
@ -31,20 +31,23 @@ namespace mp2t {
|
||||||
//
|
//
|
||||||
class EsParserH264 : public EsParser {
|
class EsParserH264 : public EsParser {
|
||||||
public:
|
public:
|
||||||
EsParserH264(uint32 pid,
|
EsParserH264(uint32_t pid,
|
||||||
const NewStreamInfoCB& new_stream_info_cb,
|
const NewStreamInfoCB& new_stream_info_cb,
|
||||||
const EmitSampleCB& emit_sample_cb);
|
const EmitSampleCB& emit_sample_cb);
|
||||||
virtual ~EsParserH264();
|
virtual ~EsParserH264();
|
||||||
|
|
||||||
// EsParser implementation overrides.
|
// EsParser implementation overrides.
|
||||||
virtual bool Parse(const uint8* buf, int size, int64 pts, int64 dts) OVERRIDE;
|
virtual bool Parse(const uint8_t* buf,
|
||||||
|
int size,
|
||||||
|
int64_t pts,
|
||||||
|
int64_t dts) OVERRIDE;
|
||||||
virtual void Flush() OVERRIDE;
|
virtual void Flush() OVERRIDE;
|
||||||
virtual void Reset() OVERRIDE;
|
virtual void Reset() OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct TimingDesc {
|
struct TimingDesc {
|
||||||
int64 dts;
|
int64_t dts;
|
||||||
int64 pts;
|
int64_t pts;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Find the AUD located at or after |*stream_pos|.
|
// Find the AUD located at or after |*stream_pos|.
|
||||||
|
@ -52,7 +55,7 @@ class EsParserH264 : public EsParser {
|
||||||
// If found, |*stream_pos| corresponds to the position of the AUD start code
|
// If found, |*stream_pos| corresponds to the position of the AUD start code
|
||||||
// in the stream. Otherwise, |*stream_pos| corresponds to the last position
|
// in the stream. Otherwise, |*stream_pos| corresponds to the last position
|
||||||
// of the start code parser.
|
// of the start code parser.
|
||||||
bool FindAUD(int64* stream_pos);
|
bool FindAUD(int64_t* stream_pos);
|
||||||
|
|
||||||
// Resumes the H264 ES parsing.
|
// Resumes the H264 ES parsing.
|
||||||
// Return true if successful.
|
// Return true if successful.
|
||||||
|
@ -60,8 +63,10 @@ class EsParserH264 : public EsParser {
|
||||||
|
|
||||||
// Emit a frame whose position in the ES queue starts at |access_unit_pos|.
|
// Emit a frame whose position in the ES queue starts at |access_unit_pos|.
|
||||||
// Returns true if successful, false if no PTS is available for the frame.
|
// Returns true if successful, false if no PTS is available for the frame.
|
||||||
bool EmitFrame(int64 access_unit_pos, int access_unit_size,
|
bool EmitFrame(int64_t access_unit_pos,
|
||||||
bool is_key_frame, int pps_id);
|
int access_unit_size,
|
||||||
|
bool is_key_frame,
|
||||||
|
int pps_id);
|
||||||
|
|
||||||
// Update the video decoder config based on an H264 SPS.
|
// Update the video decoder config based on an H264 SPS.
|
||||||
// Return true if successful.
|
// Return true if successful.
|
||||||
|
@ -73,14 +78,14 @@ class EsParserH264 : public EsParser {
|
||||||
|
|
||||||
// Bytes of the ES stream that have not been emitted yet.
|
// Bytes of the ES stream that have not been emitted yet.
|
||||||
scoped_ptr<media::OffsetByteQueue> es_queue_;
|
scoped_ptr<media::OffsetByteQueue> es_queue_;
|
||||||
std::list<std::pair<int64, TimingDesc> > timing_desc_list_;
|
std::list<std::pair<int64_t, TimingDesc> > timing_desc_list_;
|
||||||
|
|
||||||
// H264 parser state.
|
// H264 parser state.
|
||||||
// - |current_access_unit_pos_| is pointing to an annexB syncword
|
// - |current_access_unit_pos_| is pointing to an annexB syncword
|
||||||
// representing the first NALU of an H264 access unit.
|
// representing the first NALU of an H264 access unit.
|
||||||
scoped_ptr<H264Parser> h264_parser_;
|
scoped_ptr<H264Parser> h264_parser_;
|
||||||
int64 current_access_unit_pos_;
|
int64_t current_access_unit_pos_;
|
||||||
int64 next_access_unit_pos_;
|
int64_t next_access_unit_pos_;
|
||||||
|
|
||||||
// Filter to convert H.264 Annex B byte stream to unit stream.
|
// Filter to convert H.264 Annex B byte stream to unit stream.
|
||||||
scoped_ptr<H264ByteToUnitStreamConverter> stream_converter_;
|
scoped_ptr<H264ByteToUnitStreamConverter> stream_converter_;
|
||||||
|
@ -91,7 +96,7 @@ class EsParserH264 : public EsParser {
|
||||||
|
|
||||||
// Frame for which we do not yet have a duration.
|
// Frame for which we do not yet have a duration.
|
||||||
scoped_refptr<MediaSample> pending_sample_;
|
scoped_refptr<MediaSample> pending_sample_;
|
||||||
uint64 pending_sample_duration_;
|
uint64_t pending_sample_duration_;
|
||||||
|
|
||||||
// Indicates whether waiting for first key frame.
|
// Indicates whether waiting for first key frame.
|
||||||
bool waiting_for_key_frame_;
|
bool waiting_for_key_frame_;
|
||||||
|
|
|
@ -49,7 +49,7 @@ void ComputePacketSize(std::vector<Packet>& packets, size_t stream_size) {
|
||||||
// This function assumes there is only one slice per access unit.
|
// This function assumes there is only one slice per access unit.
|
||||||
// This is a very simplified access unit segmenter that is good
|
// This is a very simplified access unit segmenter that is good
|
||||||
// enough for unit tests.
|
// enough for unit tests.
|
||||||
std::vector<Packet> GetAccessUnits(const uint8* stream, size_t stream_size) {
|
std::vector<Packet> GetAccessUnits(const uint8_t* stream, size_t stream_size) {
|
||||||
std::vector<Packet> access_units;
|
std::vector<Packet> access_units;
|
||||||
bool start_access_unit = true;
|
bool start_access_unit = true;
|
||||||
|
|
||||||
|
@ -92,12 +92,12 @@ std::vector<Packet> GetAccessUnits(const uint8* stream, size_t stream_size) {
|
||||||
|
|
||||||
// Append an AUD NALU at the beginning of each access unit
|
// Append an AUD NALU at the beginning of each access unit
|
||||||
// needed for streams which do not already have AUD NALUs.
|
// needed for streams which do not already have AUD NALUs.
|
||||||
void AppendAUD(
|
void AppendAUD(const uint8_t* stream,
|
||||||
const uint8* stream, size_t stream_size,
|
size_t stream_size,
|
||||||
const std::vector<Packet>& access_units,
|
const std::vector<Packet>& access_units,
|
||||||
std::vector<uint8>& stream_with_aud,
|
std::vector<uint8_t>& stream_with_aud,
|
||||||
std::vector<Packet>& access_units_with_aud) {
|
std::vector<Packet>& access_units_with_aud) {
|
||||||
uint8 aud[] = { 0x00, 0x00, 0x01, 0x09 };
|
uint8_t aud[] = {0x00, 0x00, 0x01, 0x09};
|
||||||
stream_with_aud.resize(stream_size + access_units.size() * sizeof(aud));
|
stream_with_aud.resize(stream_size + access_units.size() * sizeof(aud));
|
||||||
access_units_with_aud.resize(access_units.size());
|
access_units_with_aud.resize(access_units.size());
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ class EsParserH264Test : public testing::Test {
|
||||||
void LoadStream(const char* filename);
|
void LoadStream(const char* filename);
|
||||||
void ProcessPesPackets(const std::vector<Packet>& pes_packets);
|
void ProcessPesPackets(const std::vector<Packet>& pes_packets);
|
||||||
|
|
||||||
void EmitSample(uint32 pid, scoped_refptr<MediaSample>& sample) {
|
void EmitSample(uint32_t pid, scoped_refptr<MediaSample>& sample) {
|
||||||
sample_count_++;
|
sample_count_++;
|
||||||
if (sample_count_ == 1)
|
if (sample_count_ == 1)
|
||||||
first_frame_is_key_frame_ = sample->is_key_frame();
|
first_frame_is_key_frame_ = sample->is_key_frame();
|
||||||
|
@ -139,7 +139,7 @@ class EsParserH264Test : public testing::Test {
|
||||||
bool first_frame_is_key_frame() { return first_frame_is_key_frame_; }
|
bool first_frame_is_key_frame() { return first_frame_is_key_frame_; }
|
||||||
|
|
||||||
// Stream with AUD NALUs.
|
// Stream with AUD NALUs.
|
||||||
std::vector<uint8> stream_;
|
std::vector<uint8_t> stream_;
|
||||||
|
|
||||||
// Access units of the stream with AUD NALUs.
|
// Access units of the stream with AUD NALUs.
|
||||||
std::vector<Packet> access_units_;
|
std::vector<Packet> access_units_;
|
||||||
|
@ -168,7 +168,7 @@ void EsParserH264Test::LoadStream(const char* filename) {
|
||||||
void EsParserH264Test::ProcessPesPackets(
|
void EsParserH264Test::ProcessPesPackets(
|
||||||
const std::vector<Packet>& pes_packets) {
|
const std::vector<Packet>& pes_packets) {
|
||||||
// Duration of one 25fps video frame in 90KHz clock units.
|
// Duration of one 25fps video frame in 90KHz clock units.
|
||||||
const uint32 kMpegTicksPerFrame = 3600;
|
const uint32_t kMpegTicksPerFrame = 3600;
|
||||||
|
|
||||||
EsParserH264 es_parser(
|
EsParserH264 es_parser(
|
||||||
0,
|
0,
|
||||||
|
@ -189,8 +189,8 @@ void EsParserH264Test::ProcessPesPackets(
|
||||||
|
|
||||||
// Check whether the PES packet includes the start of an access unit.
|
// Check whether the PES packet includes the start of an access unit.
|
||||||
// The timings are relevant only in this case.
|
// The timings are relevant only in this case.
|
||||||
int64 pts = kNoTimestamp;
|
int64_t pts = kNoTimestamp;
|
||||||
int64 dts = kNoTimestamp;
|
int64_t dts = kNoTimestamp;
|
||||||
if (cur_pes_offset <= access_units_[au_idx].offset &&
|
if (cur_pes_offset <= access_units_[au_idx].offset &&
|
||||||
cur_pes_offset + cur_pes_size > access_units_[au_idx].offset) {
|
cur_pes_offset + cur_pes_size > access_units_[au_idx].offset) {
|
||||||
pts = au_idx * kMpegTicksPerFrame;
|
pts = au_idx * kMpegTicksPerFrame;
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
namespace edash_packager {
|
namespace edash_packager {
|
||||||
namespace media {
|
namespace media {
|
||||||
|
|
||||||
const uint32 kMpeg2Timescale = 90000;
|
const uint32_t kMpeg2Timescale = 90000;
|
||||||
|
|
||||||
} // namespace media
|
} // namespace media
|
||||||
} // namespace edash_packager
|
} // namespace edash_packager
|
||||||
|
|
|
@ -184,14 +184,14 @@ void Mp2tMediaParser::Flush() {
|
||||||
ts_byte_queue_.Reset();
|
ts_byte_queue_.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mp2tMediaParser::Parse(const uint8* buf, int size) {
|
bool Mp2tMediaParser::Parse(const uint8_t* buf, int size) {
|
||||||
DVLOG(1) << "Mp2tMediaParser::Parse size=" << size;
|
DVLOG(1) << "Mp2tMediaParser::Parse size=" << size;
|
||||||
|
|
||||||
// Add the data to the parser state.
|
// Add the data to the parser state.
|
||||||
ts_byte_queue_.Push(buf, size);
|
ts_byte_queue_.Push(buf, size);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
const uint8* ts_buffer;
|
const uint8_t* ts_buffer;
|
||||||
int ts_buffer_size;
|
int ts_buffer_size;
|
||||||
ts_byte_queue_.Peek(&ts_buffer, &ts_buffer_size);
|
ts_byte_queue_.Peek(&ts_buffer, &ts_buffer_size);
|
||||||
if (ts_buffer_size < TsPacket::kPacketSize)
|
if (ts_buffer_size < TsPacket::kPacketSize)
|
||||||
|
@ -354,7 +354,7 @@ bool Mp2tMediaParser::FinishInitializationIfNeeded() {
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
std::vector<scoped_refptr<StreamInfo> > all_stream_info;
|
std::vector<scoped_refptr<StreamInfo> > all_stream_info;
|
||||||
uint32 num_es(0);
|
uint32_t num_es(0);
|
||||||
for (PidMap::const_iterator iter = pids_.begin(); iter != pids_.end();
|
for (PidMap::const_iterator iter = pids_.begin(); iter != pids_.end();
|
||||||
++iter) {
|
++iter) {
|
||||||
if (((iter->second->pid_type() == PidState::kPidAudioPes) ||
|
if (((iter->second->pid_type() == PidState::kPidAudioPes) ||
|
||||||
|
@ -374,7 +374,7 @@ bool Mp2tMediaParser::FinishInitializationIfNeeded() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mp2tMediaParser::OnEmitSample(uint32 pes_pid,
|
void Mp2tMediaParser::OnEmitSample(uint32_t pes_pid,
|
||||||
scoped_refptr<MediaSample>& new_sample) {
|
scoped_refptr<MediaSample>& new_sample) {
|
||||||
DCHECK(new_sample);
|
DCHECK(new_sample);
|
||||||
DVLOG(LOG_LEVEL_ES)
|
DVLOG(LOG_LEVEL_ES)
|
||||||
|
|
|
@ -39,7 +39,7 @@ class Mp2tMediaParser : public MediaParser {
|
||||||
|
|
||||||
virtual void Flush() OVERRIDE;
|
virtual void Flush() OVERRIDE;
|
||||||
|
|
||||||
virtual bool Parse(const uint8* buf, int size) OVERRIDE;
|
virtual bool Parse(const uint8_t* buf, int size) OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::map<int, PidState*> PidMap;
|
typedef std::map<int, PidState*> PidMap;
|
||||||
|
@ -60,7 +60,7 @@ class Mp2tMediaParser : public MediaParser {
|
||||||
|
|
||||||
// Callback invoked by the ES media parser
|
// Callback invoked by the ES media parser
|
||||||
// to emit a new audio/video access unit.
|
// to emit a new audio/video access unit.
|
||||||
void OnEmitSample(uint32 pes_pid, scoped_refptr<MediaSample>& new_sample);
|
void OnEmitSample(uint32_t pes_pid, scoped_refptr<MediaSample>& new_sample);
|
||||||
|
|
||||||
// Invoke the initialization callback if needed.
|
// Invoke the initialization callback if needed.
|
||||||
bool FinishInitializationIfNeeded();
|
bool FinishInitializationIfNeeded();
|
||||||
|
|
|
@ -40,16 +40,18 @@ class Mp2tMediaParserTest : public testing::Test {
|
||||||
StreamMap stream_map_;
|
StreamMap stream_map_;
|
||||||
int audio_frame_count_;
|
int audio_frame_count_;
|
||||||
int video_frame_count_;
|
int video_frame_count_;
|
||||||
int64 video_min_dts_;
|
int64_t video_min_dts_;
|
||||||
int64 video_max_dts_;
|
int64_t video_max_dts_;
|
||||||
|
|
||||||
bool AppendData(const uint8* data, size_t length) {
|
bool AppendData(const uint8_t* data, size_t length) {
|
||||||
return parser_->Parse(data, length);
|
return parser_->Parse(data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AppendDataInPieces(const uint8* data, size_t length, size_t piece_size) {
|
bool AppendDataInPieces(const uint8_t* data,
|
||||||
const uint8* start = data;
|
size_t length,
|
||||||
const uint8* end = data + length;
|
size_t piece_size) {
|
||||||
|
const uint8_t* start = data;
|
||||||
|
const uint8_t* end = data + length;
|
||||||
while (start < end) {
|
while (start < end) {
|
||||||
size_t append_size = std::min(piece_size,
|
size_t append_size = std::min(piece_size,
|
||||||
static_cast<size_t>(end - start));
|
static_cast<size_t>(end - start));
|
||||||
|
@ -69,7 +71,8 @@ class Mp2tMediaParserTest : public testing::Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OnNewSample(uint32 track_id, const scoped_refptr<MediaSample>& sample) {
|
bool OnNewSample(uint32_t track_id,
|
||||||
|
const scoped_refptr<MediaSample>& sample) {
|
||||||
std::string stream_type;
|
std::string stream_type;
|
||||||
StreamMap::const_iterator stream = stream_map_.find(track_id);
|
StreamMap::const_iterator stream = stream_map_.find(track_id);
|
||||||
if (stream != stream_map_.end()) {
|
if (stream != stream_map_.end()) {
|
||||||
|
@ -110,7 +113,7 @@ class Mp2tMediaParserTest : public testing::Test {
|
||||||
bool ParseMpeg2TsFile(const std::string& filename, int append_bytes) {
|
bool ParseMpeg2TsFile(const std::string& filename, int append_bytes) {
|
||||||
InitializeParser();
|
InitializeParser();
|
||||||
|
|
||||||
std::vector<uint8> buffer = ReadTestDataFile(filename);
|
std::vector<uint8_t> buffer = ReadTestDataFile(filename);
|
||||||
EXPECT_TRUE(AppendDataInPieces(buffer.data(),
|
EXPECT_TRUE(AppendDataInPieces(buffer.data(),
|
||||||
buffer.size(),
|
buffer.size(),
|
||||||
append_bytes));
|
append_bytes));
|
||||||
|
@ -144,7 +147,7 @@ TEST_F(Mp2tMediaParserTest, TimestampWrapAround) {
|
||||||
EXPECT_EQ(video_frame_count_, 82);
|
EXPECT_EQ(video_frame_count_, 82);
|
||||||
EXPECT_GE(video_min_dts_, (95443 - 1) * kMpeg2Timescale);
|
EXPECT_GE(video_min_dts_, (95443 - 1) * kMpeg2Timescale);
|
||||||
EXPECT_LE(video_max_dts_,
|
EXPECT_LE(video_max_dts_,
|
||||||
static_cast<int64>((95443 + 4)) * kMpeg2Timescale);
|
static_cast<int64_t>((95443 + 4)) * kMpeg2Timescale);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace mp2t
|
} // namespace mp2t
|
||||||
|
|
|
@ -12,10 +12,10 @@ namespace edash_packager {
|
||||||
namespace media {
|
namespace media {
|
||||||
namespace mp2t {
|
namespace mp2t {
|
||||||
|
|
||||||
static const uint8 kTsHeaderSyncword = 0x47;
|
static const uint8_t kTsHeaderSyncword = 0x47;
|
||||||
|
|
||||||
// static
|
// static
|
||||||
int TsPacket::Sync(const uint8* buf, int size) {
|
int TsPacket::Sync(const uint8_t* buf, int size) {
|
||||||
int k = 0;
|
int k = 0;
|
||||||
for (; k < size; k++) {
|
for (; k < size; k++) {
|
||||||
// Verify that we have 4 syncwords in a row when possible,
|
// Verify that we have 4 syncwords in a row when possible,
|
||||||
|
@ -42,7 +42,7 @@ int TsPacket::Sync(const uint8* buf, int size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
TsPacket* TsPacket::Parse(const uint8* buf, int size) {
|
TsPacket* TsPacket::Parse(const uint8_t* buf, int size) {
|
||||||
if (size < kPacketSize) {
|
if (size < kPacketSize) {
|
||||||
DVLOG(1) << "Buffer does not hold one full TS packet:"
|
DVLOG(1) << "Buffer does not hold one full TS packet:"
|
||||||
<< " buffer_size=" << size;
|
<< " buffer_size=" << size;
|
||||||
|
@ -72,7 +72,7 @@ TsPacket::TsPacket() {
|
||||||
TsPacket::~TsPacket() {
|
TsPacket::~TsPacket() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TsPacket::ParseHeader(const uint8* buf) {
|
bool TsPacket::ParseHeader(const uint8_t* buf) {
|
||||||
BitReader bit_reader(buf, kPacketSize);
|
BitReader bit_reader(buf, kPacketSize);
|
||||||
payload_ = buf;
|
payload_ = buf;
|
||||||
payload_size_ = kPacketSize;
|
payload_size_ = kPacketSize;
|
||||||
|
@ -160,7 +160,7 @@ bool TsPacket::ParseAdaptationField(BitReader* bit_reader,
|
||||||
random_access_indicator_ = (random_access_indicator != 0);
|
random_access_indicator_ = (random_access_indicator != 0);
|
||||||
|
|
||||||
if (pcr_flag) {
|
if (pcr_flag) {
|
||||||
int64 program_clock_reference_base;
|
int64_t program_clock_reference_base;
|
||||||
int reserved;
|
int reserved;
|
||||||
int program_clock_reference_extension;
|
int program_clock_reference_extension;
|
||||||
RCHECK(bit_reader->ReadBits(33, &program_clock_reference_base));
|
RCHECK(bit_reader->ReadBits(33, &program_clock_reference_base));
|
||||||
|
@ -169,7 +169,7 @@ bool TsPacket::ParseAdaptationField(BitReader* bit_reader,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opcr_flag) {
|
if (opcr_flag) {
|
||||||
int64 original_program_clock_reference_base;
|
int64_t original_program_clock_reference_base;
|
||||||
int reserved;
|
int reserved;
|
||||||
int original_program_clock_reference_extension;
|
int original_program_clock_reference_extension;
|
||||||
RCHECK(bit_reader->ReadBits(33, &original_program_clock_reference_base));
|
RCHECK(bit_reader->ReadBits(33, &original_program_clock_reference_base));
|
||||||
|
|
|
@ -20,12 +20,12 @@ class TsPacket {
|
||||||
|
|
||||||
// Return the number of bytes to discard
|
// Return the number of bytes to discard
|
||||||
// to be synchronized on a TS syncword.
|
// to be synchronized on a TS syncword.
|
||||||
static int Sync(const uint8* buf, int size);
|
static int Sync(const uint8_t* buf, int size);
|
||||||
|
|
||||||
// Parse a TS packet.
|
// Parse a TS packet.
|
||||||
// Return a TsPacket only when parsing was successful.
|
// Return a TsPacket only when parsing was successful.
|
||||||
// Return NULL otherwise.
|
// Return NULL otherwise.
|
||||||
static TsPacket* Parse(const uint8* buf, int size);
|
static TsPacket* Parse(const uint8_t* buf, int size);
|
||||||
|
|
||||||
~TsPacket();
|
~TsPacket();
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ class TsPacket {
|
||||||
bool random_access_indicator() const { return random_access_indicator_; }
|
bool random_access_indicator() const { return random_access_indicator_; }
|
||||||
|
|
||||||
// Return the offset and the size of the payload.
|
// Return the offset and the size of the payload.
|
||||||
const uint8* payload() const { return payload_; }
|
const uint8_t* payload() const { return payload_; }
|
||||||
int payload_size() const { return payload_size_; }
|
int payload_size() const { return payload_size_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -47,12 +47,12 @@ class TsPacket {
|
||||||
|
|
||||||
// Parse an Mpeg2 TS header.
|
// Parse an Mpeg2 TS header.
|
||||||
// The buffer size should be at least |kPacketSize|
|
// The buffer size should be at least |kPacketSize|
|
||||||
bool ParseHeader(const uint8* buf);
|
bool ParseHeader(const uint8_t* buf);
|
||||||
bool ParseAdaptationField(BitReader* bit_reader,
|
bool ParseAdaptationField(BitReader* bit_reader,
|
||||||
int adaptation_field_length);
|
int adaptation_field_length);
|
||||||
|
|
||||||
// Size of the payload.
|
// Size of the payload.
|
||||||
const uint8* payload_;
|
const uint8_t* payload_;
|
||||||
int payload_size_;
|
int payload_size_;
|
||||||
|
|
||||||
// TS header.
|
// TS header.
|
||||||
|
|
|
@ -25,7 +25,8 @@ class TsSection {
|
||||||
// Parse the data bytes of the TS packet.
|
// Parse the data bytes of the TS packet.
|
||||||
// Return true if parsing is successful.
|
// Return true if parsing is successful.
|
||||||
virtual bool Parse(bool payload_unit_start_indicator,
|
virtual bool Parse(bool payload_unit_start_indicator,
|
||||||
const uint8* buf, int size) = 0;
|
const uint8_t* buf,
|
||||||
|
int size) = 0;
|
||||||
|
|
||||||
// Process bytes that have not been processed yet (pending buffers in the
|
// Process bytes that have not been processed yet (pending buffers in the
|
||||||
// pipe). Flush might thus results in frame emission, as an example.
|
// pipe). Flush might thus results in frame emission, as an example.
|
||||||
|
|
|
@ -19,7 +19,7 @@ static const int kPesStartCode = 0x000001;
|
||||||
// |time| + k * (2 ^ 33)
|
// |time| + k * (2 ^ 33)
|
||||||
// where k is estimated so that the unrolled timestamp
|
// where k is estimated so that the unrolled timestamp
|
||||||
// is as close as possible to |previous_unrolled_time|.
|
// is as close as possible to |previous_unrolled_time|.
|
||||||
static int64 UnrollTimestamp(int64 previous_unrolled_time, int64 time) {
|
static int64_t UnrollTimestamp(int64_t previous_unrolled_time, int64_t time) {
|
||||||
// Mpeg2 TS timestamps have an accuracy of 33 bits.
|
// Mpeg2 TS timestamps have an accuracy of 33 bits.
|
||||||
const int nbits = 33;
|
const int nbits = 33;
|
||||||
|
|
||||||
|
@ -28,17 +28,16 @@ static int64 UnrollTimestamp(int64 previous_unrolled_time, int64 time) {
|
||||||
DCHECK_EQ((time >> nbits), 0);
|
DCHECK_EQ((time >> nbits), 0);
|
||||||
|
|
||||||
// Consider 3 possibilities to estimate the missing high bits of |time|.
|
// Consider 3 possibilities to estimate the missing high bits of |time|.
|
||||||
int64 previous_unrolled_time_high =
|
int64_t previous_unrolled_time_high = (previous_unrolled_time >> nbits);
|
||||||
(previous_unrolled_time >> nbits);
|
int64_t time0 = ((previous_unrolled_time_high - 1) << nbits) | time;
|
||||||
int64 time0 = ((previous_unrolled_time_high - 1) << nbits) | time;
|
int64_t time1 = ((previous_unrolled_time_high + 0) << nbits) | time;
|
||||||
int64 time1 = ((previous_unrolled_time_high + 0) << nbits) | time;
|
int64_t time2 = ((previous_unrolled_time_high + 1) << nbits) | time;
|
||||||
int64 time2 = ((previous_unrolled_time_high + 1) << nbits) | time;
|
|
||||||
|
|
||||||
// Select the min absolute difference with the current time
|
// Select the min absolute difference with the current time
|
||||||
// so as to ensure time continuity.
|
// so as to ensure time continuity.
|
||||||
int64 diff0 = time0 - previous_unrolled_time;
|
int64_t diff0 = time0 - previous_unrolled_time;
|
||||||
int64 diff1 = time1 - previous_unrolled_time;
|
int64_t diff1 = time1 - previous_unrolled_time;
|
||||||
int64 diff2 = time2 - previous_unrolled_time;
|
int64_t diff2 = time2 - previous_unrolled_time;
|
||||||
if (diff0 < 0)
|
if (diff0 < 0)
|
||||||
diff0 = -diff0;
|
diff0 = -diff0;
|
||||||
if (diff1 < 0)
|
if (diff1 < 0)
|
||||||
|
@ -46,8 +45,8 @@ static int64 UnrollTimestamp(int64 previous_unrolled_time, int64 time) {
|
||||||
if (diff2 < 0)
|
if (diff2 < 0)
|
||||||
diff2 = -diff2;
|
diff2 = -diff2;
|
||||||
|
|
||||||
int64 unrolled_time;
|
int64_t unrolled_time;
|
||||||
int64 min_diff;
|
int64_t min_diff;
|
||||||
if (diff1 < diff0) {
|
if (diff1 < diff0) {
|
||||||
unrolled_time = time1;
|
unrolled_time = time1;
|
||||||
min_diff = diff1;
|
min_diff = diff1;
|
||||||
|
@ -61,7 +60,7 @@ static int64 UnrollTimestamp(int64 previous_unrolled_time, int64 time) {
|
||||||
return unrolled_time;
|
return unrolled_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsTimestampSectionValid(int64 timestamp_section) {
|
static bool IsTimestampSectionValid(int64_t timestamp_section) {
|
||||||
// |pts_section| has 40 bits:
|
// |pts_section| has 40 bits:
|
||||||
// - starting with either '0010' or '0011' or '0001'
|
// - starting with either '0010' or '0011' or '0001'
|
||||||
// - and ending with a marker bit.
|
// - and ending with a marker bit.
|
||||||
|
@ -73,7 +72,7 @@ static bool IsTimestampSectionValid(int64 timestamp_section) {
|
||||||
((timestamp_section & 0x100000000LL) != 0);
|
((timestamp_section & 0x100000000LL) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64 ConvertTimestampSectionToTimestamp(int64 timestamp_section) {
|
static int64_t ConvertTimestampSectionToTimestamp(int64_t timestamp_section) {
|
||||||
return (((timestamp_section >> 33) & 0x7) << 30) |
|
return (((timestamp_section >> 33) & 0x7) << 30) |
|
||||||
(((timestamp_section >> 17) & 0x7fff) << 15) |
|
(((timestamp_section >> 17) & 0x7fff) << 15) |
|
||||||
(((timestamp_section >> 1) & 0x7fff) << 0);
|
(((timestamp_section >> 1) & 0x7fff) << 0);
|
||||||
|
@ -97,7 +96,8 @@ TsSectionPes::~TsSectionPes() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TsSectionPes::Parse(bool payload_unit_start_indicator,
|
bool TsSectionPes::Parse(bool payload_unit_start_indicator,
|
||||||
const uint8* buf, int size) {
|
const uint8_t* buf,
|
||||||
|
int size) {
|
||||||
// Ignore partial PES.
|
// Ignore partial PES.
|
||||||
if (wait_for_pusi_ && !payload_unit_start_indicator)
|
if (wait_for_pusi_ && !payload_unit_start_indicator)
|
||||||
return true;
|
return true;
|
||||||
|
@ -108,7 +108,7 @@ bool TsSectionPes::Parse(bool payload_unit_start_indicator,
|
||||||
// with an undefined size.
|
// with an undefined size.
|
||||||
// In this case, a unit is emitted when the next unit is coming.
|
// In this case, a unit is emitted when the next unit is coming.
|
||||||
int raw_pes_size;
|
int raw_pes_size;
|
||||||
const uint8* raw_pes;
|
const uint8_t* raw_pes;
|
||||||
pes_byte_queue_.Peek(&raw_pes, &raw_pes_size);
|
pes_byte_queue_.Peek(&raw_pes, &raw_pes_size);
|
||||||
if (raw_pes_size > 0)
|
if (raw_pes_size > 0)
|
||||||
parse_result = Emit(true);
|
parse_result = Emit(true);
|
||||||
|
@ -150,7 +150,7 @@ void TsSectionPes::Reset() {
|
||||||
|
|
||||||
bool TsSectionPes::Emit(bool emit_for_unknown_size) {
|
bool TsSectionPes::Emit(bool emit_for_unknown_size) {
|
||||||
int raw_pes_size;
|
int raw_pes_size;
|
||||||
const uint8* raw_pes;
|
const uint8_t* raw_pes;
|
||||||
pes_byte_queue_.Peek(&raw_pes, &raw_pes_size);
|
pes_byte_queue_.Peek(&raw_pes, &raw_pes_size);
|
||||||
|
|
||||||
// A PES should be at least 6 bytes.
|
// A PES should be at least 6 bytes.
|
||||||
|
@ -181,7 +181,7 @@ bool TsSectionPes::Emit(bool emit_for_unknown_size) {
|
||||||
return parse_result;
|
return parse_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TsSectionPes::ParseInternal(const uint8* raw_pes, int raw_pes_size) {
|
bool TsSectionPes::ParseInternal(const uint8_t* raw_pes, int raw_pes_size) {
|
||||||
BitReader bit_reader(raw_pes, raw_pes_size);
|
BitReader bit_reader(raw_pes, raw_pes_size);
|
||||||
|
|
||||||
// Read up to the pes_packet_length (6 bytes).
|
// Read up to the pes_packet_length (6 bytes).
|
||||||
|
@ -247,8 +247,8 @@ bool TsSectionPes::ParseInternal(const uint8* raw_pes, int raw_pes_size) {
|
||||||
// Read the timing information section.
|
// Read the timing information section.
|
||||||
bool is_pts_valid = false;
|
bool is_pts_valid = false;
|
||||||
bool is_dts_valid = false;
|
bool is_dts_valid = false;
|
||||||
int64 pts_section = 0;
|
int64_t pts_section = 0;
|
||||||
int64 dts_section = 0;
|
int64_t dts_section = 0;
|
||||||
if (pts_dts_flags == 0x2) {
|
if (pts_dts_flags == 0x2) {
|
||||||
RCHECK(bit_reader.ReadBits(40, &pts_section));
|
RCHECK(bit_reader.ReadBits(40, &pts_section));
|
||||||
RCHECK((((pts_section >> 36) & 0xf) == 0x2) &&
|
RCHECK((((pts_section >> 36) & 0xf) == 0x2) &&
|
||||||
|
@ -267,10 +267,10 @@ bool TsSectionPes::ParseInternal(const uint8* raw_pes, int raw_pes_size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert and unroll the timestamps.
|
// Convert and unroll the timestamps.
|
||||||
int64 media_pts(kNoTimestamp);
|
int64_t media_pts(kNoTimestamp);
|
||||||
int64 media_dts(kNoTimestamp);
|
int64_t media_dts(kNoTimestamp);
|
||||||
if (is_pts_valid) {
|
if (is_pts_valid) {
|
||||||
int64 pts = ConvertTimestampSectionToTimestamp(pts_section);
|
int64_t pts = ConvertTimestampSectionToTimestamp(pts_section);
|
||||||
if (previous_pts_valid_)
|
if (previous_pts_valid_)
|
||||||
pts = UnrollTimestamp(previous_pts_, pts);
|
pts = UnrollTimestamp(previous_pts_, pts);
|
||||||
previous_pts_ = pts;
|
previous_pts_ = pts;
|
||||||
|
@ -278,7 +278,7 @@ bool TsSectionPes::ParseInternal(const uint8* raw_pes, int raw_pes_size) {
|
||||||
media_pts = pts;
|
media_pts = pts;
|
||||||
}
|
}
|
||||||
if (is_dts_valid) {
|
if (is_dts_valid) {
|
||||||
int64 dts = ConvertTimestampSectionToTimestamp(dts_section);
|
int64_t dts = ConvertTimestampSectionToTimestamp(dts_section);
|
||||||
if (previous_dts_valid_)
|
if (previous_dts_valid_)
|
||||||
dts = UnrollTimestamp(previous_dts_, dts);
|
dts = UnrollTimestamp(previous_dts_, dts);
|
||||||
previous_dts_ = dts;
|
previous_dts_ = dts;
|
||||||
|
|
|
@ -24,7 +24,8 @@ class TsSectionPes : public TsSection {
|
||||||
|
|
||||||
// TsSection implementation.
|
// TsSection implementation.
|
||||||
virtual bool Parse(bool payload_unit_start_indicator,
|
virtual bool Parse(bool payload_unit_start_indicator,
|
||||||
const uint8* buf, int size) OVERRIDE;
|
const uint8_t* buf,
|
||||||
|
int size) OVERRIDE;
|
||||||
virtual void Flush() OVERRIDE;
|
virtual void Flush() OVERRIDE;
|
||||||
virtual void Reset() OVERRIDE;
|
virtual void Reset() OVERRIDE;
|
||||||
|
|
||||||
|
@ -36,7 +37,7 @@ class TsSectionPes : public TsSection {
|
||||||
bool Emit(bool emit_for_unknown_size);
|
bool Emit(bool emit_for_unknown_size);
|
||||||
|
|
||||||
// Parse a PES packet, return true if successful.
|
// Parse a PES packet, return true if successful.
|
||||||
bool ParseInternal(const uint8* raw_pes, int raw_pes_size);
|
bool ParseInternal(const uint8_t* raw_pes, int raw_pes_size);
|
||||||
|
|
||||||
void ResetPesState();
|
void ResetPesState();
|
||||||
|
|
||||||
|
@ -51,9 +52,9 @@ class TsSectionPes : public TsSection {
|
||||||
|
|
||||||
// Used to unroll PTS and DTS.
|
// Used to unroll PTS and DTS.
|
||||||
bool previous_pts_valid_;
|
bool previous_pts_valid_;
|
||||||
int64 previous_pts_;
|
int64_t previous_pts_;
|
||||||
bool previous_dts_valid_;
|
bool previous_dts_valid_;
|
||||||
int64 previous_dts_;
|
int64_t previous_dts_;
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(TsSectionPes);
|
DISALLOW_COPY_AND_ASSIGN(TsSectionPes);
|
||||||
};
|
};
|
||||||
|
|
|
@ -9,13 +9,13 @@
|
||||||
#include "media/base/bit_reader.h"
|
#include "media/base/bit_reader.h"
|
||||||
#include "media/formats/mp2t/mp2t_common.h"
|
#include "media/formats/mp2t/mp2t_common.h"
|
||||||
|
|
||||||
static bool IsCrcValid(const uint8* buf, int size) {
|
static bool IsCrcValid(const uint8_t* buf, int size) {
|
||||||
uint32 crc = 0xffffffffu;
|
uint32_t crc = 0xffffffffu;
|
||||||
const uint32 kCrcPoly = 0x4c11db7;
|
const uint32_t kCrcPoly = 0x4c11db7;
|
||||||
|
|
||||||
for (int k = 0; k < size; k++) {
|
for (int k = 0; k < size; k++) {
|
||||||
int nbits = 8;
|
int nbits = 8;
|
||||||
uint32 data_msb_aligned = buf[k];
|
uint32_t data_msb_aligned = buf[k];
|
||||||
data_msb_aligned <<= (32 - nbits);
|
data_msb_aligned <<= (32 - nbits);
|
||||||
|
|
||||||
while (nbits > 0) {
|
while (nbits > 0) {
|
||||||
|
@ -47,7 +47,8 @@ TsSectionPsi::~TsSectionPsi() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TsSectionPsi::Parse(bool payload_unit_start_indicator,
|
bool TsSectionPsi::Parse(bool payload_unit_start_indicator,
|
||||||
const uint8* buf, int size) {
|
const uint8_t* buf,
|
||||||
|
int size) {
|
||||||
// Ignore partial PSI.
|
// Ignore partial PSI.
|
||||||
if (wait_for_pusi_ && !payload_unit_start_indicator)
|
if (wait_for_pusi_ && !payload_unit_start_indicator)
|
||||||
return true;
|
return true;
|
||||||
|
@ -78,7 +79,7 @@ bool TsSectionPsi::Parse(bool payload_unit_start_indicator,
|
||||||
// Add the data to the parser state.
|
// Add the data to the parser state.
|
||||||
psi_byte_queue_.Push(buf, size);
|
psi_byte_queue_.Push(buf, size);
|
||||||
int raw_psi_size;
|
int raw_psi_size;
|
||||||
const uint8* raw_psi;
|
const uint8_t* raw_psi;
|
||||||
psi_byte_queue_.Peek(&raw_psi, &raw_psi_size);
|
psi_byte_queue_.Peek(&raw_psi, &raw_psi_size);
|
||||||
|
|
||||||
// Check whether we have enough data to start parsing.
|
// Check whether we have enough data to start parsing.
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue