blob: b4dad1fe134fc707c6b10b1287a354c1dbbb4e7f [file] [log] [blame]
// 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