Upload upstream chromium 108.0.5359.1
[platform/framework/web/chromium-efl.git] / media / filters / ivf_parser.cc
1 // Copyright 2015 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "media/filters/ivf_parser.h"
6
7 #include <cstring>
8
9 #include "base/check.h"
10 #include "base/check_op.h"
11 #include "base/logging.h"
12 #include "base/numerics/safe_conversions.h"
13 #include "base/sys_byteorder.h"
14
15 namespace media {
16
17 void IvfFileHeader::ByteSwap() {
18   version = base::ByteSwapToLE16(version);
19   header_size = base::ByteSwapToLE16(header_size);
20   fourcc = base::ByteSwapToLE32(fourcc);
21   width = base::ByteSwapToLE16(width);
22   height = base::ByteSwapToLE16(height);
23   timebase_denum = base::ByteSwapToLE32(timebase_denum);
24   timebase_num = base::ByteSwapToLE32(timebase_num);
25   num_frames = base::ByteSwapToLE32(num_frames);
26   unused = base::ByteSwapToLE32(unused);
27 }
28
29 void IvfFrameHeader::ByteSwap() {
30   frame_size = base::ByteSwapToLE32(frame_size);
31   timestamp = base::ByteSwapToLE64(timestamp);
32 }
33
34 IvfParser::IvfParser() : ptr_(nullptr), end_(nullptr) {}
35
36 bool IvfParser::Initialize(const uint8_t* stream,
37                            size_t size,
38                            IvfFileHeader* file_header) {
39   DCHECK(stream);
40   DCHECK(file_header);
41   ptr_ = stream;
42   end_ = stream + size;
43   CHECK_GE(end_, ptr_);
44
45   if (size < sizeof(IvfFileHeader)) {
46     DLOG(ERROR) << "EOF before file header";
47     return false;
48   }
49
50   memcpy(file_header, ptr_, sizeof(IvfFileHeader));
51   file_header->ByteSwap();
52
53   if (memcmp(file_header->signature, kIvfHeaderSignature,
54              sizeof(file_header->signature)) != 0) {
55     DLOG(ERROR) << "IVF signature mismatch";
56     return false;
57   }
58   DLOG_IF(WARNING, file_header->version != 0)
59       << "IVF version unknown: " << file_header->version
60       << ", the parser may not be able to parse correctly";
61   if (file_header->header_size != sizeof(IvfFileHeader)) {
62     DLOG(ERROR) << "IVF file header size mismatch";
63     return false;
64   }
65
66   ptr_ += sizeof(IvfFileHeader);
67
68   return true;
69 }
70
71 bool IvfParser::ParseNextFrame(IvfFrameHeader* frame_header,
72                                const uint8_t** payload) {
73   DCHECK(ptr_);
74   DCHECK(payload);
75   CHECK_GE(end_, ptr_);
76
77   if (base::checked_cast<size_t>(end_ - ptr_) < sizeof(IvfFrameHeader)) {
78     DLOG_IF(ERROR, ptr_ != end_) << "Incomplete frame header";
79     return false;
80   }
81
82   memcpy(frame_header, ptr_, sizeof(IvfFrameHeader));
83   frame_header->ByteSwap();
84   ptr_ += sizeof(IvfFrameHeader);
85
86   if (base::checked_cast<uint32_t>(end_ - ptr_) < frame_header->frame_size) {
87     DLOG(ERROR) << "Not enough frame data";
88     return false;
89   }
90
91   *payload = ptr_;
92   ptr_ += frame_header->frame_size;
93
94   return true;
95 }
96
97 }  // namespace media