mkvparser: add support for compression elements

ContentCompression elements are now parsed.

Change-Id: I9a67ae444ed929e49c7ea223a16c13c9d16a4c13
This commit is contained in:
Patrik Carlsson 2013-02-27 15:38:58 +01:00 committed by Johan Redestig
parent 3980cf4159
commit 0d5b3fc5ae
2 changed files with 85 additions and 2 deletions

View File

@ -5032,7 +5032,8 @@ const char* SegmentInfo::GetTitleAsUTF8() const
// ContentEncoding element
ContentEncoding::ContentCompression::ContentCompression()
: algo(0),
settings(NULL) {
settings(NULL),
settings_len(0) {
}
ContentEncoding::ContentCompression::~ContentCompression() {
@ -5238,7 +5239,17 @@ long ContentEncoding::ParseContentEncodingEntry(long long start,
encoding_type_ = UnserializeUInt(pReader, pos, size);
} else if (id == 0x1034) {
// ContentCompression ID
// TODO(fgaligan): Add code to parse ContentCompression elements.
ContentCompression* const compression =
new (std::nothrow) ContentCompression();
if (!compression)
return -1;
status = ParseCompressionEntry(pos, size, pReader, compression);
if (status) {
delete compression;
return status;
}
*compression_entries_end_++ = compression;
} else if (id == 0x1035) {
// ContentEncryption ID
ContentEncryption* const encryption =
@ -5262,6 +5273,68 @@ long ContentEncoding::ParseContentEncodingEntry(long long start,
return 0;
}
long ContentEncoding::ParseCompressionEntry(
long long start,
long long size,
IMkvReader* pReader,
ContentCompression* compression) {
assert(pReader);
assert(compression);
long long pos = start;
const long long stop = start + size;
bool valid = false;
while (pos < stop) {
long long id, size;
const long status = ParseElementHeader(pReader,
pos,
stop,
id,
size);
if (status < 0) //error
return status;
if (id == 0x254) {
// ContentCompAlgo
long long algo = UnserializeUInt(pReader, pos, size);
if (algo < 0)
return E_FILE_FORMAT_INVALID;
compression->algo = algo;
valid = true;
} else if (id == 0x255) {
// ContentCompSettings
if (size <= 0)
return E_FILE_FORMAT_INVALID;
const size_t buflen = static_cast<size_t>(size);
typedef unsigned char* buf_t;
const buf_t buf = new (std::nothrow) unsigned char[buflen];
if (buf == NULL)
return -1;
const int read_status = pReader->Read(pos, buflen, buf);
if (read_status) {
delete [] buf;
return status;
}
compression->settings = buf;
compression->settings_len = buflen;
}
pos += size; //consume payload
assert(pos <= stop);
}
// ContentCompAlgo is mandatory
if (!valid)
return E_FILE_FORMAT_INVALID;
return 0;
}
long ContentEncoding::ParseEncryptionEntry(
long long start,
long long size,

View File

@ -217,6 +217,7 @@ public:
unsigned long long algo;
unsigned char* settings;
long long settings_len;
};
// ContentEncAESSettings element names
@ -253,6 +254,15 @@ public:
// element.
unsigned long GetCompressionCount() const;
// Parses the ContentCompression element from |pReader|. |start| is the
// starting offset of the ContentCompression payload. |size| is the size in
// bytes of the ContentCompression payload. |compression| is where the parsed
// values will be stored.
long ParseCompressionEntry(long long start,
long long size,
IMkvReader* pReader,
ContentCompression* compression);
// Returns ContentEncryption represented by |idx|. Returns NULL if |idx|
// is out of bounds.
const ContentEncryption* GetEncryptionByIndex(unsigned long idx) const;