nalu_test_helper.cc 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "media/formats/mp4/nalu_test_helper.h"
  5. #include "base/check_op.h"
  6. #include "base/strings/string_split.h"
  7. #include "base/strings/string_util.h"
  8. #include "media/video/h264_parser.h"
  9. #if BUILDFLAG(ENABLE_PLATFORM_HEVC)
  10. #include "media/video/h265_nalu_parser.h"
  11. #endif // BUILDFLAG(ENABLE_PLATFORM_HEVC)
  12. namespace media {
  13. namespace mp4 {
  14. namespace {
  15. template <typename T>
  16. void WriteNALUType(std::vector<uint8_t>* buffer,
  17. const std::string& nal_unit_type);
  18. H264NALU::Type H264StringToNALUType(const std::string& name) {
  19. if (name == "P")
  20. return H264NALU::kNonIDRSlice;
  21. if (name == "I")
  22. return H264NALU::kIDRSlice;
  23. if (name == "SDA")
  24. return H264NALU::kSliceDataA;
  25. if (name == "SDB")
  26. return H264NALU::kSliceDataB;
  27. if (name == "SDC")
  28. return H264NALU::kSliceDataC;
  29. if (name == "SEI")
  30. return H264NALU::kSEIMessage;
  31. if (name == "SPS")
  32. return H264NALU::kSPS;
  33. if (name == "SPSExt")
  34. return H264NALU::kSPSExt;
  35. if (name == "PPS")
  36. return H264NALU::kPPS;
  37. if (name == "AUD")
  38. return H264NALU::kAUD;
  39. if (name == "EOSeq")
  40. return H264NALU::kEOSeq;
  41. if (name == "EOStr")
  42. return H264NALU::kEOStream;
  43. if (name == "FILL")
  44. return H264NALU::kFiller;
  45. if (name == "Prefix")
  46. return H264NALU::kPrefix;
  47. if (name == "SubsetSPS")
  48. return H264NALU::kSubsetSPS;
  49. if (name == "DPS")
  50. return H264NALU::kDPS;
  51. CHECK(false) << "Unexpected name: " << name;
  52. return H264NALU::kUnspecified;
  53. }
  54. template <>
  55. void WriteNALUType<H264NALU>(std::vector<uint8_t>* buffer,
  56. const std::string& nal_unit_type) {
  57. buffer->push_back(H264StringToNALUType(nal_unit_type));
  58. }
  59. #if BUILDFLAG(ENABLE_PLATFORM_HEVC)
  60. // Convert NALU type string to NALU type. It only supports a subset of all the
  61. // NALU types for testing purpose.
  62. H265NALU::Type H265StringToNALUType(const std::string& name) {
  63. if (name == "AUD")
  64. return H265NALU::AUD_NUT;
  65. if (name == "SPS")
  66. return H265NALU::SPS_NUT;
  67. if (name == "FD")
  68. return H265NALU::FD_NUT;
  69. if (name == "EOS")
  70. return H265NALU::EOS_NUT;
  71. if (name == "EOB")
  72. return H265NALU::EOB_NUT;
  73. // There're lots of H265 NALU I/P frames, return one from all possible types
  74. // for testing purpose, since we only care about the order of I/P frames and
  75. // other non VCL NALU.
  76. if (name == "P")
  77. return H265NALU::TRAIL_N;
  78. if (name == "I")
  79. return H265NALU::IDR_W_RADL;
  80. CHECK(false) << "Unexpected name: " << name;
  81. return H265NALU::EOB_NUT;
  82. }
  83. template <>
  84. void WriteNALUType<H265NALU>(std::vector<uint8_t>* buffer,
  85. const std::string& nal_unit_type) {
  86. uint8_t header1 = 0;
  87. uint8_t header2 = 0;
  88. uint8_t type = static_cast<uint8_t>(H265StringToNALUType(nal_unit_type));
  89. DCHECK_LT(type, 64);
  90. header1 |= (type << 1);
  91. buffer->push_back(header1);
  92. buffer->push_back(header2);
  93. }
  94. #endif // BUILDFLAG(ENABLE_PLATFORM_HEVC)
  95. template <typename T>
  96. void WriteStartCodeAndNALUType(std::vector<uint8_t>* buffer,
  97. const std::string& nal_unit_type) {
  98. buffer->push_back(0x00);
  99. buffer->push_back(0x00);
  100. buffer->push_back(0x00);
  101. buffer->push_back(0x01);
  102. WriteNALUType<T>(buffer, nal_unit_type);
  103. }
  104. template <typename T>
  105. void StringToAnnexB(const std::string& str,
  106. std::vector<uint8_t>* buffer,
  107. std::vector<SubsampleEntry>* subsamples) {
  108. DCHECK(!str.empty());
  109. std::vector<std::string> subsample_specs = base::SplitString(
  110. str, " ", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  111. DCHECK_GT(subsample_specs.size(), 0u);
  112. buffer->clear();
  113. for (size_t i = 0; i < subsample_specs.size(); ++i) {
  114. SubsampleEntry entry;
  115. size_t start = buffer->size();
  116. std::vector<std::string> subsample_nalus =
  117. base::SplitString(subsample_specs[i], ",", base::KEEP_WHITESPACE,
  118. base::SPLIT_WANT_NONEMPTY);
  119. DCHECK_GT(subsample_nalus.size(), 0u);
  120. for (size_t j = 0; j < subsample_nalus.size(); ++j) {
  121. WriteStartCodeAndNALUType<T>(buffer, subsample_nalus[j]);
  122. // Write junk for the payload since the current code doesn't
  123. // actually look at it.
  124. buffer->push_back(0x32);
  125. buffer->push_back(0x12);
  126. buffer->push_back(0x67);
  127. }
  128. entry.clear_bytes = buffer->size() - start;
  129. if (subsamples) {
  130. // Simulate the encrypted bits containing something that looks
  131. // like a SPS NALU.
  132. WriteStartCodeAndNALUType<T>(buffer, "SPS");
  133. }
  134. entry.cypher_bytes = buffer->size() - start - entry.clear_bytes;
  135. if (subsamples) {
  136. subsamples->push_back(entry);
  137. }
  138. }
  139. }
  140. } // namespace
  141. void AvcStringToAnnexB(const std::string& str,
  142. std::vector<uint8_t>* buffer,
  143. std::vector<SubsampleEntry>* subsamples) {
  144. StringToAnnexB<H264NALU>(str, buffer, subsamples);
  145. }
  146. #if BUILDFLAG(ENABLE_PLATFORM_HEVC)
  147. void HevcStringToAnnexB(const std::string& str,
  148. std::vector<uint8_t>* buffer,
  149. std::vector<SubsampleEntry>* subsamples) {
  150. StringToAnnexB<H265NALU>(str, buffer, subsamples);
  151. }
  152. #endif // BUILDFLAG(ENABLE_PLATFORM_HEVC)
  153. bool AnalysesMatch(const BitstreamConverter::AnalysisResult& r1,
  154. const BitstreamConverter::AnalysisResult& r2) {
  155. return r1.is_conformant == r2.is_conformant &&
  156. r1.is_keyframe == r2.is_keyframe;
  157. }
  158. } // namespace mp4
  159. } // namespace media