123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- // Copyright 2019 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "media/formats/mp4/nalu_test_helper.h"
- #include "base/check_op.h"
- #include "base/strings/string_split.h"
- #include "base/strings/string_util.h"
- #include "media/video/h264_parser.h"
- #if BUILDFLAG(ENABLE_PLATFORM_HEVC)
- #include "media/video/h265_nalu_parser.h"
- #endif // BUILDFLAG(ENABLE_PLATFORM_HEVC)
- namespace media {
- namespace mp4 {
- namespace {
- template <typename T>
- void WriteNALUType(std::vector<uint8_t>* buffer,
- const std::string& nal_unit_type);
- H264NALU::Type H264StringToNALUType(const std::string& name) {
- if (name == "P")
- return H264NALU::kNonIDRSlice;
- if (name == "I")
- return H264NALU::kIDRSlice;
- if (name == "SDA")
- return H264NALU::kSliceDataA;
- if (name == "SDB")
- return H264NALU::kSliceDataB;
- if (name == "SDC")
- return H264NALU::kSliceDataC;
- if (name == "SEI")
- return H264NALU::kSEIMessage;
- if (name == "SPS")
- return H264NALU::kSPS;
- if (name == "SPSExt")
- return H264NALU::kSPSExt;
- if (name == "PPS")
- return H264NALU::kPPS;
- if (name == "AUD")
- return H264NALU::kAUD;
- if (name == "EOSeq")
- return H264NALU::kEOSeq;
- if (name == "EOStr")
- return H264NALU::kEOStream;
- if (name == "FILL")
- return H264NALU::kFiller;
- if (name == "Prefix")
- return H264NALU::kPrefix;
- if (name == "SubsetSPS")
- return H264NALU::kSubsetSPS;
- if (name == "DPS")
- return H264NALU::kDPS;
- CHECK(false) << "Unexpected name: " << name;
- return H264NALU::kUnspecified;
- }
- template <>
- void WriteNALUType<H264NALU>(std::vector<uint8_t>* buffer,
- const std::string& nal_unit_type) {
- buffer->push_back(H264StringToNALUType(nal_unit_type));
- }
- #if BUILDFLAG(ENABLE_PLATFORM_HEVC)
- // Convert NALU type string to NALU type. It only supports a subset of all the
- // NALU types for testing purpose.
- H265NALU::Type H265StringToNALUType(const std::string& name) {
- if (name == "AUD")
- return H265NALU::AUD_NUT;
- if (name == "SPS")
- return H265NALU::SPS_NUT;
- if (name == "FD")
- return H265NALU::FD_NUT;
- if (name == "EOS")
- return H265NALU::EOS_NUT;
- if (name == "EOB")
- return H265NALU::EOB_NUT;
- // There're lots of H265 NALU I/P frames, return one from all possible types
- // for testing purpose, since we only care about the order of I/P frames and
- // other non VCL NALU.
- if (name == "P")
- return H265NALU::TRAIL_N;
- if (name == "I")
- return H265NALU::IDR_W_RADL;
- CHECK(false) << "Unexpected name: " << name;
- return H265NALU::EOB_NUT;
- }
- template <>
- void WriteNALUType<H265NALU>(std::vector<uint8_t>* buffer,
- const std::string& nal_unit_type) {
- uint8_t header1 = 0;
- uint8_t header2 = 0;
- uint8_t type = static_cast<uint8_t>(H265StringToNALUType(nal_unit_type));
- DCHECK_LT(type, 64);
- header1 |= (type << 1);
- buffer->push_back(header1);
- buffer->push_back(header2);
- }
- #endif // BUILDFLAG(ENABLE_PLATFORM_HEVC)
- template <typename T>
- void WriteStartCodeAndNALUType(std::vector<uint8_t>* buffer,
- const std::string& nal_unit_type) {
- buffer->push_back(0x00);
- buffer->push_back(0x00);
- buffer->push_back(0x00);
- buffer->push_back(0x01);
- WriteNALUType<T>(buffer, nal_unit_type);
- }
- template <typename T>
- void StringToAnnexB(const std::string& str,
- std::vector<uint8_t>* buffer,
- std::vector<SubsampleEntry>* subsamples) {
- DCHECK(!str.empty());
- std::vector<std::string> subsample_specs = base::SplitString(
- str, " ", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
- DCHECK_GT(subsample_specs.size(), 0u);
- buffer->clear();
- for (size_t i = 0; i < subsample_specs.size(); ++i) {
- SubsampleEntry entry;
- size_t start = buffer->size();
- std::vector<std::string> subsample_nalus =
- base::SplitString(subsample_specs[i], ",", base::KEEP_WHITESPACE,
- base::SPLIT_WANT_NONEMPTY);
- DCHECK_GT(subsample_nalus.size(), 0u);
- for (size_t j = 0; j < subsample_nalus.size(); ++j) {
- WriteStartCodeAndNALUType<T>(buffer, subsample_nalus[j]);
- // Write junk for the payload since the current code doesn't
- // actually look at it.
- buffer->push_back(0x32);
- buffer->push_back(0x12);
- buffer->push_back(0x67);
- }
- entry.clear_bytes = buffer->size() - start;
- if (subsamples) {
- // Simulate the encrypted bits containing something that looks
- // like a SPS NALU.
- WriteStartCodeAndNALUType<T>(buffer, "SPS");
- }
- entry.cypher_bytes = buffer->size() - start - entry.clear_bytes;
- if (subsamples) {
- subsamples->push_back(entry);
- }
- }
- }
- } // namespace
- void AvcStringToAnnexB(const std::string& str,
- std::vector<uint8_t>* buffer,
- std::vector<SubsampleEntry>* subsamples) {
- StringToAnnexB<H264NALU>(str, buffer, subsamples);
- }
- #if BUILDFLAG(ENABLE_PLATFORM_HEVC)
- void HevcStringToAnnexB(const std::string& str,
- std::vector<uint8_t>* buffer,
- std::vector<SubsampleEntry>* subsamples) {
- StringToAnnexB<H265NALU>(str, buffer, subsamples);
- }
- #endif // BUILDFLAG(ENABLE_PLATFORM_HEVC)
- bool AnalysesMatch(const BitstreamConverter::AnalysisResult& r1,
- const BitstreamConverter::AnalysisResult& r2) {
- return r1.is_conformant == r2.is_conformant &&
- r1.is_keyframe == r2.is_keyframe;
- }
- } // namespace mp4
- } // namespace media
|