2022-08-26 15:44:59 +00:00
|
|
|
// Copyright 2016 Google LLC. All rights reserved.
|
2016-02-03 22:13:57 +00:00
|
|
|
//
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file or at
|
|
|
|
// https://developers.google.com/open-source/licenses/bsd
|
|
|
|
|
2023-10-10 23:51:11 +00:00
|
|
|
#include <packager/media/codecs/video_slice_header_parser.h>
|
2016-02-03 22:13:57 +00:00
|
|
|
|
2023-10-10 23:51:11 +00:00
|
|
|
#include <packager/media/base/rcheck.h>
|
|
|
|
#include <packager/media/codecs/avc_decoder_configuration_record.h>
|
|
|
|
#include <packager/media/codecs/hevc_decoder_configuration_record.h>
|
2016-02-03 22:13:57 +00:00
|
|
|
|
2016-05-20 21:19:33 +00:00
|
|
|
namespace shaka {
|
2016-02-03 22:13:57 +00:00
|
|
|
namespace media {
|
|
|
|
|
2016-02-22 23:32:22 +00:00
|
|
|
namespace {
|
|
|
|
|
2016-11-09 02:11:13 +00:00
|
|
|
size_t NumBitsToNumBytes(size_t size_in_bits) {
|
2016-02-22 23:32:22 +00:00
|
|
|
// Round-up division.
|
2016-11-09 02:11:13 +00:00
|
|
|
return (size_in_bits + 7) >> 3;
|
2016-02-22 23:32:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
2016-02-03 22:13:57 +00:00
|
|
|
H264VideoSliceHeaderParser::H264VideoSliceHeaderParser() {}
|
|
|
|
H264VideoSliceHeaderParser::~H264VideoSliceHeaderParser() {}
|
|
|
|
|
|
|
|
bool H264VideoSliceHeaderParser::Initialize(
|
|
|
|
const std::vector<uint8_t>& decoder_configuration) {
|
2016-05-25 17:33:53 +00:00
|
|
|
AVCDecoderConfigurationRecord config;
|
2016-02-26 22:34:14 +00:00
|
|
|
RCHECK(config.Parse(decoder_configuration));
|
2016-02-03 22:13:57 +00:00
|
|
|
|
2016-02-26 22:34:14 +00:00
|
|
|
for (size_t i = 0; i < config.nalu_count(); i++) {
|
2016-02-03 22:13:57 +00:00
|
|
|
int id;
|
2016-02-26 22:34:14 +00:00
|
|
|
const Nalu& nalu = config.nalu(i);
|
|
|
|
if (nalu.type() == Nalu::H264_SPS) {
|
2016-03-14 19:09:26 +00:00
|
|
|
RCHECK(parser_.ParseSps(nalu, &id) == H264Parser::kOk);
|
2020-08-06 00:08:53 +00:00
|
|
|
} else if (nalu.type() == Nalu::H264_PPS) {
|
2016-03-14 19:09:26 +00:00
|
|
|
RCHECK(parser_.ParsePps(nalu, &id) == H264Parser::kOk);
|
2016-02-26 22:34:14 +00:00
|
|
|
}
|
2016-02-03 22:13:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-07-16 22:09:25 +00:00
|
|
|
bool H264VideoSliceHeaderParser::ProcessNalu(const Nalu& nalu) {
|
|
|
|
int id;
|
|
|
|
switch (nalu.type()) {
|
|
|
|
case Nalu::H264_SPS:
|
|
|
|
return parser_.ParseSps(nalu, &id) == H264Parser::kOk;
|
|
|
|
case Nalu::H264_PPS:
|
|
|
|
return parser_.ParsePps(nalu, &id) == H264Parser::kOk;
|
|
|
|
default:
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-03 22:13:57 +00:00
|
|
|
int64_t H264VideoSliceHeaderParser::GetHeaderSize(const Nalu& nalu) {
|
|
|
|
DCHECK(nalu.is_video_slice());
|
|
|
|
H264SliceHeader slice_header;
|
|
|
|
if (parser_.ParseSliceHeader(nalu, &slice_header) != H264Parser::kOk)
|
|
|
|
return -1;
|
|
|
|
|
2016-02-22 23:32:22 +00:00
|
|
|
return NumBitsToNumBytes(slice_header.header_bit_size);
|
|
|
|
}
|
|
|
|
|
|
|
|
H265VideoSliceHeaderParser::H265VideoSliceHeaderParser() {}
|
|
|
|
H265VideoSliceHeaderParser::~H265VideoSliceHeaderParser() {}
|
|
|
|
|
|
|
|
bool H265VideoSliceHeaderParser::Initialize(
|
|
|
|
const std::vector<uint8_t>& decoder_configuration) {
|
|
|
|
int id;
|
2016-05-25 17:33:53 +00:00
|
|
|
HEVCDecoderConfigurationRecord hevc_config;
|
2016-02-22 23:32:22 +00:00
|
|
|
RCHECK(hevc_config.Parse(decoder_configuration));
|
|
|
|
|
|
|
|
for (size_t i = 0; i < hevc_config.nalu_count(); i++) {
|
|
|
|
const Nalu& nalu = hevc_config.nalu(i);
|
|
|
|
if (nalu.type() == Nalu::H265_SPS) {
|
|
|
|
RCHECK(parser_.ParseSps(nalu, &id) == H265Parser::kOk);
|
|
|
|
} else if (nalu.type() == Nalu::H265_PPS) {
|
|
|
|
RCHECK(parser_.ParsePps(nalu, &id) == H265Parser::kOk);
|
|
|
|
} else if (nalu.type() == Nalu::H265_VPS) {
|
|
|
|
// Ignore since it does not affect video slice header parsing.
|
|
|
|
} else {
|
|
|
|
VLOG(1) << "Ignoring decoder configuration Nalu of unknown type "
|
|
|
|
<< nalu.type();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-07-16 22:09:25 +00:00
|
|
|
bool H265VideoSliceHeaderParser::ProcessNalu(const Nalu& nalu) {
|
|
|
|
int id;
|
|
|
|
switch (nalu.type()) {
|
|
|
|
case Nalu::H265_SPS:
|
|
|
|
return parser_.ParseSps(nalu, &id) == H265Parser::kOk;
|
|
|
|
case Nalu::H265_PPS:
|
|
|
|
return parser_.ParsePps(nalu, &id) == H265Parser::kOk;
|
|
|
|
case Nalu::H265_VPS:
|
|
|
|
// Ignore since it does not affect video slice header parsing.
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-02-22 23:32:22 +00:00
|
|
|
int64_t H265VideoSliceHeaderParser::GetHeaderSize(const Nalu& nalu) {
|
|
|
|
DCHECK(nalu.is_video_slice());
|
|
|
|
H265SliceHeader slice_header;
|
|
|
|
if (parser_.ParseSliceHeader(nalu, &slice_header) != H265Parser::kOk)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return NumBitsToNumBytes(slice_header.header_bit_size);
|
2016-02-03 22:13:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace media
|
2016-05-20 21:19:33 +00:00
|
|
|
} // namespace shaka
|
2016-02-03 22:13:57 +00:00
|
|
|
|