diff options
Diffstat (limited to 'chromium/media/filters/ivf_parser.cc')
-rw-r--r-- | chromium/media/filters/ivf_parser.cc | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/chromium/media/filters/ivf_parser.cc b/chromium/media/filters/ivf_parser.cc new file mode 100644 index 00000000000..b6160fb533b --- /dev/null +++ b/chromium/media/filters/ivf_parser.cc @@ -0,0 +1,89 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/logging.h" +#include "base/sys_byteorder.h" +#include "media/filters/ivf_parser.h" + +namespace media { + +void IvfFileHeader::ByteSwap() { + version = base::ByteSwapToLE16(version); + header_size = base::ByteSwapToLE16(header_size); + fourcc = base::ByteSwapToLE32(fourcc); + width = base::ByteSwapToLE16(width); + height = base::ByteSwapToLE16(height); + timebase_denum = base::ByteSwapToLE32(timebase_denum); + timebase_num = base::ByteSwapToLE32(timebase_num); + num_frames = base::ByteSwapToLE32(num_frames); + unused = base::ByteSwapToLE32(unused); +} + +void IvfFrameHeader::ByteSwap() { + frame_size = base::ByteSwapToLE32(frame_size); + timestamp = base::ByteSwapToLE64(timestamp); +} + +IvfParser::IvfParser() : ptr_(nullptr), end_(nullptr) {} + +bool IvfParser::Initialize(const uint8_t* stream, + size_t size, + IvfFileHeader* file_header) { + DCHECK(stream); + DCHECK(file_header); + ptr_ = stream; + end_ = stream + size; + + if (size < sizeof(IvfFileHeader)) { + DLOG(ERROR) << "EOF before file header"; + return false; + } + + memcpy(file_header, ptr_, sizeof(IvfFileHeader)); + file_header->ByteSwap(); + + if (memcmp(file_header->signature, kIvfHeaderSignature, + sizeof(file_header->signature)) != 0) { + DLOG(ERROR) << "IVF signature mismatch"; + return false; + } + DLOG_IF(WARNING, file_header->version != 0) + << "IVF version unknown: " << file_header->version + << ", the parser may not be able to parse correctly"; + if (file_header->header_size != sizeof(IvfFileHeader)) { + DLOG(ERROR) << "IVF file header size mismatch"; + return false; + } + + ptr_ += sizeof(IvfFileHeader); + + return true; +} + +bool IvfParser::ParseNextFrame(IvfFrameHeader* frame_header, + const uint8_t** payload) { + DCHECK(ptr_); + DCHECK(payload); + + if (end_ < ptr_ + sizeof(IvfFrameHeader)) { + DLOG_IF(ERROR, ptr_ != end_) << "Incomplete frame header"; + return false; + } + + memcpy(frame_header, ptr_, sizeof(IvfFrameHeader)); + frame_header->ByteSwap(); + ptr_ += sizeof(IvfFrameHeader); + + if (end_ < ptr_ + frame_header->frame_size) { + DLOG(ERROR) << "Not enough frame data"; + return false; + } + + *payload = ptr_; + ptr_ += frame_header->frame_size; + + return true; +} + +} // namespace media |