// Copyright (C) 2020 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // // frame parsing code is taken from libvpx decoder /* * Copyright (c) 2013 The WebM project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include "host-common/VpxFrameParser.h" #define VPX_DEBUG 0 #if VPX_DEBUG #define RED "\x1B[31m" #define GRN "\x1B[32m" #define YEL "\x1B[33m" #define BLU "\x1B[34m" #define MAG "\x1B[35m" #define CYN "\x1B[36m" #define WHT "\x1B[37m" #define RESET "\x1B[0m" #define VPX_PRINT(color, fmt, ...) \ fprintf(stderr, color "VpxFrameParser: %s:%d " fmt "\n" RESET, __func__, \ __LINE__, ##__VA_ARGS__); #else #define VPX_PRINT(fmt, ...) #endif #define VPX_INFO(fmt, ...) VPX_PRINT(RESET, fmt, ##__VA_ARGS__); #define VPX_WARN(fmt, ...) VPX_PRINT(YEL, fmt, ##__VA_ARGS__); #define VPX_ERROR(fmt, ...) VPX_PRINT(RED, fmt, ##__VA_ARGS__); namespace android { namespace emulation { VpxFrameParser::VpxFrameParser(int vpxtype, const uint8_t* data, size_t size) : type(vpxtype), bit_buffer(data), bit_buffer_end(data + size) { if (vpxtype == 8) { parse_vp8_uncompressed_header(); } else if (vpxtype == 9) { parse_vp9_uncompressed_header(); } } int VpxFrameParser::read_bit() { const size_t off = bit_offset; const size_t p = off >> 3; const int q = 7 - (int)(off & 0x7); if (bit_buffer + p < bit_buffer_end) { const int bit = (bit_buffer[p] >> q) & 1; bit_offset = off + 1; return bit; } else { return 0; } } int VpxFrameParser::read_literal(int bits) { int value = 0, bit; for (bit = bits - 1; bit >= 0; bit--) value |= read_bit() << bit; return value; } void VpxFrameParser::parse_vp9_uncompressed_header() { // http://downloads.webmproject.org/docs/vp9/vp9-bitstream_superframe-and-uncompressed-header_v1.0.pdf // FRAME_MARKER 2bits // version 1 bit // high 1 bit // profile = high << 1 + version // optional 1 bit // show_existing_frame 1 bit // optional 3 bit // frame_tyep 1 bit read_literal(2); int profile = read_bit(); profile |= read_bit() << 1; if (profile > 2) profile += read_bit(); int show_existing_frame = read_bit(); if (show_existing_frame) { read_literal(3); } m_is_key_frame = (read_bit() == KEY_FRAME); VPX_PRINT("found vp9 %s frame", m_is_key_frame ? "KEY" : "NON-KEY"); } void VpxFrameParser::parse_vp8_uncompressed_header() { // https://tools.ietf.org/html/rfc6386#section-9.1 m_is_key_frame = (read_bit() == KEY_FRAME); VPX_PRINT("found vp8 %s frame", m_is_key_frame ? "KEY" : "NON-KEY"); } } // namespace emulation } // namespace android