1 // Copyright (c) 2015 The WebM project authors. All Rights Reserved.
2 //
3 // Use of this source code is governed by a BSD-style license
4 // that can be found in the LICENSE file in the root of the source
5 // tree. An additional intellectual property rights grant can be found
6 // in the file PATENTS. All contributing project authors may
7 // be found in the AUTHORS file in the root of the source tree.
8 #include "common/libwebm_util.h"
9
10 #include <cassert>
11 #include <cstdint>
12 #include <cstdio>
13 #include <limits>
14
15 namespace libwebm {
16
NanosecondsTo90KhzTicks(std::int64_t nanoseconds)17 std::int64_t NanosecondsTo90KhzTicks(std::int64_t nanoseconds) {
18 const double pts_seconds = nanoseconds / kNanosecondsPerSecond;
19 return static_cast<std::int64_t>(pts_seconds * 90000);
20 }
21
Khz90TicksToNanoseconds(std::int64_t ticks)22 std::int64_t Khz90TicksToNanoseconds(std::int64_t ticks) {
23 const double seconds = ticks / 90000.0;
24 return static_cast<std::int64_t>(seconds * kNanosecondsPerSecond);
25 }
26
ParseVP9SuperFrameIndex(const std::uint8_t * frame,std::size_t frame_length,Ranges * frame_ranges,bool * error)27 bool ParseVP9SuperFrameIndex(const std::uint8_t* frame,
28 std::size_t frame_length, Ranges* frame_ranges,
29 bool* error) {
30 if (frame == nullptr || frame_length == 0 || frame_ranges == nullptr ||
31 error == nullptr) {
32 return false;
33 }
34
35 bool parse_ok = false;
36 const std::uint8_t marker = frame[frame_length - 1];
37 const std::uint32_t kHasSuperFrameIndexMask = 0xe0;
38 const std::uint32_t kSuperFrameMarker = 0xc0;
39 const std::uint32_t kLengthFieldSizeMask = 0x3;
40
41 if ((marker & kHasSuperFrameIndexMask) == kSuperFrameMarker) {
42 const std::uint32_t kFrameCountMask = 0x7;
43 const int num_frames = (marker & kFrameCountMask) + 1;
44 const int length_field_size = ((marker >> 3) & kLengthFieldSizeMask) + 1;
45 const std::size_t index_length = 2 + length_field_size * num_frames;
46
47 if (frame_length < index_length) {
48 std::fprintf(stderr,
49 "VP9ParseSuperFrameIndex: Invalid superframe index size.\n");
50 *error = true;
51 return false;
52 }
53
54 // Consume the super frame index. Note: it's at the end of the super frame.
55 const std::size_t length = frame_length - index_length;
56
57 if (length >= index_length &&
58 frame[frame_length - index_length] == marker) {
59 // Found a valid superframe index.
60 const std::uint8_t* byte = frame + length + 1;
61
62 std::size_t frame_offset = 0;
63
64 for (int i = 0; i < num_frames; ++i) {
65 std::uint32_t child_frame_length = 0;
66
67 for (int j = 0; j < length_field_size; ++j) {
68 child_frame_length |= (*byte++) << (j * 8);
69 }
70
71 if (length - frame_offset < child_frame_length) {
72 std::fprintf(stderr,
73 "ParseVP9SuperFrameIndex: Invalid superframe, sub frame "
74 "larger than entire frame.\n");
75 *error = true;
76 return false;
77 }
78
79 frame_ranges->push_back(Range(frame_offset, child_frame_length));
80 frame_offset += child_frame_length;
81 }
82
83 if (static_cast<int>(frame_ranges->size()) != num_frames) {
84 std::fprintf(stderr, "VP9Parse: superframe index parse failed.\n");
85 *error = true;
86 return false;
87 }
88
89 parse_ok = true;
90 } else {
91 std::fprintf(stderr, "VP9Parse: Invalid superframe index.\n");
92 *error = true;
93 }
94 }
95 return parse_ok;
96 }
97
WriteUint8(std::uint8_t val,std::FILE * fileptr)98 bool WriteUint8(std::uint8_t val, std::FILE* fileptr) {
99 if (fileptr == nullptr)
100 return false;
101 return (std::fputc(val, fileptr) == val);
102 }
103
ReadUint16(const std::uint8_t * buf)104 std::uint16_t ReadUint16(const std::uint8_t* buf) {
105 if (buf == nullptr)
106 return 0;
107 return ((buf[0] << 8) | buf[1]);
108 }
109
110 } // namespace libwebm
111