Chromium Code Reviews| Index: media/filters/ivf_parser.cc |
| diff --git a/media/filters/ivf_parser.cc b/media/filters/ivf_parser.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..0f88da576d6430704d4561e61c6abf20326098e2 |
| --- /dev/null |
| +++ b/media/filters/ivf_parser.cc |
| @@ -0,0 +1,86 @@ |
| +#include "base/logging.h" |
| +#include "base/sys_byteorder.h" |
| +#include "media/filters/ivf_parser.h" |
| + |
| +namespace { |
|
xhwang
2015/07/29 16:43:42
nit: Move this whole block into namespace media.
kcwu
2015/07/30 11:52:52
Done.
|
| + |
| +const size_t kIvfFileHeaderSize = 32; |
|
wuchengli
2015/07/30 06:26:13
Can we use sizeof(IvfFileHeader)? Same for kIvfFra
kcwu
2015/07/30 11:52:52
Done.
|
| +const size_t kIvfFrameHeaderSize = 12; |
| + |
| +uint16_t ReadU16(const uint8_t* buffer) { |
| + return base::ByteSwapToLE16(*reinterpret_cast<const uint16_t*>(buffer)); |
| +} |
| + |
| +uint32_t ReadU32(const uint8_t* buffer) { |
| + return base::ByteSwapToLE32(*reinterpret_cast<const uint32_t*>(buffer)); |
| +} |
| + |
| +uint64_t ReadU64(const uint8_t* buffer) { |
| + return base::ByteSwapToLE64(*reinterpret_cast<const uint64_t*>(buffer)); |
| +} |
| + |
| +} // namespace |
| + |
| +namespace media { |
| + |
| +IvfParser::IvfParser() : ptr_(nullptr), end_(nullptr) {} |
| + |
| +bool IvfParser::Initialize(const uint8_t* stream, |
| + size_t size, |
| + IvfFileHeader* file_header) { |
| + DCHECK(stream); |
| + DCHECK(file_header); |
| + if (size < kIvfFileHeaderSize) { |
| + DLOG(ERROR) << "EOF before file header"; |
| + return false; |
| + } |
| + |
| + ptr_ = stream; |
| + end_ = stream + size; |
| + |
| + // signature |
| + if (ptr_[0] != 'D' || ptr_[1] != 'K' || ptr_[2] != 'I' || ptr_[3] != 'F') { |
| + DLOG(ERROR) << "IVF signature mismatch"; |
| + return false; |
| + } |
| + |
| + file_header->version = ReadU16(ptr_ + 4); |
| + file_header->header_size = ReadU16(ptr_ + 6); |
| + if (file_header->header_size != kIvfFileHeaderSize) { |
| + DLOG(ERROR) << "IVF file header size mismatch"; |
| + return false; |
| + } |
| + file_header->fourcc = ReadU32(ptr_ + 8); |
| + file_header->width = ReadU16(ptr_ + 12); |
| + file_header->height = ReadU16(ptr_ + 14); |
| + file_header->timebase_denum = ReadU32(ptr_ + 16); |
| + file_header->timebase_num = ReadU32(ptr_ + 20); |
| + file_header->num_frames = ReadU32(ptr_ + 24); |
| + file_header->unused = ReadU32(ptr_ + 28); |
|
xhwang
2015/07/29 16:43:42
Does media::BitReader work for you?
https://code.
kcwu
2015/07/30 11:52:52
Ah, great! I was finding it in base/ . I will use
|
| + |
| + ptr_ += kIvfFileHeaderSize; |
| + |
| + return true; |
| +} |
| + |
| +bool IvfParser::ParseNextFrame(IvfFrameHeader* frame_header) { |
| + DCHECK(ptr_); |
| + if (ptr_ + kIvfFrameHeaderSize > end_) { |
| + DLOG_IF(ERROR, ptr_ != end_) << "Incomplete frame header"; |
| + return false; |
| + } |
| + frame_header->data_size = ReadU32(ptr_); |
| + frame_header->timestamp = ReadU64(ptr_); |
|
xhwang
2015/07/29 16:43:42
ptr_ + 4 ?
kcwu
2015/07/30 11:52:52
Revised.
|
| + ptr_ += kIvfFrameHeaderSize; |
| + |
| + if (ptr_ + frame_header->data_size > end_) { |
| + DLOG(ERROR) << "Not enough frame data"; |
| + return false; |
| + } |
| + |
| + frame_header->data = ptr_; |
| + ptr_ += frame_header->data_size; |
| + return true; |
| +} |
| + |
| +} // namespace media |