mp4_stream_parser_unittest.cc 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854
  1. // Copyright 2014 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/mp4_stream_parser.h"
  5. #include <stddef.h>
  6. #include <stdint.h>
  7. #include <algorithm>
  8. #include <memory>
  9. #include <string>
  10. #include <tuple>
  11. #include "base/bind.h"
  12. #include "base/callback_helpers.h"
  13. #include "base/logging.h"
  14. #include "base/memory/ref_counted.h"
  15. #include "base/test/metrics/histogram_tester.h"
  16. #include "base/test/mock_callback.h"
  17. #include "base/time/time.h"
  18. #include "media/base/audio_decoder_config.h"
  19. #include "media/base/decoder_buffer.h"
  20. #include "media/base/media_switches.h"
  21. #include "media/base/media_track.h"
  22. #include "media/base/media_tracks.h"
  23. #include "media/base/mock_media_log.h"
  24. #include "media/base/stream_parser.h"
  25. #include "media/base/stream_parser_buffer.h"
  26. #include "media/base/test_data_util.h"
  27. #include "media/base/test_helpers.h"
  28. #include "media/base/text_track_config.h"
  29. #include "media/base/video_decoder_config.h"
  30. #include "media/formats/mp4/es_descriptor.h"
  31. #include "media/formats/mp4/fourccs.h"
  32. #include "media/media_buildflags.h"
  33. #include "testing/gmock/include/gmock/gmock.h"
  34. #include "testing/gtest/include/gtest/gtest-param-test.h"
  35. #include "testing/gtest/include/gtest/gtest.h"
  36. using ::testing::InSequence;
  37. using ::testing::StrictMock;
  38. namespace media {
  39. namespace mp4 {
  40. namespace {
  41. // Useful in single-track test media cases that need to verify
  42. // keyframe/non-keyframe sequence in output of parse.
  43. enum class Keyframeness {
  44. kKeyframe = 0,
  45. kNonKeyframe,
  46. };
  47. // Tells gtest how to print our Keyframeness enum values.
  48. std::ostream& operator<<(std::ostream& os, Keyframeness k) {
  49. return os << (k == Keyframeness::kKeyframe ? "kKeyframe" : "kNonKeyframe");
  50. }
  51. } // namespace
  52. // Matchers for verifying common media log entry strings.
  53. MATCHER(SampleEncryptionInfoUnavailableLog, "") {
  54. return CONTAINS_STRING(arg, "Sample encryption info is not available.");
  55. }
  56. MATCHER_P(ErrorLog, error_string, "") {
  57. return CONTAINS_STRING(arg, error_string) && CONTAINS_STRING(arg, "error");
  58. }
  59. MATCHER_P(DebugLog, debug_string, "") {
  60. return CONTAINS_STRING(arg, debug_string) && CONTAINS_STRING(arg, "debug");
  61. }
  62. class MP4StreamParserTest : public testing::Test {
  63. public:
  64. MP4StreamParserTest()
  65. : configs_received_(false),
  66. lower_bound_(kMaxDecodeTimestamp),
  67. verifying_keyframeness_sequence_(false) {
  68. std::set<int> audio_object_types;
  69. audio_object_types.insert(kISO_14496_3);
  70. parser_.reset(new MP4StreamParser(audio_object_types, false, false));
  71. }
  72. protected:
  73. StrictMock<MockMediaLog> media_log_;
  74. std::unique_ptr<MP4StreamParser> parser_;
  75. bool configs_received_;
  76. std::unique_ptr<MediaTracks> media_tracks_;
  77. AudioDecoderConfig audio_decoder_config_;
  78. VideoDecoderConfig video_decoder_config_;
  79. DecodeTimestamp lower_bound_;
  80. StreamParser::TrackId audio_track_id_;
  81. StreamParser::TrackId video_track_id_;
  82. bool verifying_keyframeness_sequence_;
  83. StrictMock<base::MockRepeatingCallback<void(Keyframeness)>> keyframeness_cb_;
  84. bool AppendData(const uint8_t* data, size_t length) {
  85. return parser_->Parse(data, length);
  86. }
  87. bool AppendDataInPieces(const uint8_t* data,
  88. size_t length,
  89. size_t piece_size) {
  90. const uint8_t* start = data;
  91. const uint8_t* end = data + length;
  92. while (start < end) {
  93. size_t append_size = std::min(piece_size,
  94. static_cast<size_t>(end - start));
  95. if (!AppendData(start, append_size))
  96. return false;
  97. start += append_size;
  98. }
  99. return true;
  100. }
  101. void InitF(const StreamParser::InitParameters& expected_params,
  102. const StreamParser::InitParameters& params) {
  103. DVLOG(1) << "InitF: dur=" << params.duration.InMicroseconds();
  104. EXPECT_EQ(expected_params.duration, params.duration);
  105. EXPECT_EQ(expected_params.timeline_offset, params.timeline_offset);
  106. EXPECT_EQ(expected_params.liveness, params.liveness);
  107. EXPECT_EQ(expected_params.detected_audio_track_count,
  108. params.detected_audio_track_count);
  109. EXPECT_EQ(expected_params.detected_video_track_count,
  110. params.detected_video_track_count);
  111. EXPECT_EQ(expected_params.detected_text_track_count,
  112. params.detected_text_track_count);
  113. }
  114. bool NewConfigF(std::unique_ptr<MediaTracks> tracks,
  115. const StreamParser::TextTrackConfigMap& tc) {
  116. configs_received_ = true;
  117. CHECK(tracks.get());
  118. DVLOG(1) << "NewConfigF: got " << tracks->tracks().size() << " tracks";
  119. for (const auto& track : tracks->tracks()) {
  120. const auto& track_id = track->bytestream_track_id();
  121. if (track->type() == MediaTrack::Audio) {
  122. audio_track_id_ = track_id;
  123. audio_decoder_config_ = tracks->getAudioConfig(track_id);
  124. DVLOG(1) << "track_id=" << track_id << " audio config="
  125. << (audio_decoder_config_.IsValidConfig()
  126. ? audio_decoder_config_.AsHumanReadableString()
  127. : "INVALID");
  128. } else if (track->type() == MediaTrack::Video) {
  129. video_track_id_ = track_id;
  130. video_decoder_config_ = tracks->getVideoConfig(track_id);
  131. DVLOG(1) << "track_id=" << track_id << " video config="
  132. << (video_decoder_config_.IsValidConfig()
  133. ? video_decoder_config_.AsHumanReadableString()
  134. : "INVALID");
  135. }
  136. }
  137. media_tracks_ = std::move(tracks);
  138. return true;
  139. }
  140. bool NewBuffersF(const StreamParser::BufferQueueMap& buffer_queue_map) {
  141. DecodeTimestamp lowest_end_dts = kNoDecodeTimestamp;
  142. for (const auto& [track_id, buffer_queue] : buffer_queue_map) {
  143. DVLOG(3) << "Buffers for track_id=" << track_id;
  144. DCHECK(!buffer_queue.empty());
  145. if (lowest_end_dts == kNoDecodeTimestamp ||
  146. lowest_end_dts > buffer_queue.back()->GetDecodeTimestamp())
  147. lowest_end_dts = buffer_queue.back()->GetDecodeTimestamp();
  148. for (const auto& buf : buffer_queue) {
  149. DVLOG(3) << " track_id=" << buf->track_id()
  150. << ", size=" << buf->data_size()
  151. << ", pts=" << buf->timestamp().InSecondsF()
  152. << ", dts=" << buf->GetDecodeTimestamp().InSecondsF()
  153. << ", dur=" << buf->duration().InSecondsF();
  154. // Ensure that track ids are properly assigned on all emitted buffers.
  155. EXPECT_EQ(track_id, buf->track_id());
  156. // Let single-track tests verify the sequence of keyframes/nonkeyframes.
  157. if (verifying_keyframeness_sequence_) {
  158. keyframeness_cb_.Run(buf->is_key_frame()
  159. ? Keyframeness::kKeyframe
  160. : Keyframeness::kNonKeyframe);
  161. }
  162. }
  163. }
  164. EXPECT_NE(lowest_end_dts, kNoDecodeTimestamp);
  165. if (lower_bound_ != kNoDecodeTimestamp && lowest_end_dts < lower_bound_) {
  166. return false;
  167. }
  168. lower_bound_ = lowest_end_dts;
  169. return true;
  170. }
  171. void KeyNeededF(EmeInitDataType type, const std::vector<uint8_t>& init_data) {
  172. DVLOG(1) << "KeyNeededF: " << init_data.size();
  173. EXPECT_EQ(EmeInitDataType::CENC, type);
  174. EXPECT_FALSE(init_data.empty());
  175. }
  176. void NewSegmentF() {
  177. DVLOG(1) << "NewSegmentF";
  178. lower_bound_ = kNoDecodeTimestamp;
  179. }
  180. void EndOfSegmentF() {
  181. DVLOG(1) << "EndOfSegmentF()";
  182. lower_bound_ = kMaxDecodeTimestamp;
  183. }
  184. void InitializeParserWithInitParametersExpectations(
  185. StreamParser::InitParameters params) {
  186. parser_->Init(base::BindOnce(&MP4StreamParserTest::InitF,
  187. base::Unretained(this), params),
  188. base::BindRepeating(&MP4StreamParserTest::NewConfigF,
  189. base::Unretained(this)),
  190. base::BindRepeating(&MP4StreamParserTest::NewBuffersF,
  191. base::Unretained(this)),
  192. true,
  193. base::BindRepeating(&MP4StreamParserTest::KeyNeededF,
  194. base::Unretained(this)),
  195. base::BindRepeating(&MP4StreamParserTest::NewSegmentF,
  196. base::Unretained(this)),
  197. base::BindRepeating(&MP4StreamParserTest::EndOfSegmentF,
  198. base::Unretained(this)),
  199. &media_log_);
  200. }
  201. StreamParser::InitParameters GetDefaultInitParametersExpectations() {
  202. // Most unencrypted test mp4 files have zero duration and are treated as
  203. // live streams.
  204. StreamParser::InitParameters params(kInfiniteDuration);
  205. params.liveness = StreamLiveness::kLive;
  206. params.detected_audio_track_count = 1;
  207. params.detected_video_track_count = 1;
  208. params.detected_text_track_count = 0;
  209. return params;
  210. }
  211. void InitializeParserAndExpectLiveness(StreamLiveness liveness) {
  212. auto params = GetDefaultInitParametersExpectations();
  213. params.liveness = liveness;
  214. InitializeParserWithInitParametersExpectations(params);
  215. }
  216. void InitializeParser() {
  217. InitializeParserWithInitParametersExpectations(
  218. GetDefaultInitParametersExpectations());
  219. }
  220. bool ParseMP4File(const std::string& filename, int append_bytes) {
  221. scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile(filename);
  222. EXPECT_TRUE(AppendDataInPieces(buffer->data(),
  223. buffer->data_size(),
  224. append_bytes));
  225. return true;
  226. }
  227. };
  228. TEST_F(MP4StreamParserTest, UnalignedAppend) {
  229. // Test small, non-segment-aligned appends (small enough to exercise
  230. // incremental append system)
  231. InitializeParser();
  232. ParseMP4File("bear-1280x720-av_frag.mp4", 512);
  233. }
  234. TEST_F(MP4StreamParserTest, BytewiseAppend) {
  235. // Ensure no incremental errors occur when parsing
  236. InitializeParser();
  237. ParseMP4File("bear-1280x720-av_frag.mp4", 1);
  238. }
  239. TEST_F(MP4StreamParserTest, MultiFragmentAppend) {
  240. // Large size ensures multiple fragments are appended in one call (size is
  241. // larger than this particular test file)
  242. InitializeParser();
  243. ParseMP4File("bear-1280x720-av_frag.mp4", 768432);
  244. }
  245. TEST_F(MP4StreamParserTest, Flush) {
  246. // Flush while reading sample data, then start a new stream.
  247. InitializeParser();
  248. scoped_refptr<DecoderBuffer> buffer =
  249. ReadTestDataFile("bear-1280x720-av_frag.mp4");
  250. EXPECT_TRUE(AppendDataInPieces(buffer->data(), 65536, 512));
  251. parser_->Flush();
  252. EXPECT_TRUE(AppendDataInPieces(buffer->data(),
  253. buffer->data_size(),
  254. 512));
  255. }
  256. TEST_F(MP4StreamParserTest, Reinitialization) {
  257. InitializeParser();
  258. scoped_refptr<DecoderBuffer> buffer =
  259. ReadTestDataFile("bear-1280x720-av_frag.mp4");
  260. EXPECT_TRUE(AppendDataInPieces(buffer->data(),
  261. buffer->data_size(),
  262. 512));
  263. EXPECT_TRUE(AppendDataInPieces(buffer->data(),
  264. buffer->data_size(),
  265. 512));
  266. }
  267. TEST_F(MP4StreamParserTest, UnknownDuration_V0_AllBitsSet) {
  268. InitializeParser();
  269. // 32 bit duration field in mvhd box, all bits set.
  270. ParseMP4File(
  271. "bear-1280x720-av_frag-initsegment-mvhd_version_0-mvhd_duration_bits_all_"
  272. "set.mp4",
  273. 512);
  274. }
  275. TEST_F(MP4StreamParserTest, AVC_KeyAndNonKeyframeness_Match_Container) {
  276. // Both AVC video frames' keyframe-ness metadata matches the MP4:
  277. // Frame 0: AVC IDR, trun.first_sample_flags: sync sample that doesn't
  278. // depend on others.
  279. // Frame 1: AVC Non-IDR, tfhd.default_sample_flags: not sync sample, depends
  280. // on others.
  281. // This is the base case; see also the "Mismatches" cases, below.
  282. InSequence s; // The EXPECT* sequence matters for this test.
  283. auto params = GetDefaultInitParametersExpectations();
  284. params.detected_audio_track_count = 0;
  285. InitializeParserWithInitParametersExpectations(params);
  286. verifying_keyframeness_sequence_ = true;
  287. EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kKeyframe));
  288. EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kNonKeyframe));
  289. ParseMP4File("bear-640x360-v-2frames_frag.mp4", 512);
  290. }
  291. TEST_F(MP4StreamParserTest, AVC_Keyframeness_Mismatches_Container) {
  292. // The first AVC video frame's keyframe-ness metadata mismatches the MP4:
  293. // Frame 0: AVC IDR, trun.first_sample_flags: NOT sync sample, DEPENDS on
  294. // others.
  295. // Frame 1: AVC Non-IDR, tfhd.default_sample_flags: not sync sample, depends
  296. // on others.
  297. InSequence s; // The EXPECT* sequence matters for this test.
  298. auto params = GetDefaultInitParametersExpectations();
  299. params.detected_audio_track_count = 0;
  300. InitializeParserWithInitParametersExpectations(params);
  301. verifying_keyframeness_sequence_ = true;
  302. EXPECT_MEDIA_LOG(DebugLog(
  303. "ISO-BMFF container metadata for video frame indicates that the frame is "
  304. "not a keyframe, but the video frame contents indicate the opposite."));
  305. EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kKeyframe));
  306. EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kNonKeyframe));
  307. ParseMP4File("bear-640x360-v-2frames-keyframe-is-non-sync-sample_frag.mp4",
  308. 512);
  309. }
  310. TEST_F(MP4StreamParserTest, AVC_NonKeyframeness_Mismatches_Container) {
  311. // The second AVC video frame's keyframe-ness metadata mismatches the MP4:
  312. // Frame 0: AVC IDR, trun.first_sample_flags: sync sample that doesn't
  313. // depend on others.
  314. // Frame 1: AVC Non-IDR, tfhd.default_sample_flags: SYNC sample, DOES NOT
  315. // depend on others.
  316. InSequence s; // The EXPECT* sequence matters for this test.
  317. auto params = GetDefaultInitParametersExpectations();
  318. params.detected_audio_track_count = 0;
  319. InitializeParserWithInitParametersExpectations(params);
  320. verifying_keyframeness_sequence_ = true;
  321. EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kKeyframe));
  322. EXPECT_MEDIA_LOG(DebugLog(
  323. "ISO-BMFF container metadata for video frame indicates that the frame is "
  324. "a keyframe, but the video frame contents indicate the opposite."));
  325. EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kNonKeyframe));
  326. ParseMP4File("bear-640x360-v-2frames-nonkeyframe-is-sync-sample_frag.mp4",
  327. 512);
  328. }
  329. TEST_F(MP4StreamParserTest, MPEG2_AAC_LC) {
  330. InSequence s;
  331. std::set<int> audio_object_types;
  332. audio_object_types.insert(kISO_13818_7_AAC_LC);
  333. parser_.reset(new MP4StreamParser(audio_object_types, false, false));
  334. auto params = GetDefaultInitParametersExpectations();
  335. params.detected_video_track_count = 0;
  336. InitializeParserWithInitParametersExpectations(params);
  337. ParseMP4File("bear-mpeg2-aac-only_frag.mp4", 512);
  338. EXPECT_EQ(audio_decoder_config_.profile(), AudioCodecProfile::kUnknown);
  339. }
  340. TEST_F(MP4StreamParserTest, MPEG4_XHE_AAC) {
  341. InSequence s; // The keyframeness sequence matters for this test.
  342. std::set<int> audio_object_types;
  343. audio_object_types.insert(kISO_14496_3);
  344. parser_.reset(new MP4StreamParser(audio_object_types, false, false));
  345. auto params = GetDefaultInitParametersExpectations();
  346. params.detected_video_track_count = 0;
  347. InitializeParserWithInitParametersExpectations(params);
  348. // This test file contains a single audio keyframe followed by 23
  349. // non-keyframes.
  350. verifying_keyframeness_sequence_ = true;
  351. EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kKeyframe));
  352. EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kNonKeyframe)).Times(23);
  353. ParseMP4File("noise-xhe-aac.mp4", 512);
  354. EXPECT_EQ(audio_decoder_config_.profile(), AudioCodecProfile::kXHE_AAC);
  355. }
  356. // Test that a moov box is not always required after Flush() is called.
  357. TEST_F(MP4StreamParserTest, NoMoovAfterFlush) {
  358. InitializeParser();
  359. scoped_refptr<DecoderBuffer> buffer =
  360. ReadTestDataFile("bear-1280x720-av_frag.mp4");
  361. EXPECT_TRUE(AppendDataInPieces(buffer->data(),
  362. buffer->data_size(),
  363. 512));
  364. parser_->Flush();
  365. const int kFirstMoofOffset = 1307;
  366. EXPECT_TRUE(AppendDataInPieces(buffer->data() + kFirstMoofOffset,
  367. buffer->data_size() - kFirstMoofOffset,
  368. 512));
  369. }
  370. // Test an invalid file where there are encrypted samples, but
  371. // SampleEncryptionBox (senc) and SampleAuxiliaryInformation{Sizes|Offsets}Box
  372. // (saiz|saio) are missing.
  373. // The parser should fail instead of crash. See http://crbug.com/361347
  374. TEST_F(MP4StreamParserTest, MissingSampleEncryptionInfo) {
  375. InSequence s;
  376. // Encrypted test mp4 files have non-zero duration and are treated as
  377. // recorded streams.
  378. auto params = GetDefaultInitParametersExpectations();
  379. params.duration = base::Microseconds(23219);
  380. params.liveness = StreamLiveness::kRecorded;
  381. params.detected_video_track_count = 0;
  382. InitializeParserWithInitParametersExpectations(params);
  383. scoped_refptr<DecoderBuffer> buffer =
  384. ReadTestDataFile("bear-1280x720-a_frag-cenc_missing-saiz-saio.mp4");
  385. EXPECT_MEDIA_LOG(SampleEncryptionInfoUnavailableLog());
  386. EXPECT_FALSE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512));
  387. }
  388. // Test a file where all video samples start with an Access Unit
  389. // Delimiter (AUD) NALU.
  390. TEST_F(MP4StreamParserTest, VideoSamplesStartWithAUDs) {
  391. auto params = GetDefaultInitParametersExpectations();
  392. params.detected_audio_track_count = 0;
  393. InitializeParserWithInitParametersExpectations(params);
  394. ParseMP4File("bear-1280x720-av_with-aud-nalus_frag.mp4", 512);
  395. }
  396. TEST_F(MP4StreamParserTest, HEVC_in_MP4_container) {
  397. #if BUILDFLAG(ENABLE_PLATFORM_HEVC)
  398. bool expect_success = true;
  399. #else
  400. bool expect_success = false;
  401. EXPECT_MEDIA_LOG(ErrorLog("Unsupported VisualSampleEntry type hev1"));
  402. #endif
  403. auto params = GetDefaultInitParametersExpectations();
  404. params.duration = base::Microseconds(1002000);
  405. params.liveness = StreamLiveness::kRecorded;
  406. params.detected_audio_track_count = 0;
  407. InitializeParserWithInitParametersExpectations(params);
  408. scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile("bear-hevc-frag.mp4");
  409. EXPECT_EQ(expect_success,
  410. AppendDataInPieces(buffer->data(), buffer->data_size(), 512));
  411. #if BUILDFLAG(ENABLE_PLATFORM_HEVC)
  412. EXPECT_EQ(VideoCodec::kHEVC, video_decoder_config_.codec());
  413. EXPECT_EQ(HEVCPROFILE_MAIN, video_decoder_config_.profile());
  414. #endif
  415. }
  416. #if BUILDFLAG(ENABLE_PLATFORM_HEVC)
  417. TEST_F(MP4StreamParserTest, HEVC_KeyAndNonKeyframeness_Match_Container) {
  418. // Both HEVC video frames' keyframe-ness metadata matches the MP4:
  419. // Frame 0: HEVC IDR, trun.first_sample_flags: sync sample that doesn't
  420. // depend on others.
  421. // Frame 1: HEVC Non-IDR, tfhd.default_sample_flags: not sync sample, depends
  422. // on others.
  423. // This is the base case; see also the "Mismatches" cases, below.
  424. InSequence s; // The EXPECT* sequence matters for this test.
  425. auto params = GetDefaultInitParametersExpectations();
  426. params.detected_audio_track_count = 0;
  427. InitializeParserWithInitParametersExpectations(params);
  428. verifying_keyframeness_sequence_ = true;
  429. EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kKeyframe));
  430. EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kNonKeyframe));
  431. ParseMP4File("bear-320x240-v-2frames_frag-hevc.mp4", 256);
  432. }
  433. TEST_F(MP4StreamParserTest, HEVC_Keyframeness_Mismatches_Container) {
  434. // The first HEVC video frame's keyframe-ness metadata mismatches the MP4:
  435. // Frame 0: HEVC IDR, trun.first_sample_flags: NOT sync sample, DEPENDS on
  436. // others.
  437. // Frame 1: HEVC Non-IDR, tfhd.default_sample_flags: not sync sample, depends
  438. // on others.
  439. InSequence s; // The EXPECT* sequence matters for this test.
  440. auto params = GetDefaultInitParametersExpectations();
  441. params.detected_audio_track_count = 0;
  442. InitializeParserWithInitParametersExpectations(params);
  443. verifying_keyframeness_sequence_ = true;
  444. EXPECT_MEDIA_LOG(DebugLog(
  445. "ISO-BMFF container metadata for video frame indicates that the frame is "
  446. "not a keyframe, but the video frame contents indicate the opposite."));
  447. EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kKeyframe));
  448. EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kNonKeyframe));
  449. ParseMP4File(
  450. "bear-320x240-v-2frames-keyframe-is-non-sync-sample_frag-hevc.mp4", 256);
  451. }
  452. TEST_F(MP4StreamParserTest, HEVC_NonKeyframeness_Mismatches_Container) {
  453. // The second HEVC video frame's keyframe-ness metadata mismatches the MP4:
  454. // Frame 0: HEVC IDR, trun.first_sample_flags: sync sample that doesn't
  455. // depend on others.
  456. // Frame 1: HEVC Non-IDR, tfhd.default_sample_flags: SYNC sample, DOES NOT
  457. // depend on others.
  458. InSequence s; // The EXPECT* sequence matters for this test.
  459. auto params = GetDefaultInitParametersExpectations();
  460. params.detected_audio_track_count = 0;
  461. InitializeParserWithInitParametersExpectations(params);
  462. verifying_keyframeness_sequence_ = true;
  463. EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kKeyframe));
  464. EXPECT_MEDIA_LOG(DebugLog(
  465. "ISO-BMFF container metadata for video frame indicates that the frame is "
  466. "a keyframe, but the video frame contents indicate the opposite."));
  467. EXPECT_CALL(keyframeness_cb_, Run(Keyframeness::kNonKeyframe));
  468. ParseMP4File(
  469. "bear-320x240-v-2frames-nonkeyframe-is-sync-sample_frag-hevc.mp4", 256);
  470. }
  471. #endif
  472. // Sample encryption information is stored as CencSampleAuxiliaryDataFormat
  473. // (ISO/IEC 23001-7:2015 8) inside 'mdat' box. No SampleEncryption ('senc') box.
  474. TEST_F(MP4StreamParserTest, CencWithEncryptionInfoStoredAsAuxDataInMdat) {
  475. // Encrypted test mp4 files have non-zero duration and are treated as
  476. // recorded streams.
  477. auto params = GetDefaultInitParametersExpectations();
  478. params.duration = base::Microseconds(2736066);
  479. params.liveness = StreamLiveness::kRecorded;
  480. params.detected_audio_track_count = 0;
  481. InitializeParserWithInitParametersExpectations(params);
  482. scoped_refptr<DecoderBuffer> buffer =
  483. ReadTestDataFile("bear-1280x720-v_frag-cenc.mp4");
  484. EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512));
  485. }
  486. TEST_F(MP4StreamParserTest, CencWithSampleEncryptionBox) {
  487. // Encrypted test mp4 files have non-zero duration and are treated as
  488. // recorded streams.
  489. auto params = GetDefaultInitParametersExpectations();
  490. params.duration = base::Microseconds(2736066);
  491. params.liveness = StreamLiveness::kRecorded;
  492. params.detected_audio_track_count = 0;
  493. InitializeParserWithInitParametersExpectations(params);
  494. scoped_refptr<DecoderBuffer> buffer =
  495. ReadTestDataFile("bear-640x360-v_frag-cenc-senc.mp4");
  496. EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512));
  497. }
  498. TEST_F(MP4StreamParserTest, NaturalSizeWithoutPASP) {
  499. auto params = GetDefaultInitParametersExpectations();
  500. params.duration = base::Microseconds(1000966);
  501. params.liveness = StreamLiveness::kRecorded;
  502. params.detected_audio_track_count = 0;
  503. InitializeParserWithInitParametersExpectations(params);
  504. scoped_refptr<DecoderBuffer> buffer =
  505. ReadTestDataFile("bear-640x360-non_square_pixel-without_pasp.mp4");
  506. EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512));
  507. EXPECT_EQ(gfx::Size(639, 360), video_decoder_config_.natural_size());
  508. }
  509. TEST_F(MP4StreamParserTest, NaturalSizeWithPASP) {
  510. auto params = GetDefaultInitParametersExpectations();
  511. params.duration = base::Microseconds(1000966);
  512. params.liveness = StreamLiveness::kRecorded;
  513. params.detected_audio_track_count = 0;
  514. InitializeParserWithInitParametersExpectations(params);
  515. scoped_refptr<DecoderBuffer> buffer =
  516. ReadTestDataFile("bear-640x360-non_square_pixel-with_pasp.mp4");
  517. EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512));
  518. EXPECT_EQ(gfx::Size(639, 360), video_decoder_config_.natural_size());
  519. }
  520. TEST_F(MP4StreamParserTest, DemuxingAC3) {
  521. std::set<int> audio_object_types;
  522. audio_object_types.insert(kAC3);
  523. parser_.reset(new MP4StreamParser(audio_object_types, false, false));
  524. #if BUILDFLAG(ENABLE_PLATFORM_AC3_EAC3_AUDIO)
  525. bool expect_success = true;
  526. #else
  527. bool expect_success = false;
  528. EXPECT_MEDIA_LOG(ErrorLog("Unsupported audio format 0x61632d33 in stsd box"));
  529. #endif
  530. auto params = GetDefaultInitParametersExpectations();
  531. params.duration = base::Microseconds(1045000);
  532. params.liveness = StreamLiveness::kRecorded;
  533. params.detected_video_track_count = 0;
  534. InitializeParserWithInitParametersExpectations(params);
  535. scoped_refptr<DecoderBuffer> buffer =
  536. ReadTestDataFile("bear-ac3-only-frag.mp4");
  537. EXPECT_EQ(expect_success,
  538. AppendDataInPieces(buffer->data(), buffer->data_size(), 512));
  539. }
  540. TEST_F(MP4StreamParserTest, DemuxingEAC3) {
  541. std::set<int> audio_object_types;
  542. audio_object_types.insert(kEAC3);
  543. parser_.reset(new MP4StreamParser(audio_object_types, false, false));
  544. #if BUILDFLAG(ENABLE_PLATFORM_AC3_EAC3_AUDIO)
  545. bool expect_success = true;
  546. #else
  547. bool expect_success = false;
  548. EXPECT_MEDIA_LOG(ErrorLog("Unsupported audio format 0x65632d33 in stsd box"));
  549. #endif
  550. auto params = GetDefaultInitParametersExpectations();
  551. params.duration = base::Microseconds(1045000);
  552. params.liveness = StreamLiveness::kRecorded;
  553. params.detected_video_track_count = 0;
  554. InitializeParserWithInitParametersExpectations(params);
  555. scoped_refptr<DecoderBuffer> buffer =
  556. ReadTestDataFile("bear-eac3-only-frag.mp4");
  557. EXPECT_EQ(expect_success,
  558. AppendDataInPieces(buffer->data(), buffer->data_size(), 512));
  559. }
  560. TEST_F(MP4StreamParserTest, Flac) {
  561. parser_.reset(new MP4StreamParser(std::set<int>(), false, true));
  562. auto params = GetDefaultInitParametersExpectations();
  563. params.detected_video_track_count = 0;
  564. InitializeParserWithInitParametersExpectations(params);
  565. scoped_refptr<DecoderBuffer> buffer = ReadTestDataFile("bear-flac_frag.mp4");
  566. EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512));
  567. }
  568. TEST_F(MP4StreamParserTest, Flac192kHz) {
  569. parser_.reset(new MP4StreamParser(std::set<int>(), false, true));
  570. auto params = GetDefaultInitParametersExpectations();
  571. params.detected_video_track_count = 0;
  572. // 192kHz exceeds the range of AudioSampleEntry samplerate. The correct
  573. // samplerate should be applied from the dfLa STREAMINFO metadata block.
  574. EXPECT_MEDIA_LOG(FlacAudioSampleRateOverriddenByStreaminfo("0", "192000"));
  575. InitializeParserWithInitParametersExpectations(params);
  576. scoped_refptr<DecoderBuffer> buffer =
  577. ReadTestDataFile("bear-flac-192kHz_frag.mp4");
  578. EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512));
  579. }
  580. TEST_F(MP4StreamParserTest, Vp9) {
  581. auto params = GetDefaultInitParametersExpectations();
  582. params.detected_audio_track_count = 0;
  583. InitializeParserWithInitParametersExpectations(params);
  584. auto buffer = ReadTestDataFile("vp9-hdr-init-segment.mp4");
  585. EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512));
  586. EXPECT_EQ(video_decoder_config_.profile(), VP9PROFILE_PROFILE2);
  587. EXPECT_EQ(video_decoder_config_.level(), 31u);
  588. EXPECT_EQ(video_decoder_config_.color_space_info(),
  589. VideoColorSpace(VideoColorSpace::PrimaryID::BT2020,
  590. VideoColorSpace::TransferID::SMPTEST2084,
  591. VideoColorSpace::MatrixID::BT2020_NCL,
  592. gfx::ColorSpace::RangeID::LIMITED));
  593. ASSERT_TRUE(video_decoder_config_.hdr_metadata().has_value());
  594. const auto& hdr_metadata = *video_decoder_config_.hdr_metadata();
  595. EXPECT_EQ(hdr_metadata.max_content_light_level, 1000u);
  596. EXPECT_EQ(hdr_metadata.max_frame_average_light_level, 640u);
  597. const auto& color_volume_metadata = hdr_metadata.color_volume_metadata;
  598. constexpr float kColorCoordinateUnit = 1 / 16.0f;
  599. EXPECT_NEAR(color_volume_metadata.primary_r.x(), 0.68, kColorCoordinateUnit);
  600. EXPECT_NEAR(color_volume_metadata.primary_r.y(), 0.31998,
  601. kColorCoordinateUnit);
  602. EXPECT_NEAR(color_volume_metadata.primary_g.x(), 0.26496,
  603. kColorCoordinateUnit);
  604. EXPECT_NEAR(color_volume_metadata.primary_g.y(), 0.68998,
  605. kColorCoordinateUnit);
  606. EXPECT_NEAR(color_volume_metadata.primary_b.x(), 0.15, kColorCoordinateUnit);
  607. EXPECT_NEAR(color_volume_metadata.primary_b.y(), 0.05998,
  608. kColorCoordinateUnit);
  609. EXPECT_NEAR(color_volume_metadata.white_point.x(), 0.314,
  610. kColorCoordinateUnit);
  611. EXPECT_NEAR(color_volume_metadata.white_point.y(), 0.351,
  612. kColorCoordinateUnit);
  613. constexpr float kLuminanceMaxUnit = 1 / 8.0f;
  614. EXPECT_NEAR(color_volume_metadata.luminance_max, 1000.0f, kLuminanceMaxUnit);
  615. constexpr float kLuminanceMinUnit = 1 / 14.0;
  616. EXPECT_NEAR(color_volume_metadata.luminance_min, 0.01f, kLuminanceMinUnit);
  617. }
  618. TEST_F(MP4StreamParserTest, FourCCToString) {
  619. // A real FOURCC should print.
  620. EXPECT_EQ("mvex", FourCCToString(FOURCC_MVEX));
  621. // Invalid FOURCC should also print whenever ASCII values are printable.
  622. EXPECT_EQ("fake", FourCCToString(static_cast<FourCC>(0x66616b65)));
  623. // Invalid FORCC with non-printable values should not give error message.
  624. EXPECT_EQ("0x66616b00", FourCCToString(static_cast<FourCC>(0x66616b00)));
  625. }
  626. TEST_F(MP4StreamParserTest, MediaTrackInfoSourcing) {
  627. InitializeParser();
  628. ParseMP4File("bear-1280x720-av_frag.mp4", 4096);
  629. EXPECT_EQ(media_tracks_->tracks().size(), 2u);
  630. const MediaTrack& video_track = *(media_tracks_->tracks()[0]);
  631. EXPECT_EQ(video_track.type(), MediaTrack::Video);
  632. EXPECT_EQ(video_track.bytestream_track_id(), 1);
  633. EXPECT_EQ(video_track.kind().value(), "main");
  634. EXPECT_EQ(video_track.label().value(), "VideoHandler");
  635. EXPECT_EQ(video_track.language().value(), "und");
  636. const MediaTrack& audio_track = *(media_tracks_->tracks()[1]);
  637. EXPECT_EQ(audio_track.type(), MediaTrack::Audio);
  638. EXPECT_EQ(audio_track.bytestream_track_id(), 2);
  639. EXPECT_EQ(audio_track.kind().value(), "main");
  640. EXPECT_EQ(audio_track.label().value(), "SoundHandler");
  641. EXPECT_EQ(audio_track.language().value(), "und");
  642. }
  643. TEST_F(MP4StreamParserTest, TextTrackDetection) {
  644. auto params = GetDefaultInitParametersExpectations();
  645. params.detected_text_track_count = 1;
  646. InitializeParserWithInitParametersExpectations(params);
  647. scoped_refptr<DecoderBuffer> buffer =
  648. ReadTestDataFile("bear-1280x720-avt_subt_frag.mp4");
  649. EXPECT_TRUE(AppendDataInPieces(buffer->data(), buffer->data_size(), 512));
  650. }
  651. TEST_F(MP4StreamParserTest, MultiTrackFile) {
  652. auto params = GetDefaultInitParametersExpectations();
  653. params.duration = base::Milliseconds(4248);
  654. params.liveness = StreamLiveness::kRecorded;
  655. params.detected_audio_track_count = 2;
  656. params.detected_video_track_count = 2;
  657. InitializeParserWithInitParametersExpectations(params);
  658. ParseMP4File("bbb-320x240-2video-2audio.mp4", 4096);
  659. EXPECT_EQ(media_tracks_->tracks().size(), 4u);
  660. const MediaTrack& video_track1 = *(media_tracks_->tracks()[0]);
  661. EXPECT_EQ(video_track1.type(), MediaTrack::Video);
  662. EXPECT_EQ(video_track1.bytestream_track_id(), 1);
  663. EXPECT_EQ(video_track1.kind().value(), "main");
  664. EXPECT_EQ(video_track1.label().value(), "VideoHandler");
  665. EXPECT_EQ(video_track1.language().value(), "und");
  666. const MediaTrack& audio_track1 = *(media_tracks_->tracks()[1]);
  667. EXPECT_EQ(audio_track1.type(), MediaTrack::Audio);
  668. EXPECT_EQ(audio_track1.bytestream_track_id(), 2);
  669. EXPECT_EQ(audio_track1.kind().value(), "main");
  670. EXPECT_EQ(audio_track1.label().value(), "SoundHandler");
  671. EXPECT_EQ(audio_track1.language().value(), "und");
  672. const MediaTrack& video_track2 = *(media_tracks_->tracks()[2]);
  673. EXPECT_EQ(video_track2.type(), MediaTrack::Video);
  674. EXPECT_EQ(video_track2.bytestream_track_id(), 3);
  675. EXPECT_EQ(video_track2.kind().value(), "");
  676. EXPECT_EQ(video_track2.label().value(), "VideoHandler");
  677. EXPECT_EQ(video_track2.language().value(), "und");
  678. const MediaTrack& audio_track2 = *(media_tracks_->tracks()[3]);
  679. EXPECT_EQ(audio_track2.type(), MediaTrack::Audio);
  680. EXPECT_EQ(audio_track2.bytestream_track_id(), 4);
  681. EXPECT_EQ(audio_track2.kind().value(), "");
  682. EXPECT_EQ(audio_track2.label().value(), "SoundHandler");
  683. EXPECT_EQ(audio_track2.language().value(), "und");
  684. }
  685. // <cos(θ), sin(θ), θ expressed as a rotation Enum>
  686. using MatrixRotationTestCaseParam =
  687. std::tuple<double, double, VideoTransformation>;
  688. class MP4StreamParserRotationMatrixEvaluatorTest
  689. : public ::testing::TestWithParam<MatrixRotationTestCaseParam> {
  690. public:
  691. MP4StreamParserRotationMatrixEvaluatorTest() {
  692. std::set<int> audio_object_types;
  693. audio_object_types.insert(kISO_14496_3);
  694. parser_.reset(new MP4StreamParser(audio_object_types, false, false));
  695. }
  696. protected:
  697. std::unique_ptr<MP4StreamParser> parser_;
  698. };
  699. TEST_P(MP4StreamParserRotationMatrixEvaluatorTest, RotationCalculation) {
  700. TrackHeader track_header;
  701. MovieHeader movie_header;
  702. // Identity matrix, with 16.16 and 2.30 fixed points.
  703. uint32_t identity_matrix[9] = {1 << 16, 0, 0, 0, 1 << 16, 0, 0, 0, 1 << 30};
  704. memcpy(movie_header.display_matrix, identity_matrix, sizeof(identity_matrix));
  705. memcpy(track_header.display_matrix, identity_matrix, sizeof(identity_matrix));
  706. MatrixRotationTestCaseParam data = GetParam();
  707. // Insert fixed point decimal data into the rotation matrix.
  708. track_header.display_matrix[0] = std::get<0>(data) * (1 << 16);
  709. track_header.display_matrix[4] = std::get<0>(data) * (1 << 16);
  710. track_header.display_matrix[1] = -(std::get<1>(data) * (1 << 16));
  711. track_header.display_matrix[3] = std::get<1>(data) * (1 << 16);
  712. VideoTransformation expected = std::get<2>(data);
  713. VideoTransformation actual =
  714. parser_->CalculateRotation(track_header, movie_header);
  715. EXPECT_EQ(actual.rotation, expected.rotation);
  716. EXPECT_EQ(actual.mirrored, expected.mirrored);
  717. }
  718. MatrixRotationTestCaseParam rotation_test_cases[6] = {
  719. {1, 0, VideoTransformation(VIDEO_ROTATION_0)}, // cos(0) = 1, sin(0) = 0
  720. {0, -1,
  721. VideoTransformation(VIDEO_ROTATION_90)}, // cos(90) = 0, sin(90) =-1
  722. {-1, 0,
  723. VideoTransformation(VIDEO_ROTATION_180)}, // cos(180)=-1, sin(180)= 0
  724. {0, 1,
  725. VideoTransformation(VIDEO_ROTATION_270)}, // cos(270)= 0, sin(270)= 1
  726. {1, 1, VideoTransformation(VIDEO_ROTATION_0)}, // Error case
  727. {5, 5, VideoTransformation(VIDEO_ROTATION_0)}, // Error case
  728. };
  729. INSTANTIATE_TEST_SUITE_P(CheckMath,
  730. MP4StreamParserRotationMatrixEvaluatorTest,
  731. testing::ValuesIn(rotation_test_cases));
  732. } // namespace mp4
  733. } // namespace media