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 |