1 // Copyright (C) 2020 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 //
16 // frame parsing code is taken from libvpx decoder
17 /*
18 * Copyright (c) 2013 The WebM project authors. All Rights Reserved.
19 *
20 * Use of this source code is governed by a BSD-style license
21 * that can be found in the LICENSE file in the root of the source
22 * tree. An additional intellectual property rights grant can be found
23 * in the file PATENTS. All contributing project authors may
24 * be found in the AUTHORS file in the root of the source tree.
25 */
26
27 #include "host-common/VpxFrameParser.h"
28
29 #define VPX_DEBUG 0
30
31 #if VPX_DEBUG
32 #define RED "\x1B[31m"
33 #define GRN "\x1B[32m"
34 #define YEL "\x1B[33m"
35 #define BLU "\x1B[34m"
36 #define MAG "\x1B[35m"
37 #define CYN "\x1B[36m"
38 #define WHT "\x1B[37m"
39 #define RESET "\x1B[0m"
40 #define VPX_PRINT(color, fmt, ...) \
41 fprintf(stderr, color "VpxFrameParser: %s:%d " fmt "\n" RESET, __func__, \
42 __LINE__, ##__VA_ARGS__);
43 #else
44 #define VPX_PRINT(fmt, ...)
45 #endif
46
47 #define VPX_INFO(fmt, ...) VPX_PRINT(RESET, fmt, ##__VA_ARGS__);
48 #define VPX_WARN(fmt, ...) VPX_PRINT(YEL, fmt, ##__VA_ARGS__);
49 #define VPX_ERROR(fmt, ...) VPX_PRINT(RED, fmt, ##__VA_ARGS__);
50
51 namespace android {
52 namespace emulation {
53
VpxFrameParser(int vpxtype,const uint8_t * data,size_t size)54 VpxFrameParser::VpxFrameParser(int vpxtype, const uint8_t* data, size_t size)
55 : type(vpxtype), bit_buffer(data), bit_buffer_end(data + size) {
56 if (vpxtype == 8) {
57 parse_vp8_uncompressed_header();
58 } else if (vpxtype == 9) {
59 parse_vp9_uncompressed_header();
60 }
61 }
62
read_bit()63 int VpxFrameParser::read_bit() {
64 const size_t off = bit_offset;
65 const size_t p = off >> 3;
66 const int q = 7 - (int)(off & 0x7);
67 if (bit_buffer + p < bit_buffer_end) {
68 const int bit = (bit_buffer[p] >> q) & 1;
69 bit_offset = off + 1;
70 return bit;
71 } else {
72 return 0;
73 }
74 }
75
read_literal(int bits)76 int VpxFrameParser::read_literal(int bits) {
77 int value = 0, bit;
78 for (bit = bits - 1; bit >= 0; bit--)
79 value |= read_bit() << bit;
80 return value;
81 }
82
parse_vp9_uncompressed_header()83 void VpxFrameParser::parse_vp9_uncompressed_header() {
84 // http://downloads.webmproject.org/docs/vp9/vp9-bitstream_superframe-and-uncompressed-header_v1.0.pdf
85 // FRAME_MARKER 2bits
86 // version 1 bit
87 // high 1 bit
88 // profile = high << 1 + version
89 // optional 1 bit
90 // show_existing_frame 1 bit
91 // optional 3 bit
92 // frame_tyep 1 bit
93
94 read_literal(2);
95 int profile = read_bit();
96 profile |= read_bit() << 1;
97 if (profile > 2)
98 profile += read_bit();
99 int show_existing_frame = read_bit();
100 if (show_existing_frame) {
101 read_literal(3);
102 }
103 m_is_key_frame = (read_bit() == KEY_FRAME);
104 VPX_PRINT("found vp9 %s frame", m_is_key_frame ? "KEY" : "NON-KEY");
105 }
106
parse_vp8_uncompressed_header()107 void VpxFrameParser::parse_vp8_uncompressed_header() {
108 // https://tools.ietf.org/html/rfc6386#section-9.1
109 m_is_key_frame = (read_bit() == KEY_FRAME);
110 VPX_PRINT("found vp8 %s frame", m_is_key_frame ? "KEY" : "NON-KEY");
111 }
112
113 } // namespace emulation
114 } // namespace android
115