frame_processor_unittest.cc 108 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581
  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 <stddef.h>
  5. #include <stdint.h>
  6. #include <cstring>
  7. #include <map>
  8. #include <memory>
  9. #include <string>
  10. #include <vector>
  11. #include "base/bind.h"
  12. #include "base/run_loop.h"
  13. #include "base/strings/string_number_conversions.h"
  14. #include "base/strings/string_split.h"
  15. #include "base/strings/string_util.h"
  16. #include "base/test/task_environment.h"
  17. #include "base/time/time.h"
  18. #include "media/base/media_log.h"
  19. #include "media/base/media_util.h"
  20. #include "media/base/mock_filters.h"
  21. #include "media/base/mock_media_log.h"
  22. #include "media/base/test_helpers.h"
  23. #include "media/base/timestamp_constants.h"
  24. #include "media/filters/chunk_demuxer.h"
  25. #include "media/filters/frame_processor.h"
  26. #include "testing/gtest/include/gtest/gtest.h"
  27. using base::Milliseconds;
  28. using ::testing::_;
  29. using ::testing::InSequence;
  30. using ::testing::StrictMock;
  31. using ::testing::Values;
  32. namespace {
  33. // Helpers to encode/decode a base::TimeDelta to/from a string, used in these
  34. // tests to populate coded frame payloads with an encoded version of the
  35. // original frame timestamp while (slightly) obfuscating the payload itself to
  36. // help ensure the payload itself is neither changed by frame processing nor
  37. // interpreted directly and mistakenly as a base::TimeDelta by frame processing.
  38. std::string EncodeTestPayload(base::TimeDelta timestamp) {
  39. return base::NumberToString(timestamp.InMicroseconds());
  40. }
  41. base::TimeDelta DecodeTestPayload(std::string payload) {
  42. int64_t microseconds = 0;
  43. CHECK(base::StringToInt64(payload, &microseconds));
  44. return base::Microseconds(microseconds);
  45. }
  46. } // namespace
  47. namespace media {
  48. typedef StreamParser::BufferQueue BufferQueue;
  49. typedef StreamParser::TrackId TrackId;
  50. // Used for setting expectations on callbacks. Using a StrictMock also lets us
  51. // test for missing or extra callbacks.
  52. class FrameProcessorTestCallbackHelper {
  53. public:
  54. FrameProcessorTestCallbackHelper() = default;
  55. FrameProcessorTestCallbackHelper(const FrameProcessorTestCallbackHelper&) =
  56. delete;
  57. FrameProcessorTestCallbackHelper& operator=(
  58. const FrameProcessorTestCallbackHelper&) = delete;
  59. virtual ~FrameProcessorTestCallbackHelper() = default;
  60. MOCK_METHOD1(OnParseWarning, void(const SourceBufferParseWarning));
  61. MOCK_METHOD1(PossibleDurationIncrease, void(base::TimeDelta new_duration));
  62. // Helper that calls the mock method as well as does basic sanity checks on
  63. // |new_duration|.
  64. void OnPossibleDurationIncrease(base::TimeDelta new_duration) {
  65. PossibleDurationIncrease(new_duration);
  66. ASSERT_NE(kNoTimestamp, new_duration);
  67. ASSERT_NE(kInfiniteDuration, new_duration);
  68. }
  69. MOCK_METHOD2(OnAppend,
  70. void(const DemuxerStream::Type type,
  71. const BufferQueue* buffers));
  72. MOCK_METHOD3(OnGroupStart,
  73. void(const DemuxerStream::Type type,
  74. DecodeTimestamp start_dts,
  75. base::TimeDelta start_pts));
  76. };
  77. class FrameProcessorTest : public ::testing::TestWithParam<bool> {
  78. public:
  79. FrameProcessorTest(const FrameProcessorTest&) = delete;
  80. FrameProcessorTest& operator=(const FrameProcessorTest&) = delete;
  81. protected:
  82. FrameProcessorTest()
  83. : append_window_end_(kInfiniteDuration),
  84. frame_duration_(Milliseconds(10)),
  85. audio_id_(1),
  86. video_id_(2) {
  87. use_sequence_mode_ = GetParam();
  88. frame_processor_ = std::make_unique<FrameProcessor>(
  89. base::BindRepeating(
  90. &FrameProcessorTestCallbackHelper::OnPossibleDurationIncrease,
  91. base::Unretained(&callbacks_)),
  92. &media_log_);
  93. frame_processor_->SetParseWarningCallback(
  94. base::BindRepeating(&FrameProcessorTestCallbackHelper::OnParseWarning,
  95. base::Unretained(&callbacks_)));
  96. }
  97. enum StreamFlags {
  98. HAS_AUDIO = 1 << 0,
  99. HAS_VIDEO = 1 << 1,
  100. OBSERVE_APPENDS_AND_GROUP_STARTS = 1 << 2,
  101. USE_AUDIO_CODEC_SUPPORTING_NONKEYFRAMES = 1 << 3
  102. };
  103. void AddTestTracks(int stream_flags) {
  104. const bool has_audio = (stream_flags & HAS_AUDIO) != 0;
  105. const bool has_video = (stream_flags & HAS_VIDEO) != 0;
  106. ASSERT_TRUE(has_audio || has_video);
  107. const bool setup_observers =
  108. (stream_flags & OBSERVE_APPENDS_AND_GROUP_STARTS) != 0;
  109. const bool support_audio_nonkeyframes =
  110. (stream_flags & USE_AUDIO_CODEC_SUPPORTING_NONKEYFRAMES) != 0;
  111. ASSERT_TRUE(has_audio || !support_audio_nonkeyframes);
  112. if (has_audio) {
  113. CreateAndConfigureStream(DemuxerStream::AUDIO, setup_observers,
  114. support_audio_nonkeyframes);
  115. ASSERT_TRUE(audio_);
  116. EXPECT_TRUE(frame_processor_->AddTrack(audio_id_, audio_.get()));
  117. SeekStream(audio_.get(), Milliseconds(0));
  118. }
  119. if (has_video) {
  120. CreateAndConfigureStream(DemuxerStream::VIDEO, setup_observers, false);
  121. ASSERT_TRUE(video_);
  122. EXPECT_TRUE(frame_processor_->AddTrack(video_id_, video_.get()));
  123. SeekStream(video_.get(), Milliseconds(0));
  124. }
  125. }
  126. void SetTimestampOffset(base::TimeDelta new_offset) {
  127. timestamp_offset_ = new_offset;
  128. frame_processor_->SetGroupStartTimestampIfInSequenceMode(timestamp_offset_);
  129. }
  130. base::TimeDelta MillisecondStringToTimestamp(std::string ts_string) {
  131. if (ts_string == "Min") {
  132. return kNoTimestamp;
  133. }
  134. if (ts_string == "Max") {
  135. return kInfiniteDuration;
  136. }
  137. // Handle large integers precisely without converting through a double.
  138. if (ts_string.find('.') == std::string::npos) {
  139. int64_t milliseconds;
  140. CHECK(base::StringToInt64(ts_string, &milliseconds));
  141. return Milliseconds(milliseconds);
  142. }
  143. double ts_double;
  144. CHECK(base::StringToDouble(ts_string, &ts_double));
  145. return Milliseconds(ts_double);
  146. }
  147. BufferQueue StringToBufferQueue(const std::string& buffers_to_append,
  148. const TrackId track_id,
  149. const DemuxerStream::Type type) {
  150. std::vector<std::string> timestamps = base::SplitString(
  151. buffers_to_append, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
  152. BufferQueue buffers;
  153. for (size_t i = 0; i < timestamps.size(); i++) {
  154. bool is_keyframe = false;
  155. if (base::EndsWith(timestamps[i], "K", base::CompareCase::SENSITIVE)) {
  156. is_keyframe = true;
  157. // Remove the "K" off of the token.
  158. timestamps[i] = timestamps[i].substr(0, timestamps[i].length() - 1);
  159. }
  160. // Use custom decode timestamp if included.
  161. std::vector<std::string> buffer_timestamps = base::SplitString(
  162. timestamps[i], "|", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
  163. if (buffer_timestamps.size() == 1)
  164. buffer_timestamps.push_back(buffer_timestamps[0]);
  165. CHECK_EQ(2u, buffer_timestamps.size());
  166. const base::TimeDelta pts =
  167. MillisecondStringToTimestamp(buffer_timestamps[0]);
  168. const DecodeTimestamp dts = DecodeTimestamp::FromPresentationTime(
  169. MillisecondStringToTimestamp(buffer_timestamps[1]));
  170. // Create buffer. Encode the original pts as the buffer's data to enable
  171. // later verification of possible buffer relocation in presentation
  172. // timeline due to coded frame processing.
  173. const std::string payload_string = EncodeTestPayload(pts);
  174. const char* pts_as_cstr = payload_string.c_str();
  175. scoped_refptr<StreamParserBuffer> buffer = StreamParserBuffer::CopyFrom(
  176. reinterpret_cast<const uint8_t*>(pts_as_cstr), strlen(pts_as_cstr),
  177. is_keyframe, type, track_id);
  178. CHECK(DecodeTestPayload(
  179. std::string(reinterpret_cast<const char*>(buffer->data()),
  180. buffer->data_size())) == pts);
  181. buffer->set_timestamp(pts);
  182. if (DecodeTimestamp::FromPresentationTime(pts) != dts) {
  183. buffer->SetDecodeTimestamp(dts);
  184. }
  185. buffer->set_duration(frame_duration_);
  186. buffers.push_back(buffer);
  187. }
  188. return buffers;
  189. }
  190. bool ProcessFrames(const std::string& audio_timestamps,
  191. const std::string& video_timestamps) {
  192. StreamParser::BufferQueueMap buffer_queue_map;
  193. const auto& audio_buffers =
  194. StringToBufferQueue(audio_timestamps, audio_id_, DemuxerStream::AUDIO);
  195. if (!audio_buffers.empty())
  196. buffer_queue_map.insert(std::make_pair(audio_id_, audio_buffers));
  197. const auto& video_buffers =
  198. StringToBufferQueue(video_timestamps, video_id_, DemuxerStream::VIDEO);
  199. if (!video_buffers.empty())
  200. buffer_queue_map.insert(std::make_pair(video_id_, video_buffers));
  201. return frame_processor_->ProcessFrames(
  202. buffer_queue_map, append_window_start_, append_window_end_,
  203. &timestamp_offset_);
  204. }
  205. // Compares |expected| to the buffered ranges of |stream| formatted into a
  206. // string as follows:
  207. //
  208. // If no ranges: "{ }"
  209. // If one range: "{ [start1,end1) }"
  210. // If multiple ranges, they are added space-delimited in sequence, like:
  211. // "{ [start1,end1) [start2,end2) }"
  212. //
  213. // startN and endN are the respective buffered start and end times of the
  214. // range in integer milliseconds.
  215. void CheckExpectedRangesByTimestamp(ChunkDemuxerStream* stream,
  216. const std::string& expected) {
  217. // Note, DemuxerStream::TEXT streams return [0,duration (==infinity here))
  218. Ranges<base::TimeDelta> r = stream->GetBufferedRanges(kInfiniteDuration);
  219. std::stringstream ss;
  220. ss << "{ ";
  221. for (size_t i = 0; i < r.size(); ++i) {
  222. int64_t start = r.start(i).InMilliseconds();
  223. int64_t end = r.end(i).InMilliseconds();
  224. ss << "[" << start << "," << end << ") ";
  225. }
  226. ss << "}";
  227. EXPECT_EQ(expected, ss.str());
  228. }
  229. void CheckReadStalls(ChunkDemuxerStream* stream) {
  230. int loop_count = 0;
  231. do {
  232. read_callback_called_ = false;
  233. stream->Read(base::BindOnce(&FrameProcessorTest::StoreStatusAndBuffer,
  234. base::Unretained(this)));
  235. base::RunLoop().RunUntilIdle();
  236. } while (++loop_count < 2 && read_callback_called_ &&
  237. last_read_status_ == DemuxerStream::kAborted);
  238. ASSERT_FALSE(read_callback_called_ &&
  239. last_read_status_ == DemuxerStream::kAborted)
  240. << "2 kAborted reads in a row. Giving up.";
  241. EXPECT_FALSE(read_callback_called_);
  242. }
  243. // Doesn't check keyframeness, but otherwise is the same as
  244. // CheckReadsAndOptionallyKeyframenessThenReadStalls().
  245. void CheckReadsThenReadStalls(ChunkDemuxerStream* stream,
  246. const std::string& expected) {
  247. CheckReadsAndOptionallyKeyframenessThenReadStalls(stream, expected, false);
  248. }
  249. // Checks keyframeness using
  250. // CheckReadsAndOptionallyKeyframenessThenReadStalls().
  251. void CheckReadsAndKeyframenessThenReadStalls(ChunkDemuxerStream* stream,
  252. const std::string& expected) {
  253. CheckReadsAndOptionallyKeyframenessThenReadStalls(stream, expected, true);
  254. }
  255. // Format of |expected| is a space-delimited sequence of
  256. // timestamp_in_ms:original_timestamp_in_ms. original_timestamp_in_ms (and the
  257. // colon) must be omitted if it is the same as timestamp_in_ms. If
  258. // |check_keyframeness| is true, then each frame in |expected| must end with
  259. // 'K' or 'N', which respectively must match the read result frames'
  260. // keyframeness.
  261. void CheckReadsAndOptionallyKeyframenessThenReadStalls(
  262. ChunkDemuxerStream* stream,
  263. const std::string& expected,
  264. bool check_keyframeness) {
  265. std::vector<std::string> timestamps = base::SplitString(
  266. expected, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
  267. std::stringstream ss;
  268. for (size_t i = 0; i < timestamps.size(); ++i) {
  269. int loop_count = 0;
  270. do {
  271. read_callback_called_ = false;
  272. stream->Read(base::BindOnce(&FrameProcessorTest::StoreStatusAndBuffer,
  273. base::Unretained(this)));
  274. base::RunLoop().RunUntilIdle();
  275. EXPECT_TRUE(read_callback_called_);
  276. } while (++loop_count < 2 &&
  277. last_read_status_ == DemuxerStream::kAborted);
  278. ASSERT_FALSE(last_read_status_ == DemuxerStream::kAborted)
  279. << "2 kAborted reads in a row. Giving up.";
  280. EXPECT_EQ(DemuxerStream::kOk, last_read_status_);
  281. EXPECT_FALSE(last_read_buffer_->end_of_stream());
  282. if (i > 0)
  283. ss << " ";
  284. int time_in_ms = last_read_buffer_->timestamp().InMilliseconds();
  285. ss << time_in_ms;
  286. // Decode the original_time_in_ms from the buffer's data.
  287. double original_time_in_ms;
  288. original_time_in_ms =
  289. DecodeTestPayload(std::string(reinterpret_cast<const char*>(
  290. last_read_buffer_->data()),
  291. last_read_buffer_->data_size()))
  292. .InMillisecondsF();
  293. if (original_time_in_ms != time_in_ms)
  294. ss << ":" << original_time_in_ms;
  295. // Detect full-discard preroll buffer.
  296. if (last_read_buffer_->discard_padding().first == kInfiniteDuration &&
  297. last_read_buffer_->discard_padding().second.is_zero()) {
  298. ss << "P";
  299. }
  300. // Conditionally check keyframeness.
  301. if (check_keyframeness) {
  302. if (last_read_buffer_->is_key_frame())
  303. ss << "K";
  304. else
  305. ss << "N";
  306. }
  307. }
  308. EXPECT_EQ(expected, ss.str());
  309. CheckReadStalls(stream);
  310. }
  311. // TODO(wolenetz): Refactor to instead verify the expected signalling or lack
  312. // thereof of new coded frame group by the FrameProcessor. See
  313. // https://crbug.com/580613.
  314. bool in_coded_frame_group() {
  315. return !frame_processor_->pending_notify_all_group_start_;
  316. }
  317. void SeekStream(ChunkDemuxerStream* stream, base::TimeDelta seek_time) {
  318. stream->AbortReads();
  319. stream->Seek(seek_time);
  320. stream->StartReturningData();
  321. }
  322. base::test::SingleThreadTaskEnvironment task_environment_;
  323. StrictMock<MockMediaLog> media_log_;
  324. StrictMock<FrameProcessorTestCallbackHelper> callbacks_;
  325. bool use_sequence_mode_;
  326. std::unique_ptr<FrameProcessor> frame_processor_;
  327. base::TimeDelta append_window_start_;
  328. base::TimeDelta append_window_end_;
  329. base::TimeDelta timestamp_offset_;
  330. base::TimeDelta frame_duration_;
  331. std::unique_ptr<ChunkDemuxerStream> audio_;
  332. std::unique_ptr<ChunkDemuxerStream> video_;
  333. const TrackId audio_id_;
  334. const TrackId video_id_;
  335. const BufferQueue empty_queue_;
  336. // StoreStatusAndBuffer's most recent result.
  337. DemuxerStream::Status last_read_status_;
  338. scoped_refptr<DecoderBuffer> last_read_buffer_;
  339. bool read_callback_called_;
  340. private:
  341. void StoreStatusAndBuffer(DemuxerStream::Status status,
  342. scoped_refptr<DecoderBuffer> buffer) {
  343. if (status == DemuxerStream::kOk && buffer.get()) {
  344. DVLOG(3) << __func__ << "status: " << status
  345. << " ts: " << buffer->timestamp().InSecondsF();
  346. } else {
  347. DVLOG(3) << __func__ << "status: " << status << " ts: n/a";
  348. }
  349. read_callback_called_ = true;
  350. last_read_status_ = status;
  351. last_read_buffer_ = buffer;
  352. }
  353. void CreateAndConfigureStream(DemuxerStream::Type type,
  354. bool setup_observers,
  355. bool support_audio_nonkeyframes) {
  356. // TODO(wolenetz/dalecurtis): Also test with splicing disabled?
  357. ChunkDemuxerStream* stream;
  358. switch (type) {
  359. case DemuxerStream::AUDIO: {
  360. ASSERT_FALSE(audio_);
  361. audio_ = std::make_unique<ChunkDemuxerStream>(DemuxerStream::AUDIO,
  362. MediaTrack::Id("1"));
  363. AudioDecoderConfig decoder_config;
  364. if (support_audio_nonkeyframes) {
  365. decoder_config = AudioDecoderConfig(
  366. AudioCodec::kAAC, kSampleFormatPlanarF32, CHANNEL_LAYOUT_STEREO,
  367. 1000, EmptyExtraData(), EncryptionScheme::kUnencrypted);
  368. decoder_config.set_profile(AudioCodecProfile::kXHE_AAC);
  369. } else {
  370. decoder_config =
  371. AudioDecoderConfig(AudioCodec::kVorbis, kSampleFormatPlanarF32,
  372. CHANNEL_LAYOUT_STEREO, 1000, EmptyExtraData(),
  373. EncryptionScheme::kUnencrypted);
  374. }
  375. frame_processor_->OnPossibleAudioConfigUpdate(decoder_config);
  376. ASSERT_TRUE(
  377. audio_->UpdateAudioConfig(decoder_config, false, &media_log_));
  378. stream = audio_.get();
  379. break;
  380. }
  381. case DemuxerStream::VIDEO: {
  382. ASSERT_FALSE(video_);
  383. ASSERT_FALSE(support_audio_nonkeyframes);
  384. video_ = std::make_unique<ChunkDemuxerStream>(DemuxerStream::VIDEO,
  385. MediaTrack::Id("2"));
  386. ASSERT_TRUE(video_->UpdateVideoConfig(TestVideoConfig::Normal(), false,
  387. &media_log_));
  388. stream = video_.get();
  389. break;
  390. }
  391. // TODO(wolenetz): Test text coded frame processing.
  392. case DemuxerStream::TEXT:
  393. case DemuxerStream::UNKNOWN: {
  394. ASSERT_FALSE(true);
  395. }
  396. }
  397. if (setup_observers) {
  398. stream->set_append_observer_for_testing(
  399. base::BindRepeating(&FrameProcessorTestCallbackHelper::OnAppend,
  400. base::Unretained(&callbacks_), type));
  401. stream->set_group_start_observer_for_testing(
  402. base::BindRepeating(&FrameProcessorTestCallbackHelper::OnGroupStart,
  403. base::Unretained(&callbacks_), type));
  404. }
  405. }
  406. };
  407. TEST_P(FrameProcessorTest, WrongTypeInAppendedBuffer) {
  408. AddTestTracks(HAS_AUDIO);
  409. EXPECT_FALSE(in_coded_frame_group());
  410. StreamParser::BufferQueueMap buffer_queue_map;
  411. const auto& audio_buffers =
  412. StringToBufferQueue("0K", audio_id_, DemuxerStream::VIDEO);
  413. buffer_queue_map.insert(std::make_pair(audio_id_, audio_buffers));
  414. EXPECT_MEDIA_LOG(FrameTypeMismatchesTrackType("video", "1"));
  415. ASSERT_FALSE(
  416. frame_processor_->ProcessFrames(buffer_queue_map, append_window_start_,
  417. append_window_end_, &timestamp_offset_));
  418. EXPECT_FALSE(in_coded_frame_group());
  419. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  420. CheckExpectedRangesByTimestamp(audio_.get(), "{ }");
  421. CheckReadStalls(audio_.get());
  422. }
  423. TEST_P(FrameProcessorTest, NonMonotonicallyIncreasingTimestampInOneCall) {
  424. AddTestTracks(HAS_AUDIO);
  425. EXPECT_MEDIA_LOG(ParsedBuffersNotInDTSSequence());
  426. EXPECT_FALSE(ProcessFrames("10K 0K", ""));
  427. EXPECT_FALSE(in_coded_frame_group());
  428. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  429. CheckExpectedRangesByTimestamp(audio_.get(), "{ }");
  430. CheckReadStalls(audio_.get());
  431. }
  432. TEST_P(FrameProcessorTest, AudioOnly_SingleFrame) {
  433. // Tests A: P(A) -> (a)
  434. InSequence s;
  435. AddTestTracks(HAS_AUDIO);
  436. if (use_sequence_mode_)
  437. frame_processor_->SetSequenceMode(true);
  438. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(10)));
  439. EXPECT_TRUE(ProcessFrames("0K", ""));
  440. EXPECT_TRUE(in_coded_frame_group());
  441. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  442. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,10) }");
  443. CheckReadsThenReadStalls(audio_.get(), "0");
  444. }
  445. TEST_P(FrameProcessorTest, VideoOnly_SingleFrame) {
  446. // Tests V: P(V) -> (v)
  447. InSequence s;
  448. AddTestTracks(HAS_VIDEO);
  449. if (use_sequence_mode_)
  450. frame_processor_->SetSequenceMode(true);
  451. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(10)));
  452. EXPECT_TRUE(ProcessFrames("", "0K"));
  453. EXPECT_TRUE(in_coded_frame_group());
  454. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  455. CheckExpectedRangesByTimestamp(video_.get(), "{ [0,10) }");
  456. CheckReadsThenReadStalls(video_.get(), "0");
  457. }
  458. TEST_P(FrameProcessorTest, AudioOnly_TwoFrames) {
  459. // Tests A: P(A0, A10) -> (a0, a10)
  460. InSequence s;
  461. AddTestTracks(HAS_AUDIO);
  462. if (use_sequence_mode_)
  463. frame_processor_->SetSequenceMode(true);
  464. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(20)));
  465. EXPECT_TRUE(ProcessFrames("0K 10K", ""));
  466. EXPECT_TRUE(in_coded_frame_group());
  467. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  468. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,20) }");
  469. CheckReadsThenReadStalls(audio_.get(), "0 10");
  470. }
  471. TEST_P(FrameProcessorTest, AudioOnly_SetOffsetThenSingleFrame) {
  472. // Tests A: STSO(50)+P(A0) -> TSO==50,(a0@50)
  473. InSequence s;
  474. AddTestTracks(HAS_AUDIO);
  475. if (use_sequence_mode_)
  476. frame_processor_->SetSequenceMode(true);
  477. SetTimestampOffset(Milliseconds(50));
  478. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(60)));
  479. EXPECT_TRUE(ProcessFrames("0K", ""));
  480. EXPECT_TRUE(in_coded_frame_group());
  481. EXPECT_EQ(Milliseconds(50), timestamp_offset_);
  482. CheckExpectedRangesByTimestamp(audio_.get(), "{ [50,60) }");
  483. // We do not stall on reading without seeking to 50ms due to
  484. // SourceBufferStream::kSeekToStartFudgeRoom().
  485. CheckReadsThenReadStalls(audio_.get(), "50:0");
  486. }
  487. TEST_P(FrameProcessorTest, AudioOnly_SetOffsetThenFrameTimestampBelowOffset) {
  488. // Tests A: STSO(50)+P(A20) ->
  489. // if sequence mode: TSO==30,(a20@50)
  490. // if segments mode: TSO==50,(a20@70)
  491. InSequence s;
  492. AddTestTracks(HAS_AUDIO);
  493. if (use_sequence_mode_)
  494. frame_processor_->SetSequenceMode(true);
  495. SetTimestampOffset(Milliseconds(50));
  496. if (use_sequence_mode_) {
  497. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(60)));
  498. } else {
  499. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(80)));
  500. }
  501. EXPECT_TRUE(ProcessFrames("20K", ""));
  502. EXPECT_TRUE(in_coded_frame_group());
  503. // We do not stall on reading without seeking to 50ms / 70ms due to
  504. // SourceBufferStream::kSeekToStartFudgeRoom().
  505. if (use_sequence_mode_) {
  506. EXPECT_EQ(Milliseconds(30), timestamp_offset_);
  507. CheckExpectedRangesByTimestamp(audio_.get(), "{ [50,60) }");
  508. CheckReadsThenReadStalls(audio_.get(), "50:20");
  509. } else {
  510. EXPECT_EQ(Milliseconds(50), timestamp_offset_);
  511. CheckExpectedRangesByTimestamp(audio_.get(), "{ [70,80) }");
  512. CheckReadsThenReadStalls(audio_.get(), "70:20");
  513. }
  514. }
  515. TEST_P(FrameProcessorTest, AudioOnly_SequentialProcessFrames) {
  516. // Tests A: P(A0,A10)+P(A20,A30) -> (a0,a10,a20,a30)
  517. InSequence s;
  518. AddTestTracks(HAS_AUDIO);
  519. if (use_sequence_mode_)
  520. frame_processor_->SetSequenceMode(true);
  521. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(20)));
  522. EXPECT_TRUE(ProcessFrames("0K 10K", ""));
  523. EXPECT_TRUE(in_coded_frame_group());
  524. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  525. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,20) }");
  526. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(40)));
  527. EXPECT_TRUE(ProcessFrames("20K 30K", ""));
  528. EXPECT_TRUE(in_coded_frame_group());
  529. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  530. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,40) }");
  531. CheckReadsThenReadStalls(audio_.get(), "0 10 20 30");
  532. }
  533. TEST_P(FrameProcessorTest, AudioOnly_NonSequentialProcessFrames) {
  534. // Tests A: P(A20,A30)+P(A0,A10) ->
  535. // if sequence mode: TSO==-20 after first P(), 20 after second P(), and
  536. // a(20@0,a30@10,a0@20,a10@30)
  537. // if segments mode: TSO==0,(a0,a10,a20,a30)
  538. InSequence s;
  539. AddTestTracks(HAS_AUDIO);
  540. if (use_sequence_mode_) {
  541. frame_processor_->SetSequenceMode(true);
  542. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(20)));
  543. } else {
  544. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(40)));
  545. }
  546. EXPECT_TRUE(ProcessFrames("20K 30K", ""));
  547. EXPECT_TRUE(in_coded_frame_group());
  548. if (use_sequence_mode_) {
  549. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,20) }");
  550. EXPECT_EQ(Milliseconds(-20), timestamp_offset_);
  551. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(40)));
  552. } else {
  553. CheckExpectedRangesByTimestamp(audio_.get(), "{ [20,40) }");
  554. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  555. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(20)));
  556. }
  557. EXPECT_TRUE(ProcessFrames("0K 10K", ""));
  558. EXPECT_TRUE(in_coded_frame_group());
  559. if (use_sequence_mode_) {
  560. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,40) }");
  561. EXPECT_EQ(Milliseconds(20), timestamp_offset_);
  562. CheckReadsThenReadStalls(audio_.get(), "0:20 10:30 20:0 30:10");
  563. } else {
  564. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,40) }");
  565. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  566. // Re-seek to 0ms now that we've appended data earlier than what has already
  567. // satisfied our initial seek to start, above.
  568. SeekStream(audio_.get(), Milliseconds(0));
  569. CheckReadsThenReadStalls(audio_.get(), "0 10 20 30");
  570. }
  571. }
  572. TEST_P(FrameProcessorTest, AudioVideo_SequentialProcessFrames) {
  573. // Tests AV: P(A0,A10;V0k,V10,V20)+P(A20,A30,A40,V30) ->
  574. // (a0,a10,a20,a30,a40);(v0,v10,v20,v30)
  575. InSequence s;
  576. AddTestTracks(HAS_AUDIO | HAS_VIDEO);
  577. if (use_sequence_mode_) {
  578. frame_processor_->SetSequenceMode(true);
  579. EXPECT_CALL(callbacks_,
  580. OnParseWarning(SourceBufferParseWarning::kMuxedSequenceMode));
  581. EXPECT_MEDIA_LOG(MuxedSequenceModeWarning());
  582. }
  583. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(30)));
  584. EXPECT_TRUE(ProcessFrames("0K 10K", "0K 10 20"));
  585. EXPECT_TRUE(in_coded_frame_group());
  586. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  587. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,20) }");
  588. CheckExpectedRangesByTimestamp(video_.get(), "{ [0,30) }");
  589. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(50)));
  590. EXPECT_TRUE(ProcessFrames("20K 30K 40K", "30"));
  591. EXPECT_TRUE(in_coded_frame_group());
  592. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  593. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,50) }");
  594. CheckExpectedRangesByTimestamp(video_.get(), "{ [0,40) }");
  595. CheckReadsThenReadStalls(audio_.get(), "0 10 20 30 40");
  596. CheckReadsThenReadStalls(video_.get(), "0 10 20 30");
  597. }
  598. TEST_P(FrameProcessorTest, AudioVideo_Discontinuity) {
  599. // Tests AV: P(A0,A10,A30,A40,A50;V0key,V10,V40,V50key) ->
  600. // if sequence mode: TSO==10,(a0,a10,a30,a40,a50@60);(v0,v10,v50@60)
  601. // if segments mode: TSO==0,(a0,a10,a30,a40,a50);(v0,v10,v50)
  602. // This assumes A40K is processed before V40, which depends currently on
  603. // MergeBufferQueues() behavior.
  604. InSequence s;
  605. AddTestTracks(HAS_AUDIO | HAS_VIDEO);
  606. if (use_sequence_mode_) {
  607. frame_processor_->SetSequenceMode(true);
  608. EXPECT_CALL(callbacks_,
  609. OnParseWarning(SourceBufferParseWarning::kMuxedSequenceMode));
  610. EXPECT_MEDIA_LOG(MuxedSequenceModeWarning());
  611. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(70)));
  612. } else {
  613. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(60)));
  614. }
  615. EXPECT_TRUE(ProcessFrames("0K 10K 30K 40K 50K", "0K 10 40 50K"));
  616. EXPECT_TRUE(in_coded_frame_group());
  617. if (use_sequence_mode_) {
  618. EXPECT_EQ(Milliseconds(10), timestamp_offset_);
  619. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,70) }");
  620. CheckExpectedRangesByTimestamp(video_.get(), "{ [0,20) [60,70) }");
  621. CheckReadsThenReadStalls(audio_.get(), "0 10 30 40 60:50");
  622. CheckReadsThenReadStalls(video_.get(), "0 10");
  623. SeekStream(video_.get(), Milliseconds(60));
  624. CheckReadsThenReadStalls(video_.get(), "60:50");
  625. } else {
  626. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  627. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,60) }");
  628. CheckExpectedRangesByTimestamp(video_.get(), "{ [0,20) [50,60) }");
  629. CheckReadsThenReadStalls(audio_.get(), "0 10 30 40 50");
  630. CheckReadsThenReadStalls(video_.get(), "0 10");
  631. SeekStream(video_.get(), Milliseconds(50));
  632. CheckReadsThenReadStalls(video_.get(), "50");
  633. }
  634. }
  635. TEST_P(FrameProcessorTest, AudioVideo_Discontinuity_TimestampOffset) {
  636. InSequence s;
  637. AddTestTracks(HAS_AUDIO | HAS_VIDEO);
  638. frame_processor_->SetSequenceMode(use_sequence_mode_);
  639. if (use_sequence_mode_) {
  640. EXPECT_CALL(callbacks_,
  641. OnParseWarning(SourceBufferParseWarning::kMuxedSequenceMode));
  642. EXPECT_MEDIA_LOG(MuxedSequenceModeWarning());
  643. }
  644. // Start a coded frame group at time 100ms. Note the jagged start still uses
  645. // the coded frame group's start time as the range start for both streams.
  646. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(140)));
  647. SetTimestampOffset(Milliseconds(100));
  648. EXPECT_TRUE(ProcessFrames("0K 10K 20K", "10K 20K 30K"));
  649. EXPECT_EQ(Milliseconds(100), timestamp_offset_);
  650. EXPECT_TRUE(in_coded_frame_group());
  651. CheckExpectedRangesByTimestamp(audio_.get(), "{ [100,130) }");
  652. CheckExpectedRangesByTimestamp(video_.get(), "{ [100,140) }");
  653. // Test the behavior of both 'sequence' and 'segments' mode if the coded frame
  654. // sequence jumps forward beyond the normal discontinuity threshold.
  655. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(240)));
  656. SetTimestampOffset(Milliseconds(200));
  657. EXPECT_TRUE(ProcessFrames("0K 10K 20K", "10K 20K 30K"));
  658. EXPECT_EQ(Milliseconds(200), timestamp_offset_);
  659. EXPECT_TRUE(in_coded_frame_group());
  660. CheckExpectedRangesByTimestamp(audio_.get(), "{ [100,130) [200,230) }");
  661. CheckExpectedRangesByTimestamp(video_.get(), "{ [100,140) [200,240) }");
  662. // Test the behavior when timestampOffset adjustment causes next frames to be
  663. // in the past relative to the previously processed frame and triggers a new
  664. // coded frame group.
  665. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(95)));
  666. SetTimestampOffset(Milliseconds(55));
  667. EXPECT_TRUE(ProcessFrames("0K 10K 20K", "10K 20K 30K"));
  668. EXPECT_EQ(Milliseconds(55), timestamp_offset_);
  669. EXPECT_TRUE(in_coded_frame_group());
  670. // The new audio range is not within SourceBufferStream's coalescing threshold
  671. // relative to the next range, but the new video range is within the
  672. // threshold.
  673. CheckExpectedRangesByTimestamp(audio_.get(),
  674. "{ [55,85) [100,130) [200,230) }");
  675. // Note that the range adjacency logic used in this case considers
  676. // DTS 85 to be close enough to [100,140), even though the first DTS in video
  677. // range [100,140) is actually 110. The muxed data started a coded frame
  678. // group at time 100, informing the adjacency logic.
  679. CheckExpectedRangesByTimestamp(video_.get(), "{ [55,140) [200,240) }");
  680. // Verify the buffers.
  681. // Re-seek now that we've appended data earlier than what already satisfied
  682. // our initial seek to start.
  683. SeekStream(audio_.get(), Milliseconds(55));
  684. CheckReadsThenReadStalls(audio_.get(), "55:0 65:10 75:20");
  685. SeekStream(audio_.get(), Milliseconds(100));
  686. CheckReadsThenReadStalls(audio_.get(), "100:0 110:10 120:20");
  687. SeekStream(audio_.get(), Milliseconds(200));
  688. CheckReadsThenReadStalls(audio_.get(), "200:0 210:10 220:20");
  689. SeekStream(video_.get(), Milliseconds(55));
  690. CheckReadsThenReadStalls(video_.get(),
  691. "65:10 75:20 85:30 110:10 120:20 130:30");
  692. SeekStream(video_.get(), Milliseconds(200));
  693. CheckReadsThenReadStalls(video_.get(), "210:10 220:20 230:30");
  694. }
  695. TEST_P(FrameProcessorTest, AudioVideo_OutOfSequence_After_Discontinuity) {
  696. // Once a discontinuity is detected (and all tracks drop everything until the
  697. // next keyframe per each track), we should gracefully handle the case where
  698. // some tracks' first keyframe after the discontinuity are appended after, but
  699. // end up earlier in timeline than some other track(s). In particular, we
  700. // shouldn't notify all tracks that a new coded frame group is starting and
  701. // begin dropping leading non-keyframes from all tracks. Rather, we should
  702. // notify just the track encountering this new type of discontinuity. Since
  703. // MSE doesn't require all media segments to contain media from every track,
  704. // these append sequences can occur.
  705. InSequence s;
  706. AddTestTracks(HAS_AUDIO | HAS_VIDEO);
  707. frame_processor_->SetSequenceMode(use_sequence_mode_);
  708. // Begin with a simple set of appends for all tracks.
  709. if (use_sequence_mode_) {
  710. // Allow room in the timeline for the last audio append (50K, below) in this
  711. // test to remain within default append window [0, +Infinity]. Moving the
  712. // sequence mode appends to begin at time 100ms, the same time as the first
  713. // append, below, results in a -20ms offset (instead of a -120ms offset)
  714. // applied to frames beginning at the first frame after the discontinuity
  715. // caused by the video append at 160K, below.
  716. SetTimestampOffset(Milliseconds(100));
  717. EXPECT_CALL(callbacks_,
  718. OnParseWarning(SourceBufferParseWarning::kMuxedSequenceMode));
  719. EXPECT_MEDIA_LOG(MuxedSequenceModeWarning());
  720. }
  721. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(140)));
  722. EXPECT_TRUE(ProcessFrames("100K 110K 120K", "110K 120K 130K"));
  723. EXPECT_TRUE(in_coded_frame_group());
  724. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  725. CheckExpectedRangesByTimestamp(audio_.get(), "{ [100,130) }");
  726. CheckExpectedRangesByTimestamp(video_.get(), "{ [100,140) }");
  727. // Trigger (normal) discontinuity with one track (video).
  728. if (use_sequence_mode_)
  729. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(150)));
  730. else
  731. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(170)));
  732. EXPECT_TRUE(ProcessFrames("", "160K"));
  733. EXPECT_TRUE(in_coded_frame_group());
  734. if (use_sequence_mode_) {
  735. // The new video buffer is relocated into [140,150).
  736. EXPECT_EQ(Milliseconds(-20), timestamp_offset_);
  737. CheckExpectedRangesByTimestamp(audio_.get(), "{ [100,130) }");
  738. CheckExpectedRangesByTimestamp(video_.get(), "{ [100,150) }");
  739. } else {
  740. // The new video buffer is at [160,170).
  741. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  742. CheckExpectedRangesByTimestamp(audio_.get(), "{ [100,130) }");
  743. CheckExpectedRangesByTimestamp(video_.get(), "{ [100,140) [160,170) }");
  744. }
  745. // Append to the other track (audio) with lower time than the video frame we
  746. // just appended. Append with a timestamp such that segments mode demonstrates
  747. // we don't retroactively extend the new video buffer appended above's range
  748. // start back to this audio start time.
  749. if (use_sequence_mode_)
  750. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(150)));
  751. else
  752. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(170)));
  753. EXPECT_TRUE(ProcessFrames("50K", ""));
  754. EXPECT_TRUE(in_coded_frame_group());
  755. // Because this is the first audio buffer appended following the discontinuity
  756. // detected while appending the video frame, above, a new coded frame group
  757. // for video is not triggered.
  758. if (use_sequence_mode_) {
  759. // The new audio buffer is relocated into [30,40). Note the muxed 'sequence'
  760. // mode append mode results in a buffered range gap in this case.
  761. EXPECT_EQ(Milliseconds(-20), timestamp_offset_);
  762. CheckExpectedRangesByTimestamp(audio_.get(), "{ [30,40) [100,130) }");
  763. CheckExpectedRangesByTimestamp(video_.get(), "{ [100,150) }");
  764. } else {
  765. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  766. CheckExpectedRangesByTimestamp(audio_.get(), "{ [50,60) [100,130) }");
  767. CheckExpectedRangesByTimestamp(video_.get(), "{ [100,140) [160,170) }");
  768. }
  769. // Finally, append a non-keyframe to the first track (video), to continue the
  770. // GOP that started the normal discontinuity on the previous video append.
  771. if (use_sequence_mode_)
  772. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(160)));
  773. else
  774. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(180)));
  775. EXPECT_TRUE(ProcessFrames("", "170"));
  776. EXPECT_TRUE(in_coded_frame_group());
  777. // Verify the final buffers. First, re-seek audio since we appended data
  778. // earlier than what already satisfied our initial seek to start. We satisfy
  779. // the seek with the first buffer in [0,1000).
  780. SeekStream(audio_.get(), Milliseconds(0));
  781. if (use_sequence_mode_) {
  782. // The new video buffer is relocated into [150,160).
  783. EXPECT_EQ(Milliseconds(-20), timestamp_offset_);
  784. CheckExpectedRangesByTimestamp(audio_.get(), "{ [30,40) [100,130) }");
  785. CheckReadsThenReadStalls(audio_.get(), "30:50");
  786. SeekStream(audio_.get(), Milliseconds(100));
  787. CheckReadsThenReadStalls(audio_.get(), "100 110 120");
  788. CheckExpectedRangesByTimestamp(video_.get(), "{ [100,160) }");
  789. CheckReadsThenReadStalls(video_.get(), "110 120 130 140:160 150:170");
  790. } else {
  791. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  792. CheckExpectedRangesByTimestamp(audio_.get(), "{ [50,60) [100,130) }");
  793. CheckReadsThenReadStalls(audio_.get(), "50");
  794. SeekStream(audio_.get(), Milliseconds(100));
  795. CheckReadsThenReadStalls(audio_.get(), "100 110 120");
  796. CheckExpectedRangesByTimestamp(video_.get(), "{ [100,140) [160,180) }");
  797. CheckReadsThenReadStalls(video_.get(), "110 120 130");
  798. SeekStream(video_.get(), Milliseconds(160));
  799. CheckReadsThenReadStalls(video_.get(), "160 170");
  800. }
  801. }
  802. TEST_P(FrameProcessorTest,
  803. AppendWindowFilterOfNegativeBufferTimestampsWithPrerollDiscard) {
  804. InSequence s;
  805. AddTestTracks(HAS_AUDIO);
  806. if (use_sequence_mode_)
  807. frame_processor_->SetSequenceMode(true);
  808. SetTimestampOffset(Milliseconds(-20));
  809. EXPECT_MEDIA_LOG(DroppedFrame("audio", -20000));
  810. EXPECT_MEDIA_LOG(DroppedFrame("audio", -10000));
  811. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(10)));
  812. EXPECT_TRUE(ProcessFrames("0K 10K 20K", ""));
  813. EXPECT_TRUE(in_coded_frame_group());
  814. EXPECT_EQ(Milliseconds(-20), timestamp_offset_);
  815. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,10) }");
  816. CheckReadsThenReadStalls(audio_.get(), "0:10P 0:20");
  817. }
  818. TEST_P(FrameProcessorTest, AppendWindowFilterWithInexactPreroll) {
  819. InSequence s;
  820. AddTestTracks(HAS_AUDIO);
  821. if (use_sequence_mode_)
  822. frame_processor_->SetSequenceMode(true);
  823. SetTimestampOffset(Milliseconds(-10));
  824. EXPECT_MEDIA_LOG(DroppedFrame("audio", -10000));
  825. EXPECT_MEDIA_LOG(TruncatedFrame(-250, 9750, "start", 0));
  826. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(20)));
  827. EXPECT_TRUE(ProcessFrames("0K 9.75K 20K", ""));
  828. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,20) }");
  829. CheckReadsThenReadStalls(audio_.get(), "0P 0:9.75 10:20");
  830. }
  831. TEST_P(FrameProcessorTest, AppendWindowFilterWithInexactPreroll_2) {
  832. InSequence s;
  833. AddTestTracks(HAS_AUDIO);
  834. if (use_sequence_mode_)
  835. frame_processor_->SetSequenceMode(true);
  836. SetTimestampOffset(Milliseconds(-10));
  837. EXPECT_MEDIA_LOG(DroppedFrame("audio", -10000));
  838. // Splice trimming checks are done on every audio frame following either a
  839. // discontinuity or the beginning of ProcessFrames(), and are also done on
  840. // audio frames with PTS not directly continuous with the highest frame end
  841. // PTS already processed.
  842. if (use_sequence_mode_)
  843. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(-10)));
  844. else
  845. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(0)));
  846. EXPECT_TRUE(ProcessFrames("0K", ""));
  847. EXPECT_CALL(callbacks_, PossibleDurationIncrease(base::Microseconds(10250)));
  848. EXPECT_TRUE(ProcessFrames("10.25K", ""));
  849. EXPECT_MEDIA_LOG(SkippingSpliceTooLittleOverlap(10000, 250));
  850. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(20)));
  851. EXPECT_TRUE(ProcessFrames("20K", ""));
  852. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,20) }");
  853. CheckReadsThenReadStalls(audio_.get(), "0P 0:10.25 10:20");
  854. }
  855. TEST_P(FrameProcessorTest, AllowNegativeFramePTSAndDTSBeforeOffsetAdjustment) {
  856. InSequence s;
  857. AddTestTracks(HAS_AUDIO);
  858. if (use_sequence_mode_) {
  859. frame_processor_->SetSequenceMode(true);
  860. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(30)));
  861. } else {
  862. EXPECT_MEDIA_LOG(TruncatedFrame(-5000, 5000, "start", 0));
  863. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(25)));
  864. }
  865. EXPECT_TRUE(ProcessFrames("-5K 5K 15K", ""));
  866. if (use_sequence_mode_) {
  867. EXPECT_EQ(Milliseconds(5), timestamp_offset_);
  868. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,30) }");
  869. CheckReadsThenReadStalls(audio_.get(), "0:-5 10:5 20:15");
  870. } else {
  871. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  872. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,25) }");
  873. CheckReadsThenReadStalls(audio_.get(), "0:-5 5 15");
  874. }
  875. }
  876. TEST_P(FrameProcessorTest, PartialAppendWindowFilterNoDiscontinuity) {
  877. // Tests that spurious discontinuity is not introduced by a partially
  878. // trimmed frame.
  879. append_window_start_ = Milliseconds(7);
  880. InSequence s;
  881. AddTestTracks(HAS_AUDIO);
  882. if (use_sequence_mode_)
  883. frame_processor_->SetSequenceMode(true);
  884. EXPECT_MEDIA_LOG(TruncatedFrame(0, 10000, "start", 7000));
  885. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(29)));
  886. EXPECT_TRUE(ProcessFrames("0K 19K", ""));
  887. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  888. CheckExpectedRangesByTimestamp(audio_.get(), "{ [7,29) }");
  889. CheckReadsThenReadStalls(audio_.get(), "7:0 19");
  890. }
  891. TEST_P(FrameProcessorTest,
  892. PartialAppendWindowFilterNoDiscontinuity_DtsAfterPts) {
  893. // Tests that spurious discontinuity is not introduced by a partially trimmed
  894. // frame that originally had DTS > PTS.
  895. InSequence s;
  896. AddTestTracks(HAS_AUDIO);
  897. if (use_sequence_mode_) {
  898. frame_processor_->SetSequenceMode(true);
  899. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(20)));
  900. } else {
  901. EXPECT_MEDIA_LOG(TruncatedFrame(-7000, 3000, "start", 0));
  902. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(13)));
  903. }
  904. // Process a sequence of two audio frames:
  905. // A: PTS -7ms, DTS 10ms, duration 10ms, keyframe
  906. // B: PTS 3ms, DTS 20ms, duration 10ms, keyframe
  907. EXPECT_TRUE(ProcessFrames("-7|10K 3|20K", ""));
  908. if (use_sequence_mode_) {
  909. // Sequence mode detected that frame A needs to be relocated 7ms into the
  910. // future to begin the sequence at time 0. There is no append window
  911. // filtering because the PTS result of the relocation is within the append
  912. // window of [0,+Infinity).
  913. // Frame A is relocated by 7 to PTS 0, DTS 17, duration 10.
  914. // Frame B is relocated by 7 to PTS 10, DTS 27, duration 10.
  915. EXPECT_EQ(Milliseconds(7), timestamp_offset_);
  916. // Start of frame A (0) through end of frame B (10+10).
  917. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,20) }");
  918. // Frame A is now at PTS 0 (originally at PTS -7)
  919. // Frame B is now at PTS 10 (originally at PTS 3)
  920. CheckReadsThenReadStalls(audio_.get(), "0:-7 10:3");
  921. } else {
  922. // Segments mode does not update timestampOffset automatically, so it
  923. // remained 0 and neither frame was relocated by timestampOffset.
  924. // Frame A's start *was* relocated by append window partial audio cropping:
  925. // Append window filtering (done by PTS, regardless of range buffering API)
  926. // did a partial crop of the first 7ms of frame A which was before
  927. // the default append window start time 0, and moved both the PTS and DTS of
  928. // frame A forward by 7 and reduced its duration by 7. Frame B was fully
  929. // inside the append window and remained uncropped and unrelocated.
  930. // Frame A is buffered at PTS -7+7=0, DTS 10+7=17, duration 10-7=3.
  931. // Frame B is buffered at PTS 3, DTS 20, duration 10.
  932. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  933. // Start of frame A (0) through end of frame B (3+10).
  934. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,13) }");
  935. // Frame A is now at PTS 0 (originally at PTS -7)
  936. // Frame B is now at PTS 3 (same as it was originally)
  937. CheckReadsThenReadStalls(audio_.get(), "0:-7 3");
  938. }
  939. }
  940. TEST_P(FrameProcessorTest, PartialAppendWindowFilterNoNewMediaSegment) {
  941. // Tests that a new media segment is not forcibly signalled for audio frame
  942. // partial front trim, to prevent incorrect introduction of a discontinuity
  943. // and potentially a non-keyframe video frame to be processed next after the
  944. // discontinuity.
  945. InSequence s;
  946. AddTestTracks(HAS_AUDIO | HAS_VIDEO);
  947. frame_processor_->SetSequenceMode(use_sequence_mode_);
  948. if (use_sequence_mode_) {
  949. EXPECT_CALL(callbacks_,
  950. OnParseWarning(SourceBufferParseWarning::kMuxedSequenceMode));
  951. EXPECT_MEDIA_LOG(MuxedSequenceModeWarning());
  952. }
  953. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(10)));
  954. EXPECT_TRUE(ProcessFrames("", "0K"));
  955. EXPECT_MEDIA_LOG(TruncatedFrame(-5000, 5000, "start", 0));
  956. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(10)));
  957. EXPECT_TRUE(ProcessFrames("-5K", ""));
  958. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(20)));
  959. EXPECT_TRUE(ProcessFrames("", "10"));
  960. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  961. EXPECT_TRUE(in_coded_frame_group());
  962. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,5) }");
  963. CheckExpectedRangesByTimestamp(video_.get(), "{ [0,20) }");
  964. CheckReadsThenReadStalls(audio_.get(), "0:-5");
  965. CheckReadsThenReadStalls(video_.get(), "0 10");
  966. }
  967. TEST_P(FrameProcessorTest, AudioOnly_SequenceModeContinuityAcrossReset) {
  968. if (!use_sequence_mode_) {
  969. DVLOG(1) << "Skipping segments mode variant; inapplicable to this case.";
  970. return;
  971. }
  972. InSequence s;
  973. AddTestTracks(HAS_AUDIO);
  974. frame_processor_->SetSequenceMode(true);
  975. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(10)));
  976. EXPECT_TRUE(ProcessFrames("0K", ""));
  977. frame_processor_->Reset();
  978. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(20)));
  979. EXPECT_TRUE(ProcessFrames("100K", ""));
  980. EXPECT_EQ(Milliseconds(-90), timestamp_offset_);
  981. EXPECT_TRUE(in_coded_frame_group());
  982. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,20) }");
  983. CheckReadsThenReadStalls(audio_.get(), "0 10:100");
  984. }
  985. TEST_P(FrameProcessorTest, PartialAppendWindowZeroDurationPreroll) {
  986. InSequence s;
  987. AddTestTracks(HAS_AUDIO);
  988. frame_processor_->SetSequenceMode(use_sequence_mode_);
  989. append_window_start_ = Milliseconds(5);
  990. EXPECT_MEDIA_LOG(DroppedFrame("audio", use_sequence_mode_ ? 0 : 4000));
  991. // Append a 0 duration frame that falls just before the append window.
  992. frame_duration_ = Milliseconds(0);
  993. EXPECT_FALSE(in_coded_frame_group());
  994. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(0)));
  995. EXPECT_TRUE(ProcessFrames("4K", ""));
  996. // Verify buffer is not part of ranges. It should be silently saved for
  997. // preroll for future append.
  998. CheckExpectedRangesByTimestamp(audio_.get(), "{ }");
  999. CheckReadsThenReadStalls(audio_.get(), "");
  1000. EXPECT_FALSE(in_coded_frame_group());
  1001. // Abort the reads from last stall. We don't want those reads to "complete"
  1002. // when we append below. We will initiate new reads to confirm the buffer
  1003. // looks as we expect.
  1004. SeekStream(audio_.get(), Milliseconds(0));
  1005. if (use_sequence_mode_) {
  1006. EXPECT_MEDIA_LOG(TruncatedFrame(0, 10000, "start", 5000));
  1007. } else {
  1008. EXPECT_MEDIA_LOG(TruncatedFrame(4000, 14000, "start", 5000));
  1009. }
  1010. // Append a frame with 10ms duration, with 9ms falling after the window start.
  1011. EXPECT_CALL(callbacks_, PossibleDurationIncrease(
  1012. Milliseconds(use_sequence_mode_ ? 10 : 14)));
  1013. frame_duration_ = Milliseconds(10);
  1014. EXPECT_TRUE(ProcessFrames("4K", ""));
  1015. EXPECT_TRUE(in_coded_frame_group());
  1016. // Verify range updated to reflect last append was processed and trimmed, and
  1017. // also that zero duration buffer was saved and attached as preroll.
  1018. if (use_sequence_mode_) {
  1019. // For sequence mode, append window trimming is applied after the append
  1020. // is adjusted for timestampOffset. Basically, everything gets rebased to 0
  1021. // and trimming then removes 5 seconds from the front.
  1022. CheckExpectedRangesByTimestamp(audio_.get(), "{ [5,10) }");
  1023. CheckReadsThenReadStalls(audio_.get(), "5:4P 5:4");
  1024. } else { // segments mode
  1025. CheckExpectedRangesByTimestamp(audio_.get(), "{ [5,14) }");
  1026. CheckReadsThenReadStalls(audio_.get(), "5:4P 5:4");
  1027. }
  1028. // Verify the preroll buffer still has zero duration.
  1029. StreamParserBuffer* last_read_parser_buffer =
  1030. static_cast<StreamParserBuffer*>(last_read_buffer_.get());
  1031. ASSERT_EQ(Milliseconds(0),
  1032. last_read_parser_buffer->preroll_buffer()->duration());
  1033. }
  1034. TEST_P(FrameProcessorTest,
  1035. OOOKeyframePrecededByDependantNonKeyframeShouldWarn) {
  1036. InSequence s;
  1037. AddTestTracks(HAS_VIDEO);
  1038. frame_processor_->SetSequenceMode(use_sequence_mode_);
  1039. if (use_sequence_mode_) {
  1040. // Allow room in the timeline for the last video append (40|70, below) in
  1041. // this test to remain within default append window [0, +Infinity]. Moving
  1042. // the sequence mode appends to begin at time 50ms, the same time as the
  1043. // first append, below, also results in identical expectation checks for
  1044. // buffered ranges and buffer reads for both segments and sequence modes.
  1045. SetTimestampOffset(Milliseconds(50));
  1046. }
  1047. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(70)));
  1048. EXPECT_TRUE(ProcessFrames("", "50K 60"));
  1049. CheckExpectedRangesByTimestamp(video_.get(), "{ [50,70) }");
  1050. EXPECT_CALL(callbacks_,
  1051. OnParseWarning(
  1052. SourceBufferParseWarning::kKeyframeTimeGreaterThanDependant));
  1053. EXPECT_MEDIA_LOG(KeyframeTimeGreaterThanDependant("0.05", "0.04"));
  1054. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(70)));
  1055. EXPECT_TRUE(ProcessFrames("", "40|70")); // PTS=40, DTS=70
  1056. // This reflects the expectation that PTS start is not "pulled backward" for
  1057. // the new frame at PTS=40 because current spec doesn't support SAP Type 2; it
  1058. // has no steps in the coded frame processing algorithm that would do that
  1059. // "pulling backward". See https://github.com/w3c/media-source/issues/187.
  1060. CheckExpectedRangesByTimestamp(video_.get(), "{ [50,70) }");
  1061. SeekStream(video_.get(), Milliseconds(0));
  1062. CheckReadsThenReadStalls(video_.get(), "50 60 40");
  1063. }
  1064. TEST_P(FrameProcessorTest, OOOKeyframePts_1) {
  1065. InSequence s;
  1066. AddTestTracks(HAS_AUDIO);
  1067. frame_processor_->SetSequenceMode(use_sequence_mode_);
  1068. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(1010)));
  1069. // Note that the following does not contain a DTS continuity, but *does*
  1070. // contain a PTS discontinuity (keyframe at 0.1s after keyframe at 1s).
  1071. EXPECT_TRUE(ProcessFrames("0K 1000|10K 100|20K", ""));
  1072. // Force sequence mode to place the next frames where segments mode would put
  1073. // them, to simplify this test case.
  1074. if (use_sequence_mode_)
  1075. SetTimestampOffset(Milliseconds(500));
  1076. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(510)));
  1077. EXPECT_TRUE(ProcessFrames("500|100K", ""));
  1078. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1079. // Note that the PTS discontinuity (100ms) in the first ProcessFrames() call,
  1080. // above, overlaps the previously buffered range [0,1010), so the frame at
  1081. // 100ms is processed with an adjusted coded frame group start to be 0.001ms,
  1082. // which is just after the highest timestamp before it in the overlapped
  1083. // range. This enables it to be continuous with the frame before it. The
  1084. // remainder of the overlapped range (the buffer at [1000,1010)) is adjusted
  1085. // to have a range start time at the split point (110), and is within fudge
  1086. // room and merged into [0,110). The same happens with the buffer appended
  1087. // [500,510).
  1088. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,1010) }");
  1089. CheckReadsThenReadStalls(audio_.get(), "0 100 500 1000");
  1090. }
  1091. TEST_P(FrameProcessorTest, OOOKeyframePts_2) {
  1092. InSequence s;
  1093. AddTestTracks(HAS_AUDIO);
  1094. frame_processor_->SetSequenceMode(use_sequence_mode_);
  1095. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(1010)));
  1096. EXPECT_TRUE(ProcessFrames("0K 1000|10K", ""));
  1097. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(1010)));
  1098. EXPECT_TRUE(ProcessFrames("100|20K", ""));
  1099. // Note that the PTS discontinuity (100ms) in the first ProcessFrames() call,
  1100. // above, overlaps the previously buffered range [0,1010), so the frame at
  1101. // 100ms is processed with an adjusted coded frame group start to be 0.001ms,
  1102. // which is just after the highest timestamp before it in the overlapped
  1103. // range. This enables it to be continuous with the frame before it. The
  1104. // remainder of the overlapped range (the buffer at [1000,1010)) is adjusted
  1105. // to have a range start time at the split point (110), and is within fudge
  1106. // room and merged into [0,110).
  1107. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,1010) }");
  1108. CheckReadsThenReadStalls(audio_.get(), "0 100 1000");
  1109. }
  1110. TEST_P(FrameProcessorTest, AudioNonKeyframeChangedToKeyframe) {
  1111. // Verifies that an audio non-keyframe is changed to a keyframe with a media
  1112. // log warning. An exact overlap append of the preceding keyframe is also done
  1113. // to ensure that the (original non-keyframe) survives (because it was changed
  1114. // to a keyframe, so no longer depends on the original preceding keyframe).
  1115. // The sequence mode test version uses SetTimestampOffset to make it behave
  1116. // like segments mode to simplify the tests.
  1117. // Note, see the NonkeyframeAudioBuffering tests to verify buffering of audio
  1118. // nonkeyframes for codec(s) that use nonkeyframes.
  1119. InSequence s;
  1120. AddTestTracks(HAS_AUDIO);
  1121. frame_processor_->SetSequenceMode(use_sequence_mode_);
  1122. EXPECT_MEDIA_LOG(AudioNonKeyframe(10000, 10000));
  1123. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(30)));
  1124. EXPECT_TRUE(ProcessFrames("0K 10 20K", ""));
  1125. if (use_sequence_mode_)
  1126. SetTimestampOffset(Milliseconds(0));
  1127. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(10)));
  1128. EXPECT_TRUE(ProcessFrames("0K", ""));
  1129. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,30) }");
  1130. SeekStream(audio_.get(), Milliseconds(0));
  1131. CheckReadsThenReadStalls(audio_.get(), "0 10 20");
  1132. }
  1133. TEST_P(FrameProcessorTest, TimestampOffsetNegativeDts) {
  1134. // Shift a GOP earlier using timestampOffset such that the GOP
  1135. // starts with negative DTS, but PTS 0.
  1136. InSequence s;
  1137. AddTestTracks(HAS_VIDEO);
  1138. frame_processor_->SetSequenceMode(use_sequence_mode_);
  1139. if (!use_sequence_mode_) {
  1140. // Simulate the offset that sequence mode would apply, to make the results
  1141. // the same regardless of sequence vs segments mode.
  1142. SetTimestampOffset(Milliseconds(-100));
  1143. }
  1144. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(40)));
  1145. EXPECT_TRUE(ProcessFrames("", "100|70K 130|80"));
  1146. EXPECT_EQ(Milliseconds(-100), timestamp_offset_);
  1147. CheckExpectedRangesByTimestamp(video_.get(), "{ [0,40) }");
  1148. SeekStream(video_.get(), Milliseconds(0));
  1149. CheckReadsThenReadStalls(video_.get(), "0:100 30:130");
  1150. }
  1151. TEST_P(FrameProcessorTest, LargeTimestampOffsetJumpForward) {
  1152. // Verifies that jumps forward in buffers emitted from the coded frame
  1153. // processing algorithm can create discontinuous buffered ranges if those
  1154. // jumps are large enough, in both kinds of AppendMode.
  1155. InSequence s;
  1156. AddTestTracks(HAS_AUDIO);
  1157. frame_processor_->SetSequenceMode(use_sequence_mode_);
  1158. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(10)));
  1159. EXPECT_TRUE(ProcessFrames("0K", ""));
  1160. SetTimestampOffset(Milliseconds(5000));
  1161. // Along with the new timestampOffset set above, this should cause a large
  1162. // jump forward in both PTS and DTS for both sequence and segments append
  1163. // modes.
  1164. if (use_sequence_mode_) {
  1165. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(5010)));
  1166. } else {
  1167. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(10010)));
  1168. }
  1169. EXPECT_TRUE(ProcessFrames("5000|100K", ""));
  1170. if (use_sequence_mode_) {
  1171. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1172. } else {
  1173. EXPECT_EQ(Milliseconds(5000), timestamp_offset_);
  1174. }
  1175. if (use_sequence_mode_) {
  1176. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,10) [5000,5010) }");
  1177. CheckReadsThenReadStalls(audio_.get(), "0");
  1178. SeekStream(audio_.get(), Milliseconds(5000));
  1179. CheckReadsThenReadStalls(audio_.get(), "5000");
  1180. } else {
  1181. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,10) [10000,10010) }");
  1182. CheckReadsThenReadStalls(audio_.get(), "0");
  1183. SeekStream(audio_.get(), Milliseconds(10000));
  1184. CheckReadsThenReadStalls(audio_.get(), "10000:5000");
  1185. }
  1186. }
  1187. TEST_P(FrameProcessorTest, ContinuousDts_SapType2_and_PtsJumpForward) {
  1188. InSequence s;
  1189. AddTestTracks(HAS_VIDEO | OBSERVE_APPENDS_AND_GROUP_STARTS);
  1190. frame_processor_->SetSequenceMode(use_sequence_mode_);
  1191. // Make the sequence mode buffering appear just like segments mode to simplify
  1192. // this test case.
  1193. if (use_sequence_mode_)
  1194. SetTimestampOffset(Milliseconds(1060));
  1195. // Note that the PTS of GOP non-keyframes earlier than the keyframe doesn't
  1196. // modify the GOP start of the buffered range here. This may change if we
  1197. // decide to improve spec for SAP Type 2 GOPs that begin a coded frame group.
  1198. EXPECT_CALL(callbacks_, OnGroupStart(DemuxerStream::VIDEO, DecodeTimestamp(),
  1199. Milliseconds(1060)));
  1200. EXPECT_CALL(callbacks_,
  1201. OnParseWarning(
  1202. SourceBufferParseWarning::kKeyframeTimeGreaterThanDependant));
  1203. EXPECT_MEDIA_LOG(KeyframeTimeGreaterThanDependant("1.06", "1"));
  1204. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1205. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1206. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(1070)));
  1207. EXPECT_TRUE(ProcessFrames(
  1208. "", "1060|0K 1000|10 1050|20 1010|30 1040|40 1020|50 1030|60"));
  1209. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1210. CheckExpectedRangesByTimestamp(video_.get(), "{ [1060,1070) }");
  1211. // Process just the keyframe of the next SAP Type 2 GOP in decode continuity
  1212. // with the previous one.
  1213. // Note that this second GOP is buffered continuous with the first because
  1214. // there is no decode discontinuity detected. This results in inclusion of
  1215. // the significant PTS jump forward in the same continuous range.
  1216. EXPECT_CALL(
  1217. callbacks_,
  1218. OnGroupStart(DemuxerStream::VIDEO,
  1219. DecodeTimestamp::FromPresentationTime(Milliseconds(60)),
  1220. Milliseconds(1070)));
  1221. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1222. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(1140)));
  1223. EXPECT_TRUE(ProcessFrames("", "1130|70K"));
  1224. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1225. CheckExpectedRangesByTimestamp(video_.get(), "{ [1060,1140) }");
  1226. // Process the remainder of the second GOP.
  1227. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1228. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(1140)));
  1229. EXPECT_TRUE(
  1230. ProcessFrames("", "1070|80 1120|90 1080|100 1110|110 1090|120 1100|130"));
  1231. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1232. CheckExpectedRangesByTimestamp(video_.get(), "{ [1060,1140) }");
  1233. // [1060,1140) should demux continuously without read stall in the middle.
  1234. SeekStream(video_.get(), Milliseconds(1060));
  1235. CheckReadsThenReadStalls(
  1236. video_.get(),
  1237. "1060 1000 1050 1010 1040 1020 1030 1130 1070 1120 1080 1110 1090 1100");
  1238. // Verify that seek and read of the second GOP is correct.
  1239. SeekStream(video_.get(), Milliseconds(1130));
  1240. CheckReadsThenReadStalls(video_.get(), "1130 1070 1120 1080 1110 1090 1100");
  1241. }
  1242. TEST_P(FrameProcessorTest, ContinuousDts_NewGopEndOverlapsLastGop_1) {
  1243. // API user might craft a continuous-in-DTS-with-previous-append GOP that has
  1244. // PTS interval overlapping the previous append.
  1245. // Tests SAP-Type-1 GOPs, where newly appended GOP overlaps a nonkeyframe of
  1246. // the last GOP appended.
  1247. InSequence s;
  1248. AddTestTracks(HAS_VIDEO | OBSERVE_APPENDS_AND_GROUP_STARTS);
  1249. frame_processor_->SetSequenceMode(use_sequence_mode_);
  1250. // Make the sequence mode buffering appear just like segments mode to simplify
  1251. // this test case.
  1252. if (use_sequence_mode_)
  1253. SetTimestampOffset(Milliseconds(100));
  1254. EXPECT_CALL(callbacks_, OnGroupStart(DemuxerStream::VIDEO, DecodeTimestamp(),
  1255. Milliseconds(100)));
  1256. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1257. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(140)));
  1258. EXPECT_TRUE(ProcessFrames("", "100|0K 110|10 120|20 130|30"));
  1259. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1260. EXPECT_CALL(
  1261. callbacks_,
  1262. OnGroupStart(DemuxerStream::VIDEO,
  1263. DecodeTimestamp::FromPresentationTime(Milliseconds(30)),
  1264. Milliseconds(125)));
  1265. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1266. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(165)));
  1267. EXPECT_TRUE(ProcessFrames("", "125|40K 135|50 145|60 155|70"));
  1268. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1269. CheckExpectedRangesByTimestamp(video_.get(), "{ [100,165) }");
  1270. CheckReadsThenReadStalls(video_.get(), "100 110 120 125 135 145 155");
  1271. }
  1272. TEST_P(FrameProcessorTest, ContinuousDts_NewGopEndOverlapsLastGop_2) {
  1273. // API user might craft a continuous-in-DTS-with-previous-append GOP that has
  1274. // PTS interval overlapping the previous append.
  1275. // Tests SAP-Type 1 GOPs, where newly appended GOP overlaps the keyframe of
  1276. // the last GOP appended.
  1277. InSequence s;
  1278. AddTestTracks(HAS_VIDEO | OBSERVE_APPENDS_AND_GROUP_STARTS);
  1279. frame_processor_->SetSequenceMode(use_sequence_mode_);
  1280. // Make the sequence mode buffering appear just like segments mode to simplify
  1281. // this test case.
  1282. if (use_sequence_mode_)
  1283. SetTimestampOffset(Milliseconds(100));
  1284. EXPECT_CALL(callbacks_, OnGroupStart(DemuxerStream::VIDEO, DecodeTimestamp(),
  1285. Milliseconds(100)));
  1286. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1287. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(140)));
  1288. EXPECT_TRUE(ProcessFrames("", "100|0K 110|10 120|20K 130|30"));
  1289. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1290. EXPECT_CALL(
  1291. callbacks_,
  1292. OnGroupStart(DemuxerStream::VIDEO,
  1293. DecodeTimestamp::FromPresentationTime(Milliseconds(30)),
  1294. Milliseconds(115)));
  1295. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1296. // TODO(wolenetz): Duration shouldn't be allowed to possibly increase to 140ms
  1297. // here. See https://crbug.com/763620.
  1298. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(140)));
  1299. EXPECT_TRUE(ProcessFrames("", "115|40K 125|50"));
  1300. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1301. CheckExpectedRangesByTimestamp(video_.get(), "{ [100,135) }");
  1302. CheckReadsThenReadStalls(video_.get(), "100 110 115 125");
  1303. }
  1304. TEST_P(FrameProcessorTest, ContinuousDts_NewSap2GopEndOverlapsLastGop_1) {
  1305. // API user might craft a continuous-in-DTS-with-previous-append GOP that has
  1306. // PTS interval overlapping the previous append, using SAP Type 2 GOPs.
  1307. // Tests SAP-Type 2 GOPs, where newly appended GOP overlaps nonkeyframes of
  1308. // the last GOP appended.
  1309. InSequence s;
  1310. AddTestTracks(HAS_VIDEO | OBSERVE_APPENDS_AND_GROUP_STARTS);
  1311. frame_processor_->SetSequenceMode(use_sequence_mode_);
  1312. // Make the sequence mode buffering appear just like segments mode to simplify
  1313. // this test case.
  1314. if (use_sequence_mode_)
  1315. SetTimestampOffset(Milliseconds(120));
  1316. EXPECT_CALL(callbacks_, OnGroupStart(DemuxerStream::VIDEO, DecodeTimestamp(),
  1317. Milliseconds(120)));
  1318. EXPECT_CALL(callbacks_,
  1319. OnParseWarning(
  1320. SourceBufferParseWarning::kKeyframeTimeGreaterThanDependant));
  1321. EXPECT_MEDIA_LOG(KeyframeTimeGreaterThanDependant("0.12", "0.1"));
  1322. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1323. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1324. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(140)));
  1325. EXPECT_TRUE(ProcessFrames("", "120|0K 100|10 130|20 110|30"));
  1326. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1327. // Note, we *don't* expect another OnGroupStart during the next ProcessFrames,
  1328. // since the next GOP's keyframe PTS is after the first GOP and close enough
  1329. // to be assured adjacent.
  1330. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1331. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1332. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(165)));
  1333. EXPECT_TRUE(ProcessFrames("", "145|40K 125|50 155|60 135|70"));
  1334. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1335. CheckExpectedRangesByTimestamp(video_.get(), "{ [120,165) }");
  1336. // [120,165) should demux continuously without read stall in the middle.
  1337. CheckReadsThenReadStalls(video_.get(), "120 100 130 110 145 125 155 135");
  1338. // Verify that seek and read of the second GOP is correct.
  1339. SeekStream(video_.get(), Milliseconds(145));
  1340. CheckReadsThenReadStalls(video_.get(), "145 125 155 135");
  1341. }
  1342. TEST_P(FrameProcessorTest, ContinuousDts_NewSap2GopEndOverlapsLastGop_2) {
  1343. // API user might craft a continuous-in-DTS-with-previous-append GOP that has
  1344. // PTS interval overlapping the previous append, using SAP Type 2 GOPs.
  1345. // Tests SAP-Type 2 GOPs, where newly appended GOP overlaps the keyframe of
  1346. // last GOP appended.
  1347. InSequence s;
  1348. AddTestTracks(HAS_VIDEO | OBSERVE_APPENDS_AND_GROUP_STARTS);
  1349. frame_processor_->SetSequenceMode(use_sequence_mode_);
  1350. // Make the sequence mode buffering appear just like segments mode to simplify
  1351. // this test case.
  1352. if (use_sequence_mode_)
  1353. SetTimestampOffset(Milliseconds(120));
  1354. EXPECT_CALL(callbacks_, OnGroupStart(DemuxerStream::VIDEO, DecodeTimestamp(),
  1355. Milliseconds(120)));
  1356. EXPECT_CALL(callbacks_,
  1357. OnParseWarning(
  1358. SourceBufferParseWarning::kKeyframeTimeGreaterThanDependant));
  1359. EXPECT_MEDIA_LOG(KeyframeTimeGreaterThanDependant("0.12", "0.1"));
  1360. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1361. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1362. // There is a second GOP that is SAP-Type-2 within this first ProcessFrames,
  1363. // with PTS jumping forward far enough to trigger group start signalling and a
  1364. // flush.
  1365. EXPECT_CALL(
  1366. callbacks_,
  1367. OnGroupStart(DemuxerStream::VIDEO,
  1368. DecodeTimestamp::FromPresentationTime(Milliseconds(30)),
  1369. Milliseconds(140)));
  1370. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1371. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(180)));
  1372. EXPECT_TRUE(ProcessFrames(
  1373. "", "120|0K 100|10 130|20 110|30 160|40K 140|50 170|60 150|70"));
  1374. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1375. EXPECT_CALL(
  1376. callbacks_,
  1377. OnGroupStart(DemuxerStream::VIDEO,
  1378. DecodeTimestamp::FromPresentationTime(Milliseconds(70)),
  1379. Milliseconds(155)));
  1380. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1381. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1382. // TODO(wolenetz): Duration shouldn't be allowed to possibly increase to 180ms
  1383. // here. See https://crbug.com/763620.
  1384. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(180)));
  1385. EXPECT_TRUE(ProcessFrames("", "155|80K 145|90"));
  1386. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1387. CheckExpectedRangesByTimestamp(video_.get(), "{ [120,165) }");
  1388. // [120,165) should demux continuously without read stall in the middle.
  1389. CheckReadsThenReadStalls(video_.get(), "120 100 130 110 155 145");
  1390. // Verify seek and read of the second GOP is correct.
  1391. SeekStream(video_.get(), Milliseconds(155));
  1392. CheckReadsThenReadStalls(video_.get(), "155 145");
  1393. }
  1394. TEST_P(FrameProcessorTest,
  1395. ContinuousDts_NewSap2GopEndOverlapsLastGop_3_GopByGop) {
  1396. // API user might craft a continuous-in-DTS-with-previous-append GOP that has
  1397. // PTS interval overlapping the previous append, using SAP Type 2 GOPs. Tests
  1398. // SAP-Type 2 GOPs, where newly appended GOP overlaps enough nonkeyframes of
  1399. // the previous GOP such that dropped decode dependencies might cause problems
  1400. // if the first nonkeyframe with PTS prior to the GOP's keyframe PTS is
  1401. // flushed at the same time as its keyframe, but the second GOP's keyframe PTS
  1402. // is close enough to the end of the first GOP's presentation interval to not
  1403. // signal a new coded frame group start.
  1404. InSequence s;
  1405. AddTestTracks(HAS_VIDEO | OBSERVE_APPENDS_AND_GROUP_STARTS);
  1406. frame_processor_->SetSequenceMode(use_sequence_mode_);
  1407. // Make the sequence mode buffering appear just like segments mode to simplify
  1408. // this test case.
  1409. if (use_sequence_mode_)
  1410. SetTimestampOffset(Milliseconds(500));
  1411. EXPECT_CALL(callbacks_, OnGroupStart(DemuxerStream::VIDEO, DecodeTimestamp(),
  1412. Milliseconds(500)));
  1413. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1414. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(530)));
  1415. EXPECT_TRUE(ProcessFrames("", "500|0K 520|10 510|20"));
  1416. CheckExpectedRangesByTimestamp(video_.get(), "{ [500,530) }");
  1417. EXPECT_CALL(callbacks_,
  1418. OnParseWarning(
  1419. SourceBufferParseWarning::kKeyframeTimeGreaterThanDependant));
  1420. EXPECT_MEDIA_LOG(KeyframeTimeGreaterThanDependant("0.54", "0.52"));
  1421. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1422. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1423. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(550)));
  1424. EXPECT_TRUE(ProcessFrames("", "540|30K 520|40 530|50"));
  1425. CheckExpectedRangesByTimestamp(video_.get(), "{ [500,550) }");
  1426. SeekStream(video_.get(), Milliseconds(500));
  1427. CheckReadsThenReadStalls(video_.get(), "500 520 510 540 520 530");
  1428. }
  1429. TEST_P(FrameProcessorTest,
  1430. ContinuousDts_NewSap2GopEndOverlapsLastGop_3_FrameByFrame) {
  1431. // Tests that the buffered range results match the previous GopByGop test if
  1432. // each frame of the second GOP is explicitly appended by the app
  1433. // one-at-a-time.
  1434. InSequence s;
  1435. AddTestTracks(HAS_VIDEO | OBSERVE_APPENDS_AND_GROUP_STARTS);
  1436. frame_processor_->SetSequenceMode(use_sequence_mode_);
  1437. // Make the sequence mode buffering appear just like segments mode to simplify
  1438. // this test case.
  1439. if (use_sequence_mode_)
  1440. SetTimestampOffset(Milliseconds(500));
  1441. EXPECT_CALL(callbacks_, OnGroupStart(DemuxerStream::VIDEO, DecodeTimestamp(),
  1442. Milliseconds(500)));
  1443. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1444. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(530)));
  1445. EXPECT_TRUE(ProcessFrames("", "500|0K 520|10 510|20"));
  1446. CheckExpectedRangesByTimestamp(video_.get(), "{ [500,530) }");
  1447. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1448. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(550)));
  1449. EXPECT_TRUE(ProcessFrames("", "540|30K"));
  1450. EXPECT_CALL(callbacks_,
  1451. OnParseWarning(
  1452. SourceBufferParseWarning::kKeyframeTimeGreaterThanDependant));
  1453. EXPECT_MEDIA_LOG(KeyframeTimeGreaterThanDependant("0.54", "0.52"));
  1454. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1455. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(550)));
  1456. EXPECT_TRUE(ProcessFrames("", "520|40"));
  1457. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1458. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(550)));
  1459. EXPECT_TRUE(ProcessFrames("", "530|50"));
  1460. CheckExpectedRangesByTimestamp(video_.get(), "{ [500,550) }");
  1461. SeekStream(video_.get(), Milliseconds(500));
  1462. CheckReadsThenReadStalls(video_.get(), "500 520 510 540 520 530");
  1463. }
  1464. TEST_P(FrameProcessorTest,
  1465. ContinuousDts_NewSap2GopEndOverlapsLastGop_4_GopByGop) {
  1466. // API user might craft a continuous-in-DTS-with-previous-append GOP that has
  1467. // PTS interval overlapping the previous append, using SAP Type 2 GOPs. Tests
  1468. // SAP-Type 2 GOPs, where newly appended GOP overlaps enough nonkeyframes of
  1469. // the previous GOP such that dropped decode dependencies might cause problems
  1470. // if the first nonkeyframe with PTS prior to the GOP's keyframe PTS is
  1471. // flushed at the same time as its keyframe.
  1472. InSequence s;
  1473. AddTestTracks(HAS_VIDEO | OBSERVE_APPENDS_AND_GROUP_STARTS);
  1474. frame_processor_->SetSequenceMode(use_sequence_mode_);
  1475. // Make the sequence mode buffering appear just like segments mode to simplify
  1476. // this test case.
  1477. if (use_sequence_mode_)
  1478. SetTimestampOffset(Milliseconds(500));
  1479. EXPECT_CALL(callbacks_, OnGroupStart(DemuxerStream::VIDEO, DecodeTimestamp(),
  1480. Milliseconds(500)));
  1481. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1482. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(530)));
  1483. EXPECT_TRUE(ProcessFrames("", "500|0K 520|10 510|20"));
  1484. CheckExpectedRangesByTimestamp(video_.get(), "{ [500,530) }");
  1485. EXPECT_CALL(
  1486. callbacks_,
  1487. OnGroupStart(DemuxerStream::VIDEO,
  1488. DecodeTimestamp::FromPresentationTime(Milliseconds(20)),
  1489. Milliseconds(530)));
  1490. EXPECT_CALL(callbacks_,
  1491. OnParseWarning(
  1492. SourceBufferParseWarning::kKeyframeTimeGreaterThanDependant));
  1493. EXPECT_MEDIA_LOG(KeyframeTimeGreaterThanDependant("0.55", "0.52"));
  1494. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1495. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1496. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(560)));
  1497. EXPECT_TRUE(ProcessFrames("", "550|30K 520|40 530|50 540|60"));
  1498. CheckExpectedRangesByTimestamp(video_.get(), "{ [500,560) }");
  1499. SeekStream(video_.get(), Milliseconds(500));
  1500. CheckReadsThenReadStalls(video_.get(), "500 520 510 550 520 530 540");
  1501. }
  1502. TEST_P(FrameProcessorTest,
  1503. ContinuousDts_NewSap2GopEndOverlapsLastGop_4_FrameByFrame) {
  1504. // Tests that the buffered range results match the previous GopByGop test if
  1505. // each frame of the second GOP is explicitly appended by the app
  1506. // one-at-a-time.
  1507. InSequence s;
  1508. AddTestTracks(HAS_VIDEO | OBSERVE_APPENDS_AND_GROUP_STARTS);
  1509. frame_processor_->SetSequenceMode(use_sequence_mode_);
  1510. // Make the sequence mode buffering appear just like segments mode to simplify
  1511. // this test case.
  1512. if (use_sequence_mode_)
  1513. SetTimestampOffset(Milliseconds(500));
  1514. EXPECT_CALL(callbacks_, OnGroupStart(DemuxerStream::VIDEO, DecodeTimestamp(),
  1515. Milliseconds(500)));
  1516. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1517. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(530)));
  1518. EXPECT_TRUE(ProcessFrames("", "500|0K 520|10 510|20"));
  1519. CheckExpectedRangesByTimestamp(video_.get(), "{ [500,530) }");
  1520. EXPECT_CALL(
  1521. callbacks_,
  1522. OnGroupStart(DemuxerStream::VIDEO,
  1523. DecodeTimestamp::FromPresentationTime(Milliseconds(20)),
  1524. Milliseconds(530)));
  1525. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1526. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(560)));
  1527. EXPECT_TRUE(ProcessFrames("", "550|30K"));
  1528. EXPECT_CALL(callbacks_,
  1529. OnParseWarning(
  1530. SourceBufferParseWarning::kKeyframeTimeGreaterThanDependant));
  1531. EXPECT_MEDIA_LOG(KeyframeTimeGreaterThanDependant("0.55", "0.52"));
  1532. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1533. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(560)));
  1534. EXPECT_TRUE(ProcessFrames("", "520|40"));
  1535. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1536. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(560)));
  1537. EXPECT_TRUE(ProcessFrames("", "530|50"));
  1538. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1539. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(560)));
  1540. EXPECT_TRUE(ProcessFrames("", "540|60"));
  1541. CheckExpectedRangesByTimestamp(video_.get(), "{ [500,560) }");
  1542. SeekStream(video_.get(), Milliseconds(500));
  1543. CheckReadsThenReadStalls(video_.get(), "500 520 510 550 520 530 540");
  1544. }
  1545. TEST_P(FrameProcessorTest, ContinuousDts_GopKeyframePtsOrder_2_1_3) {
  1546. // White-box test, demonstrating expected behavior for a specially crafted
  1547. // sequence that "should" be unusual, but gracefully handled:
  1548. // SAP-Type 1 GOPs for simplicity of test. First appended GOP is highest in
  1549. // timeline. Second appended GOP is earliest in timeline. Third appended GOP
  1550. // is continuous in time with highest end time of first appended GOP. The
  1551. // result should be a single continuous range containing just the second and
  1552. // third appended GOPs (since the first-appended GOP was overlap-removed from
  1553. // the timeline due to being in the gap between the second and third appended
  1554. // GOPs). Note that MseTrackBuffer::ResetHighestPresentationTimestamp() done
  1555. // at the beginning of the second appended GOP is the key to gracefully
  1556. // handling the third appended GOP.
  1557. InSequence s;
  1558. AddTestTracks(HAS_VIDEO | OBSERVE_APPENDS_AND_GROUP_STARTS);
  1559. frame_processor_->SetSequenceMode(use_sequence_mode_);
  1560. // Make the sequence mode buffering appear just like segments mode to simplify
  1561. // this test case.
  1562. if (use_sequence_mode_)
  1563. SetTimestampOffset(Milliseconds(200));
  1564. EXPECT_CALL(callbacks_, OnGroupStart(DemuxerStream::VIDEO, DecodeTimestamp(),
  1565. Milliseconds(200)));
  1566. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1567. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(240)));
  1568. EXPECT_TRUE(ProcessFrames("", "200|0K 210|10 220|20 230|30"));
  1569. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1570. CheckExpectedRangesByTimestamp(video_.get(), "{ [200,240) }");
  1571. EXPECT_CALL(
  1572. callbacks_,
  1573. OnGroupStart(DemuxerStream::VIDEO,
  1574. DecodeTimestamp::FromPresentationTime(Milliseconds(30)),
  1575. Milliseconds(100)));
  1576. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1577. // TODO(wolenetz): Duration shouldn't be allowed to possibly increase to 240ms
  1578. // here. See https://crbug.com/763620.
  1579. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(240)));
  1580. EXPECT_TRUE(ProcessFrames("", "100|40K 110|50 120|60 130|70"));
  1581. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1582. CheckExpectedRangesByTimestamp(video_.get(), "{ [100,140) [200,240) }");
  1583. EXPECT_CALL(
  1584. callbacks_,
  1585. OnGroupStart(DemuxerStream::VIDEO,
  1586. DecodeTimestamp::FromPresentationTime(Milliseconds(70)),
  1587. Milliseconds(140)));
  1588. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1589. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(260)));
  1590. EXPECT_TRUE(ProcessFrames("", "240|80K 250|90"));
  1591. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1592. CheckExpectedRangesByTimestamp(video_.get(), "{ [100,260) }");
  1593. SeekStream(video_.get(), Milliseconds(100));
  1594. CheckReadsThenReadStalls(video_.get(), "100 110 120 130 240 250");
  1595. }
  1596. TEST_P(FrameProcessorTest, ContinuousPts_DiscontinuousDts_AcrossGops) {
  1597. // GOPs which overlap in DTS, but are continuous in PTS should be buffered
  1598. // correctly. In particular, monotonic increase of DTS in continuous-in-PTS
  1599. // append sequences is not required across GOPs (just within GOPs).
  1600. InSequence s;
  1601. AddTestTracks(HAS_VIDEO | OBSERVE_APPENDS_AND_GROUP_STARTS);
  1602. frame_processor_->SetSequenceMode(use_sequence_mode_);
  1603. // Make the sequence mode buffering appear just like segments mode to simplify
  1604. // this test case.
  1605. if (use_sequence_mode_)
  1606. SetTimestampOffset(Milliseconds(200));
  1607. EXPECT_CALL(
  1608. callbacks_,
  1609. OnGroupStart(DemuxerStream::VIDEO,
  1610. DecodeTimestamp::FromPresentationTime(Milliseconds(200)),
  1611. Milliseconds(200)));
  1612. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1613. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(240)));
  1614. EXPECT_TRUE(ProcessFrames("", "200K 210 220 230"));
  1615. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1616. CheckExpectedRangesByTimestamp(video_.get(), "{ [200,240) }");
  1617. EXPECT_CALL(
  1618. callbacks_,
  1619. OnGroupStart(DemuxerStream::VIDEO,
  1620. DecodeTimestamp::FromPresentationTime(Milliseconds(225)),
  1621. Milliseconds(240)));
  1622. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::VIDEO, _));
  1623. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(280)));
  1624. // Append a second GOP whose first DTS is below the last DTS of the first GOP,
  1625. // but whose PTS interval is continuous with the end of the first GOP.
  1626. EXPECT_TRUE(ProcessFrames("", "240|225K 250|235 260|245 270|255"));
  1627. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1628. SeekStream(video_.get(), Milliseconds(200));
  1629. CheckExpectedRangesByTimestamp(video_.get(), "{ [200,280) }");
  1630. CheckReadsThenReadStalls(video_.get(), "200 210 220 230 240 250 260 270");
  1631. }
  1632. TEST_P(FrameProcessorTest, OnlyKeyframes_ContinuousDts_ContinousPts_1) {
  1633. // Verifies that precisely one group start and one stream append occurs for a
  1634. // single continuous set of frames.
  1635. InSequence s;
  1636. AddTestTracks(HAS_AUDIO | OBSERVE_APPENDS_AND_GROUP_STARTS);
  1637. if (use_sequence_mode_)
  1638. frame_processor_->SetSequenceMode(true);
  1639. // Default test frame duration is 10 milliseconds.
  1640. EXPECT_CALL(callbacks_, OnGroupStart(DemuxerStream::AUDIO, DecodeTimestamp(),
  1641. base::TimeDelta()));
  1642. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::AUDIO, _));
  1643. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(40)));
  1644. EXPECT_TRUE(ProcessFrames("0K 10K 20K 30K", ""));
  1645. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1646. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,40) }");
  1647. CheckReadsThenReadStalls(audio_.get(), "0 10 20 30");
  1648. }
  1649. TEST_P(FrameProcessorTest, OnlyKeyframes_ContinuousDts_ContinuousPts_2) {
  1650. // Verifies that precisely one group start and one stream append occurs while
  1651. // processing a single continuous set of frames that uses fudge room to just
  1652. // barely remain adjacent.
  1653. InSequence s;
  1654. AddTestTracks(HAS_AUDIO | OBSERVE_APPENDS_AND_GROUP_STARTS);
  1655. if (use_sequence_mode_)
  1656. frame_processor_->SetSequenceMode(true);
  1657. frame_duration_ = Milliseconds(5);
  1658. EXPECT_CALL(callbacks_, OnGroupStart(DemuxerStream::AUDIO, DecodeTimestamp(),
  1659. base::TimeDelta()));
  1660. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::AUDIO, _));
  1661. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(35)));
  1662. EXPECT_TRUE(ProcessFrames("0K 10K 20K 30K", ""));
  1663. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1664. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,35) }");
  1665. CheckReadsThenReadStalls(audio_.get(), "0 10 20 30");
  1666. }
  1667. TEST_P(FrameProcessorTest,
  1668. OnlyKeyframes_ContinuousDts_DiscontinuousPtsJustBeyondFudgeRoom) {
  1669. // Verifies that multiple group starts and distinct appends occur
  1670. // when processing a single DTS-continuous set of frames with PTS deltas that
  1671. // just barely exceed the adjacency assumption in FrameProcessor.
  1672. InSequence s;
  1673. AddTestTracks(HAS_AUDIO | OBSERVE_APPENDS_AND_GROUP_STARTS);
  1674. if (use_sequence_mode_)
  1675. frame_processor_->SetSequenceMode(true);
  1676. frame_duration_ = base::Microseconds(4999);
  1677. EXPECT_CALL(callbacks_, OnGroupStart(DemuxerStream::AUDIO, DecodeTimestamp(),
  1678. base::TimeDelta()));
  1679. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::AUDIO, _));
  1680. // Frame "10|5K" following "0K" triggers start of new group and eventual
  1681. // append.
  1682. EXPECT_CALL(callbacks_, OnGroupStart(DemuxerStream::AUDIO, DecodeTimestamp(),
  1683. frame_duration_));
  1684. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::AUDIO, _));
  1685. // Frame "20|10K" following "10|5K" triggers start of new group and eventual
  1686. // append.
  1687. EXPECT_CALL(
  1688. callbacks_,
  1689. OnGroupStart(DemuxerStream::AUDIO,
  1690. DecodeTimestamp::FromPresentationTime(Milliseconds(5)),
  1691. Milliseconds(10) + frame_duration_));
  1692. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::AUDIO, _));
  1693. // Frame "30|15K" following "20|10K" triggers start of new group and
  1694. // eventual append.
  1695. EXPECT_CALL(
  1696. callbacks_,
  1697. OnGroupStart(DemuxerStream::AUDIO,
  1698. DecodeTimestamp::FromPresentationTime(Milliseconds(10)),
  1699. Milliseconds(20) + frame_duration_));
  1700. EXPECT_CALL(callbacks_, OnAppend(DemuxerStream::AUDIO, _));
  1701. EXPECT_CALL(callbacks_, PossibleDurationIncrease(base::Microseconds(34999)));
  1702. EXPECT_TRUE(ProcessFrames("0K 10|5K 20|10K 30|15K", ""));
  1703. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1704. // Note that the result is still buffered continuous since DTS was continuous
  1705. // and PTS was monotonically increasing (such that each group start was
  1706. // signalled by FrameProcessor to be continuous with the end of the previous
  1707. // group, if any.)
  1708. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,34) }");
  1709. CheckReadsThenReadStalls(audio_.get(), "0 10 20 30");
  1710. }
  1711. TEST_P(FrameProcessorTest,
  1712. GroupEndTimestampDecreaseWithinMediaSegmentShouldWarn) {
  1713. // This parse warning requires:
  1714. // 1) a decode time discontinuity within the set of frames being processed,
  1715. // 2) the highest frame end time of any frame successfully processed
  1716. // before that discontinuity is higher than the highest frame end time of
  1717. // all frames processed after that discontinuity.
  1718. // TODO(wolenetz): Adjust this case once direction on spec is informed by
  1719. // data. See https://crbug.com/920853 and
  1720. // https://github.com/w3c/media-source/issues/203.
  1721. if (use_sequence_mode_) {
  1722. // Sequence mode modifies the presentation timestamps following a decode
  1723. // discontinuity such that this scenario should not repro with that mode.
  1724. DVLOG(1) << "Skipping segments mode variant; inapplicable to this case.";
  1725. return;
  1726. }
  1727. InSequence s;
  1728. AddTestTracks(HAS_VIDEO);
  1729. EXPECT_CALL(callbacks_,
  1730. OnParseWarning(SourceBufferParseWarning::
  1731. kGroupEndTimestampDecreaseWithinMediaSegment));
  1732. frame_duration_ = Milliseconds(10);
  1733. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(15)));
  1734. EXPECT_TRUE(ProcessFrames("", "0K 10K 5|40K"));
  1735. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1736. CheckExpectedRangesByTimestamp(video_.get(), "{ [0,15) }");
  1737. CheckReadsThenReadStalls(video_.get(), "0 5");
  1738. }
  1739. TEST_P(FrameProcessorTest, NonkeyframeAudioBuffering_BasicOperation) {
  1740. // With the support for audio nonkeyframe buffering enabled, buffer a couple
  1741. // continuous groups of audio key and nonkey frames.
  1742. // Note, see the AudioNonKeyframeChangedToKeyframe test that tests where
  1743. // nonkeyframe audio buffering is not supported, and instead takes a
  1744. // workaround that forces all audio to be keyframe.
  1745. InSequence s;
  1746. AddTestTracks(HAS_AUDIO | USE_AUDIO_CODEC_SUPPORTING_NONKEYFRAMES);
  1747. if (use_sequence_mode_)
  1748. frame_processor_->SetSequenceMode(true);
  1749. // Default test frame duration is 10 milliseconds.
  1750. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(80)));
  1751. EXPECT_TRUE(ProcessFrames("0K 10 20 30 40K 50 60 70", ""));
  1752. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1753. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,80) }");
  1754. CheckReadsAndKeyframenessThenReadStalls(audio_.get(),
  1755. "0K 10N 20N 30N 40K 50N 60N 70N");
  1756. }
  1757. TEST_P(FrameProcessorTest, NonkeyframeAudioBuffering_BasicOverlaps) {
  1758. // With the support for audio nonkeyframe buffering enabled, buffer a few
  1759. // groups of audio key and nonkey frames which overlap each other.
  1760. // For sequence mode versions, timestampOffset is adjusted to make it act like
  1761. // segments mode.
  1762. InSequence s;
  1763. AddTestTracks(HAS_AUDIO | USE_AUDIO_CODEC_SUPPORTING_NONKEYFRAMES);
  1764. if (use_sequence_mode_) {
  1765. frame_processor_->SetSequenceMode(true);
  1766. SetTimestampOffset(Milliseconds(10));
  1767. }
  1768. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(60)));
  1769. EXPECT_TRUE(ProcessFrames("10K 20 30 40 50", ""));
  1770. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1771. CheckExpectedRangesByTimestamp(audio_.get(), "{ [10,60) }");
  1772. // End-overlap the last nonkeyframe appended with a keyframe.
  1773. if (use_sequence_mode_)
  1774. SetTimestampOffset(Milliseconds(50));
  1775. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(70)));
  1776. EXPECT_TRUE(ProcessFrames("50K 60", ""));
  1777. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1778. CheckExpectedRangesByTimestamp(audio_.get(), "{ [10,70) }");
  1779. // Front-overlap the original group of frames.
  1780. if (use_sequence_mode_)
  1781. SetTimestampOffset(Milliseconds(0));
  1782. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(20)));
  1783. EXPECT_TRUE(ProcessFrames("0K 10", ""));
  1784. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1785. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,70) }");
  1786. SeekStream(audio_.get(), Milliseconds(0));
  1787. CheckReadsAndKeyframenessThenReadStalls(audio_.get(), "0K 10N 50K 60N");
  1788. }
  1789. TEST_P(FrameProcessorTest,
  1790. NonkeyframeAudioBuffering_InitialNonkeyframesNotBuffered) {
  1791. // With the support for audio nonkeyframe buffering enabled, try to buffer
  1792. // some frames beginning with a nonkeyframe and observe initial nonkeyframe(s)
  1793. // are not buffered.
  1794. InSequence s;
  1795. AddTestTracks(HAS_AUDIO | USE_AUDIO_CODEC_SUPPORTING_NONKEYFRAMES);
  1796. if (use_sequence_mode_)
  1797. frame_processor_->SetSequenceMode(true);
  1798. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(60)));
  1799. EXPECT_TRUE(ProcessFrames("0 10 20K 30 40 50", ""));
  1800. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1801. CheckExpectedRangesByTimestamp(audio_.get(), "{ [20,60) }");
  1802. CheckReadsAndKeyframenessThenReadStalls(audio_.get(), "20K 30N 40N 50N");
  1803. }
  1804. TEST_P(FrameProcessorTest,
  1805. NonkeyframeAudioBuffering_InvalidDecreasingNonkeyframePts) {
  1806. // With the support for audio nonkeyframe buffering enabled, try to buffer an
  1807. // invalid sequence of nonkeyframes: decreasing presentation timestamps are
  1808. // not supported for audio nonkeyframes. For sequence mode versions,
  1809. // timestampOffset is adjusted to make it act like segments mode.
  1810. InSequence s;
  1811. AddTestTracks(HAS_AUDIO | USE_AUDIO_CODEC_SUPPORTING_NONKEYFRAMES);
  1812. if (use_sequence_mode_) {
  1813. frame_processor_->SetSequenceMode(true);
  1814. SetTimestampOffset(Milliseconds(100));
  1815. }
  1816. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(110)));
  1817. EXPECT_TRUE(ProcessFrames("100K", ""));
  1818. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1819. CheckExpectedRangesByTimestamp(audio_.get(), "{ [100,110) }");
  1820. // Processing an audio nonkeyframe with lower PTS than the previous frame
  1821. // should fail.
  1822. EXPECT_MEDIA_LOG(AudioNonKeyframeOutOfOrder());
  1823. EXPECT_FALSE(ProcessFrames("90|110", ""));
  1824. }
  1825. TEST_P(FrameProcessorTest,
  1826. NonkeyframeAudioBuffering_ValidDecreasingKeyframePts) {
  1827. // With the support for audio nonkeyframe buffering enabled, try to buffer a
  1828. // valid sequence of key and nonkeyframes: decreasing presentation timestamps
  1829. // are supported for keyframes. For sequence mode versions, timestampOffset is
  1830. // adjusted to make it act like segments mode.
  1831. InSequence s;
  1832. AddTestTracks(HAS_AUDIO | USE_AUDIO_CODEC_SUPPORTING_NONKEYFRAMES);
  1833. if (use_sequence_mode_) {
  1834. frame_processor_->SetSequenceMode(true);
  1835. SetTimestampOffset(Milliseconds(100));
  1836. }
  1837. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(130)));
  1838. EXPECT_TRUE(ProcessFrames("100K 110 120", ""));
  1839. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1840. CheckExpectedRangesByTimestamp(audio_.get(), "{ [100,130) }");
  1841. // Processing an audio keyframe with lower PTS than the previous frame
  1842. // should succeed, since it is a keyframe. Here, we use continuous DTS to
  1843. // ensure we precisely target the nonkeyframe monotonicity check when a
  1844. // keyframe is not required by the track buffer currently (and to make
  1845. // sequence mode versions act like segments mode without further manual
  1846. // adjustment of timestamp offset.) The original nonkeyframe at PTS 110 should
  1847. // be overlap-removed, and the one at PTS 120 should have be removed as a
  1848. // result of depending on that removed PTS 110 nonkeyframe.
  1849. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(130)));
  1850. EXPECT_TRUE(ProcessFrames("110|130K", ""));
  1851. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1852. CheckExpectedRangesByTimestamp(audio_.get(), "{ [100,120) }");
  1853. CheckReadsAndKeyframenessThenReadStalls(audio_.get(), "100K 110K");
  1854. }
  1855. TEST_P(FrameProcessorTest,
  1856. NonkeyframeAudioBuffering_ValidSameNonKeyframePts_1) {
  1857. // With the support for audio nonkeyframe buffering enabled, try to buffer a
  1858. // valid sequence of a keyframe and a nonkeyframe: non-increasing presentation
  1859. // timestamps are supported for audio nonkeyframes, so long as they don't
  1860. // decrease. For sequence mode versions, timestampOffset is adjusted to make
  1861. // it act like segments mode.
  1862. InSequence s;
  1863. AddTestTracks(HAS_AUDIO | USE_AUDIO_CODEC_SUPPORTING_NONKEYFRAMES);
  1864. if (use_sequence_mode_) {
  1865. frame_processor_->SetSequenceMode(true);
  1866. SetTimestampOffset(Milliseconds(100));
  1867. }
  1868. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(110)));
  1869. EXPECT_TRUE(ProcessFrames("100K", ""));
  1870. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1871. CheckExpectedRangesByTimestamp(audio_.get(), "{ [100,110) }");
  1872. // Processing an audio nonkeyframe with same PTS as the previous frame should
  1873. // succeed, though there is presentation interval overlap causing removal of
  1874. // the previous frame (in this case, a keyframe), and hence the new dependent
  1875. // nonkeyframe is not buffered.
  1876. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(110)));
  1877. EXPECT_TRUE(ProcessFrames("100|110", ""));
  1878. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1879. CheckExpectedRangesByTimestamp(audio_.get(), "{ }");
  1880. CheckReadsAndKeyframenessThenReadStalls(audio_.get(), "");
  1881. }
  1882. TEST_P(FrameProcessorTest,
  1883. NonkeyframeAudioBuffering_ValidSameNonKeyframePts_2) {
  1884. // With the support for audio nonkeyframe buffering enabled, try to buffer a
  1885. // valid sequence of nonkeyframes: non-increasing presentation timestamps are
  1886. // supported for audio nonkeyframes, so long as they don't decrease. For
  1887. // sequence mode versions, timestampOffset is adjusted to make it act like
  1888. // segments mode.
  1889. InSequence s;
  1890. AddTestTracks(HAS_AUDIO | USE_AUDIO_CODEC_SUPPORTING_NONKEYFRAMES);
  1891. if (use_sequence_mode_) {
  1892. frame_processor_->SetSequenceMode(true);
  1893. SetTimestampOffset(Milliseconds(100));
  1894. }
  1895. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(120)));
  1896. EXPECT_TRUE(ProcessFrames("100K 110", ""));
  1897. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1898. CheckExpectedRangesByTimestamp(audio_.get(), "{ [100,120) }");
  1899. // Processing an audio nonkeyframe with same PTS as the previous frame should
  1900. // succeed, though there is presentation interval overlap causing removal of
  1901. // the previous nonkeyframe, and hence the new dependent nonkeyframe is not
  1902. // buffered.
  1903. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(120)));
  1904. EXPECT_TRUE(ProcessFrames("110|120", ""));
  1905. EXPECT_EQ(Milliseconds(0), timestamp_offset_);
  1906. CheckExpectedRangesByTimestamp(audio_.get(), "{ [100,110) }");
  1907. CheckReadsAndKeyframenessThenReadStalls(audio_.get(), "100K");
  1908. }
  1909. TEST_P(FrameProcessorTest,
  1910. NonkeyframeAudioBuffering_AppendWindowFilterDroppedPrerollKeyframe) {
  1911. // For simplicity currently, if the preroll (keyframe) buffer was entirely
  1912. // prior to the append window and dropped, an approximately continuous
  1913. // keyframe is still required to use that dropped frame as preroll (for
  1914. // simplicity). This may change in future if append window trimming of
  1915. // nonkeyframes with a fully excluded preroll keyframe is commonly needed to
  1916. // be supported.
  1917. InSequence s;
  1918. AddTestTracks(HAS_AUDIO | USE_AUDIO_CODEC_SUPPORTING_NONKEYFRAMES);
  1919. if (use_sequence_mode_)
  1920. frame_processor_->SetSequenceMode(true);
  1921. SetTimestampOffset(Milliseconds(-10));
  1922. EXPECT_MEDIA_LOG(DroppedFrame("audio", -10000));
  1923. if (use_sequence_mode_)
  1924. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(-10)));
  1925. else
  1926. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(0)));
  1927. EXPECT_TRUE(ProcessFrames("0K", ""));
  1928. // This nonkeyframe is dropped for simplicity since it depends on a preroll
  1929. // keyframe which was entirely outside the append window.
  1930. if (use_sequence_mode_)
  1931. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(-10)));
  1932. else
  1933. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(0)));
  1934. EXPECT_TRUE(ProcessFrames("10", ""));
  1935. // Only the following keyframe should buffer successfully, with no preroll.
  1936. EXPECT_MEDIA_LOG(DroppedAppendWindowUnusedPreroll(-10000, -10000, 10000));
  1937. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(20)));
  1938. EXPECT_TRUE(ProcessFrames("20K", ""));
  1939. CheckExpectedRangesByTimestamp(audio_.get(), "{ [10,20) }");
  1940. CheckReadsAndKeyframenessThenReadStalls(audio_.get(), "10:20K");
  1941. }
  1942. TEST_P(FrameProcessorTest,
  1943. NonkeyframeAudioBuffering_AppendWindowFilter_TrimFront) {
  1944. InSequence s;
  1945. AddTestTracks(HAS_AUDIO | USE_AUDIO_CODEC_SUPPORTING_NONKEYFRAMES);
  1946. if (use_sequence_mode_)
  1947. frame_processor_->SetSequenceMode(true);
  1948. SetTimestampOffset(Milliseconds(-4));
  1949. EXPECT_MEDIA_LOG(TruncatedFrame(-4000, 6000, "start", 0));
  1950. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(26)));
  1951. EXPECT_TRUE(ProcessFrames("0K 10 20", ""));
  1952. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,26) }");
  1953. CheckReadsAndKeyframenessThenReadStalls(audio_.get(), "0K 6:10N 16:20N");
  1954. }
  1955. TEST_P(FrameProcessorTest,
  1956. NonkeyframeAudioBuffering_AppendWindowFilter_TrimEnd) {
  1957. InSequence s;
  1958. AddTestTracks(HAS_AUDIO | USE_AUDIO_CODEC_SUPPORTING_NONKEYFRAMES);
  1959. if (use_sequence_mode_)
  1960. frame_processor_->SetSequenceMode(true);
  1961. append_window_end_ = Milliseconds(26);
  1962. EXPECT_MEDIA_LOG(TruncatedFrame(20000, 30000, "end", 26000));
  1963. EXPECT_MEDIA_LOG(DroppedFrameCheckAppendWindow("audio", 0, 26000));
  1964. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(26)));
  1965. EXPECT_TRUE(ProcessFrames("0K 10 20 30", ""));
  1966. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,26) }");
  1967. CheckReadsAndKeyframenessThenReadStalls(audio_.get(), "0K 10N 20N");
  1968. }
  1969. TEST_P(FrameProcessorTest, NonkeyframeAudioBuffering_TrimSpliceOverlap) {
  1970. // White-box test which focuses on the behavior of underlying
  1971. // SourceBufferStream::TrimSpliceOverlap() for frame sequences involving
  1972. // nonkeyframes appended by the FrameProcessor. That method detects and
  1973. // performs splice trimming on every audio frame following either a
  1974. // discontinuity or the beginning of ProcessFrames(), and also on audio frames
  1975. // with PTS not directly continuous with the highest frame end PTS already
  1976. // processed. We vary |frame_duration_| in this test to avoid confusing
  1977. // int:decimal pairs in the eventual CheckReads* call.
  1978. InSequence s;
  1979. AddTestTracks(HAS_AUDIO | USE_AUDIO_CODEC_SUPPORTING_NONKEYFRAMES);
  1980. if (use_sequence_mode_)
  1981. frame_processor_->SetSequenceMode(true);
  1982. frame_duration_ = base::Microseconds(9750);
  1983. EXPECT_CALL(callbacks_, PossibleDurationIncrease(frame_duration_));
  1984. EXPECT_TRUE(ProcessFrames("0K", ""));
  1985. // As with all-keyframe streams, a slight jump forward should not trigger any
  1986. // splicing logic, though accumulations of these may result in loss of A/V
  1987. // sync.
  1988. frame_duration_ = base::Microseconds(10250);
  1989. EXPECT_CALL(callbacks_,
  1990. PossibleDurationIncrease(Milliseconds(10) + frame_duration_));
  1991. EXPECT_TRUE(ProcessFrames("10", ""));
  1992. // As with all-keyframe streams, a slightly end-overlapping nonkeyframe should
  1993. // not trigger any splicing logic, though accumulations of these may result in
  1994. // loss of A/V sync. The difference here is there isn't even any emission of a
  1995. // "too little splice overlap" media log, since the new frame is a
  1996. // nonkeyframe.
  1997. frame_duration_ = Milliseconds(10);
  1998. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(30)));
  1999. EXPECT_TRUE(ProcessFrames("20", ""));
  2000. // A heavily overlapping nonkeyframe should not trigger any splicing logic,
  2001. // so long as it isn't completely discontinuous. This is unlike all-keyframe
  2002. // audio streams, where such a heavy overlap would end-trim the overlapped
  2003. // frame. Accumulations of these could rapidly lead to loss of A/V sync.
  2004. // Nonkeyframe timestamp & duration metadata sequences need to be correctly
  2005. // muxed to avoid this.
  2006. frame_duration_ = base::Microseconds(10250);
  2007. EXPECT_CALL(callbacks_,
  2008. PossibleDurationIncrease(Milliseconds(22) + frame_duration_));
  2009. EXPECT_TRUE(ProcessFrames("22", ""));
  2010. // A keyframe that end-overlaps a nonkeyframe will trigger splicing logic.
  2011. // Here, we test a "too little splice overlap" case.
  2012. frame_duration_ = Milliseconds(10);
  2013. EXPECT_MEDIA_LOG(SkippingSpliceTooLittleOverlap(32000, 250));
  2014. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(42)));
  2015. EXPECT_TRUE(ProcessFrames("32K", ""));
  2016. // And a keyframe that significantly end-overlaps a nonkeyframe will trigger
  2017. // splicing logic that can perform end-trimming of the overlapped frame.
  2018. // First, we buffer another nonkeyframe.
  2019. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(52)));
  2020. EXPECT_TRUE(ProcessFrames("42", ""));
  2021. // Verify correct splice behavior on significant overlap of the nonkeyframe by
  2022. // a new keyframe.
  2023. EXPECT_MEDIA_LOG(TrimmedSpliceOverlap(45000, 42000, 7000));
  2024. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(55)));
  2025. EXPECT_TRUE(ProcessFrames("45K", ""));
  2026. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,55) }");
  2027. CheckReadsAndKeyframenessThenReadStalls(audio_.get(),
  2028. "0K 10N 20N 22N 32K 42N 45K");
  2029. }
  2030. TEST_P(FrameProcessorTest, FrameDuration_kNoTimestamp_Fails) {
  2031. InSequence s;
  2032. AddTestTracks(HAS_AUDIO);
  2033. frame_processor_->SetSequenceMode(use_sequence_mode_);
  2034. frame_duration_ = kNoTimestamp;
  2035. EXPECT_MEDIA_LOG(FrameDurationUnknown("audio", 1000));
  2036. EXPECT_FALSE(ProcessFrames("1K", ""));
  2037. }
  2038. TEST_P(FrameProcessorTest,
  2039. Pts_BeforeTimestampOffsetApplied_kNoTimestamp_Fails) {
  2040. InSequence s;
  2041. AddTestTracks(HAS_AUDIO);
  2042. frame_processor_->SetSequenceMode(use_sequence_mode_);
  2043. EXPECT_MEDIA_LOG(PtsUnknown("audio"));
  2044. EXPECT_FALSE(ProcessFrames("MinK", ""));
  2045. }
  2046. TEST_P(FrameProcessorTest,
  2047. Pts_BeforeTimestampOffsetApplied_kInfiniteDuration_Fails) {
  2048. InSequence s;
  2049. AddTestTracks(HAS_AUDIO);
  2050. frame_processor_->SetSequenceMode(use_sequence_mode_);
  2051. EXPECT_MEDIA_LOG(FrameTimeOutOfRange("Before adjusting by timestampOffset",
  2052. "PTS", "audio"));
  2053. EXPECT_FALSE(ProcessFrames("MaxK", ""));
  2054. }
  2055. TEST_P(FrameProcessorTest,
  2056. Dts_BeforeTimestampOffsetApplied_kNoDecodeTimestamp_UsesPtsIfValid) {
  2057. InSequence s;
  2058. AddTestTracks(HAS_AUDIO);
  2059. frame_processor_->SetSequenceMode(use_sequence_mode_);
  2060. // When PTS is valid, but DTS is kNoDecodeTimestamp, then
  2061. // StreamParserBuffer::GetDecodeTimestamp() just returns the frame's PTS.
  2062. EXPECT_CALL(callbacks_, PossibleDurationIncrease(Milliseconds(10)));
  2063. EXPECT_TRUE(ProcessFrames("0|MinK", ""));
  2064. CheckExpectedRangesByTimestamp(audio_.get(), "{ [0,10) }");
  2065. CheckReadsAndKeyframenessThenReadStalls(audio_.get(), "0K");
  2066. }
  2067. TEST_P(FrameProcessorTest,
  2068. Dts_BeforeTimestampOffsetApplied_kMaxDecodeTimestamp_Fails) {
  2069. InSequence s;
  2070. AddTestTracks(HAS_AUDIO);
  2071. frame_processor_->SetSequenceMode(use_sequence_mode_);
  2072. EXPECT_MEDIA_LOG(FrameTimeOutOfRange("Before adjusting by timestampOffset",
  2073. "DTS", "audio"));
  2074. EXPECT_FALSE(ProcessFrames("0|MaxK", ""));
  2075. }
  2076. TEST_P(FrameProcessorTest, After_Sequence_OffsetUpdate_kNoTimestamp_Fails) {
  2077. if (!use_sequence_mode_) {
  2078. DVLOG(1) << "Skipping segments mode variant; inapplicable to this case.";
  2079. return;
  2080. }
  2081. InSequence s;
  2082. AddTestTracks(HAS_AUDIO);
  2083. frame_processor_->SetSequenceMode(use_sequence_mode_);
  2084. // (-Infinity + 5)ms minus 10ms saturates to (-Infinity)ms.
  2085. SetTimestampOffset(kNoTimestamp + Milliseconds(5));
  2086. EXPECT_MEDIA_LOG(SequenceOffsetUpdateOutOfRange());
  2087. EXPECT_FALSE(ProcessFrames("10K", ""));
  2088. }
  2089. TEST_P(FrameProcessorTest,
  2090. After_Sequence_OffsetUpdate_kInfiniteDuration_Fails) {
  2091. if (!use_sequence_mode_) {
  2092. DVLOG(1) << "Skipping segments mode variant; inapplicable to this case.";
  2093. return;
  2094. }
  2095. InSequence s;
  2096. AddTestTracks(HAS_AUDIO);
  2097. frame_processor_->SetSequenceMode(use_sequence_mode_);
  2098. // (+Infinity - 5)ms minus -10ms saturates to (+Infinity)ms.
  2099. SetTimestampOffset(kInfiniteDuration - Milliseconds(5));
  2100. EXPECT_MEDIA_LOG(SequenceOffsetUpdateOutOfRange());
  2101. EXPECT_FALSE(ProcessFrames("-10K", ""));
  2102. }
  2103. TEST_P(FrameProcessorTest,
  2104. Before_Sequence_OffsetUpdate_kInfiniteDuration_Fails) {
  2105. if (!use_sequence_mode_) {
  2106. DVLOG(1) << "Skipping segments mode variant; inapplicable to this case.";
  2107. return;
  2108. }
  2109. InSequence s;
  2110. AddTestTracks(HAS_AUDIO);
  2111. frame_processor_->SetSequenceMode(use_sequence_mode_);
  2112. // Effectively sets group start timestamp to +Infinity.
  2113. SetTimestampOffset(kInfiniteDuration);
  2114. EXPECT_MEDIA_LOG(
  2115. SequenceOffsetUpdatePreventedByOutOfRangeGroupStartTimestamp());
  2116. // That infinite value fails precondition of finite value for group start
  2117. // timestamp when about to update timestampOffset based upon it.
  2118. EXPECT_FALSE(ProcessFrames("0K", ""));
  2119. }
  2120. TEST_P(FrameProcessorTest, Segments_InfiniteTimestampOffset_Fails) {
  2121. if (use_sequence_mode_) {
  2122. DVLOG(1) << "Skipping sequence mode variant; inapplicable to this case.";
  2123. return;
  2124. }
  2125. InSequence s;
  2126. AddTestTracks(HAS_AUDIO);
  2127. frame_processor_->SetSequenceMode(use_sequence_mode_);
  2128. SetTimestampOffset(kInfiniteDuration);
  2129. EXPECT_MEDIA_LOG(OffsetOutOfRange());
  2130. EXPECT_FALSE(ProcessFrames("0K", ""));
  2131. }
  2132. TEST_P(FrameProcessorTest, Pts_AfterTimestampOffsetApplied_kNoTimestamp_Fails) {
  2133. InSequence s;
  2134. AddTestTracks(HAS_VIDEO);
  2135. frame_processor_->SetSequenceMode(use_sequence_mode_);
  2136. // Note, SetTimestampOffset(kNoTimestamp) hits DCHECK. This test instead
  2137. // checks that the result of offset application to PTS gives parse error if
  2138. // the result is <= kNoTimestamp. Getting such a result requires different
  2139. // test logic for segments vs sequence append modes.
  2140. if (use_sequence_mode_) {
  2141. // Use an extremely out-of-order DTS/PTS GOP to get the resulting
  2142. // timestampOffset needed for application to a nonkeyframe PTS (continuous
  2143. // in DTS time with its GOP's keyframe), resulting with kNoTimestamp PTS.
  2144. // First, calculate (-kNoTimestamp - 10ms), truncated down to nearest
  2145. // millisecond, for use as keyframe PTS and DTS.
  2146. frame_duration_ = Milliseconds(1);
  2147. base::TimeDelta ts =
  2148. Milliseconds(((kNoTimestamp + Milliseconds(10)) * -1).InMilliseconds());
  2149. std::string ts_str = base::NumberToString(ts.InMilliseconds());
  2150. // Append the keyframe and expect success for this step.
  2151. EXPECT_CALL(callbacks_, PossibleDurationIncrease(frame_duration_));
  2152. EXPECT_TRUE(ProcessFrames("", ts_str + "|" + ts_str + "K"));
  2153. EXPECT_EQ(timestamp_offset_.InMicroseconds(), (-1 * ts).InMicroseconds());
  2154. // A nonkeyframe with the same DTS as previous frame does not cause any
  2155. // discontinuity. Append such a frame, with PTS before offset applied that
  2156. // saturates to kNoTimestamp when the offset is applied.
  2157. EXPECT_MEDIA_LOG(FrameTimeOutOfRange("After adjusting by timestampOffset",
  2158. "PTS", "video"));
  2159. EXPECT_FALSE(ProcessFrames("", "-20|" + ts_str));
  2160. } else {
  2161. // Set the offset to be just above kNoTimestamp, and append a frame with a
  2162. // PTS that is negative by at least that small amount. The result should
  2163. // saturate to kNoTimestamp for PTS.
  2164. SetTimestampOffset(kNoTimestamp + Milliseconds(1));
  2165. EXPECT_MEDIA_LOG(FrameTimeOutOfRange("After adjusting by timestampOffset",
  2166. "PTS", "video"));
  2167. EXPECT_FALSE(ProcessFrames("", "-2K"));
  2168. }
  2169. }
  2170. TEST_P(FrameProcessorTest,
  2171. Pts_AfterTimestampOffsetApplied_kInfiniteDuration_Fails) {
  2172. InSequence s;
  2173. AddTestTracks(HAS_VIDEO);
  2174. frame_processor_->SetSequenceMode(use_sequence_mode_);
  2175. // Use a video GOP with a nonkeyframe PTS that jumps forward far enough to
  2176. // saturate to kInfiniteDuration after timestampOffset is applied. Take care
  2177. // to avoid saturating the (earlier) keyframe's frame_end_timestamp to
  2178. // kInfiniteDuration, avoiding a different parse error case.
  2179. // First, calculate (kInfiniteDuration - 2ms), truncated down to nearest
  2180. // millisecond for use as keyframe PTS (after timestamp offset application).
  2181. // It's also used for start of DTS sequence.
  2182. frame_duration_ = Milliseconds(1);
  2183. base::TimeDelta ts =
  2184. Milliseconds((kInfiniteDuration - Milliseconds(2)).InMilliseconds());
  2185. // Append the keyframe and expect success for this step.
  2186. SetTimestampOffset(ts);
  2187. EXPECT_CALL(callbacks_, PossibleDurationIncrease(ts + frame_duration_));
  2188. EXPECT_TRUE(ProcessFrames("", "0K"));
  2189. // Sequence mode might adjust the offset. This test's logic should ensure the
  2190. // offset is the same as in segments mode at this point.
  2191. EXPECT_EQ(timestamp_offset_.InMicroseconds(), ts.InMicroseconds());
  2192. // A nonkeyframe with same DTS as previous frame does not cause any
  2193. // discontinuity. Append such a frame, with PTS jumped 3ms forwards such that
  2194. // it saturates to kInfiniteDuration when offset is applied.
  2195. EXPECT_MEDIA_LOG(FrameTimeOutOfRange("After adjusting by timestampOffset",
  2196. "PTS", "video"));
  2197. EXPECT_FALSE(ProcessFrames("", "3|0"));
  2198. }
  2199. TEST_P(FrameProcessorTest,
  2200. Dts_AfterTimestampOffsetApplied_kNoDecodeTimestamp_Fails) {
  2201. InSequence s;
  2202. AddTestTracks(HAS_AUDIO);
  2203. frame_processor_->SetSequenceMode(use_sequence_mode_);
  2204. SetTimestampOffset(kNoTimestamp + Milliseconds(5));
  2205. EXPECT_MEDIA_LOG(FrameTimeOutOfRange("After adjusting by timestampOffset",
  2206. "DTS", "audio"));
  2207. EXPECT_FALSE(ProcessFrames("0|-10K", ""));
  2208. }
  2209. TEST_P(FrameProcessorTest,
  2210. Dts_AfterTimestampOffsetApplied_kMaxDecodeTimestamp_Fails) {
  2211. InSequence s;
  2212. AddTestTracks(HAS_AUDIO);
  2213. frame_processor_->SetSequenceMode(use_sequence_mode_);
  2214. SetTimestampOffset(kInfiniteDuration - Milliseconds(5));
  2215. EXPECT_MEDIA_LOG(FrameTimeOutOfRange("After adjusting by timestampOffset",
  2216. "DTS", "audio"));
  2217. EXPECT_FALSE(ProcessFrames("0|10K", ""));
  2218. }
  2219. TEST_P(FrameProcessorTest, FrameEndTimestamp_kInfiniteDuration_Fails) {
  2220. InSequence s;
  2221. AddTestTracks(HAS_AUDIO);
  2222. frame_processor_->SetSequenceMode(use_sequence_mode_);
  2223. frame_duration_ = Milliseconds(10);
  2224. SetTimestampOffset(kInfiniteDuration - Milliseconds(5));
  2225. EXPECT_MEDIA_LOG(FrameEndTimestampOutOfRange("audio"));
  2226. EXPECT_FALSE(ProcessFrames("0|0K", ""));
  2227. }
  2228. INSTANTIATE_TEST_SUITE_P(SequenceMode, FrameProcessorTest, Values(true));
  2229. INSTANTIATE_TEST_SUITE_P(SegmentsMode, FrameProcessorTest, Values(false));
  2230. } // namespace media