decoder_stream_traits.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. // Copyright 2014 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "media/filters/decoder_stream_traits.h"
  5. #include <limits>
  6. #include <memory>
  7. #include "base/logging.h"
  8. #include "base/metrics/histogram_macros.h"
  9. #include "media/base/audio_buffer.h"
  10. #include "media/base/audio_decoder.h"
  11. #include "media/base/audio_decoder_config.h"
  12. #include "media/base/video_decoder.h"
  13. #include "media/base/video_frame.h"
  14. namespace media {
  15. // Audio decoder stream traits implementation.
  16. // static
  17. std::string DecoderStreamTraits<DemuxerStream::AUDIO>::ToString() {
  18. return "audio";
  19. }
  20. // static
  21. bool DecoderStreamTraits<DemuxerStream::AUDIO>::NeedsBitstreamConversion(
  22. DecoderType* decoder) {
  23. return decoder->NeedsBitstreamConversion();
  24. }
  25. // static
  26. scoped_refptr<DecoderStreamTraits<DemuxerStream::AUDIO>::OutputType>
  27. DecoderStreamTraits<DemuxerStream::AUDIO>::CreateEOSOutput() {
  28. return OutputType::CreateEOSBuffer();
  29. }
  30. void DecoderStreamTraits<DemuxerStream::AUDIO>::SetIsPlatformDecoder(
  31. bool is_platform_decoder) {
  32. stats_.audio_pipeline_info.is_platform_decoder = is_platform_decoder;
  33. }
  34. void DecoderStreamTraits<DemuxerStream::AUDIO>::SetIsDecryptingDemuxerStream(
  35. bool is_dds) {
  36. stats_.audio_pipeline_info.has_decrypting_demuxer_stream = is_dds;
  37. }
  38. void DecoderStreamTraits<DemuxerStream::AUDIO>::SetEncryptionType(
  39. EncryptionType encryption_type) {
  40. stats_.audio_pipeline_info.encryption_type = encryption_type;
  41. }
  42. DecoderStreamTraits<DemuxerStream::AUDIO>::DecoderStreamTraits(
  43. MediaLog* media_log,
  44. ChannelLayout initial_hw_layout,
  45. SampleFormat initial_hw_sample_format)
  46. : media_log_(media_log),
  47. initial_hw_layout_(initial_hw_layout),
  48. initial_hw_sample_format_(initial_hw_sample_format) {
  49. weak_this_ = weak_factory_.GetWeakPtr();
  50. }
  51. DecoderStreamTraits<DemuxerStream::AUDIO>::DecoderConfigType
  52. DecoderStreamTraits<DemuxerStream::AUDIO>::GetDecoderConfig(
  53. DemuxerStream* stream) {
  54. auto config = stream->audio_decoder_config();
  55. // Demuxer is not aware of hw layout, so we set it here.
  56. config.set_target_output_channel_layout(initial_hw_layout_);
  57. config.set_target_output_sample_format(initial_hw_sample_format_);
  58. return config;
  59. }
  60. void DecoderStreamTraits<DemuxerStream::AUDIO>::ReportStatistics(
  61. const StatisticsCB& statistics_cb,
  62. int bytes_decoded) {
  63. stats_.audio_bytes_decoded = bytes_decoded;
  64. statistics_cb.Run(stats_);
  65. }
  66. void DecoderStreamTraits<DemuxerStream::AUDIO>::InitializeDecoder(
  67. DecoderType* decoder,
  68. const DecoderConfigType& config,
  69. bool /* low_delay */,
  70. CdmContext* cdm_context,
  71. InitCB init_cb,
  72. const OutputCB& output_cb,
  73. const WaitingCB& waiting_cb) {
  74. DCHECK(config.IsValidConfig());
  75. if (config_.IsValidConfig() && !config_.Matches(config))
  76. OnConfigChanged(config);
  77. config_ = config;
  78. stats_.audio_pipeline_info.decoder_type = AudioDecoderType::kUnknown;
  79. // Both |this| and |decoder| are owned by a DecoderSelector and will stay
  80. // alive at least until |init_cb| is finished executing.
  81. decoder->Initialize(
  82. config, cdm_context,
  83. base::BindOnce(
  84. &DecoderStreamTraits<DemuxerStream::AUDIO>::OnDecoderInitialized,
  85. weak_this_, base::Unretained(decoder), std::move(init_cb)),
  86. output_cb, waiting_cb);
  87. }
  88. void DecoderStreamTraits<DemuxerStream::AUDIO>::OnDecoderInitialized(
  89. DecoderType* decoder,
  90. InitCB cb,
  91. DecoderStatus result) {
  92. if (result.is_ok())
  93. stats_.audio_pipeline_info.decoder_type = decoder->GetDecoderType();
  94. std::move(cb).Run(result);
  95. }
  96. void DecoderStreamTraits<DemuxerStream::AUDIO>::OnStreamReset(
  97. DemuxerStream* stream) {
  98. DCHECK(stream);
  99. // Stream is likely being seeked to a new timestamp, so make new validator to
  100. // build new timestamp expectations.
  101. audio_ts_validator_ = std::make_unique<AudioTimestampValidator>(
  102. stream->audio_decoder_config(), media_log_);
  103. }
  104. void DecoderStreamTraits<DemuxerStream::AUDIO>::OnDecode(
  105. const DecoderBuffer& buffer) {
  106. audio_ts_validator_->CheckForTimestampGap(buffer);
  107. }
  108. PostDecodeAction DecoderStreamTraits<DemuxerStream::AUDIO>::OnDecodeDone(
  109. OutputType* buffer) {
  110. audio_ts_validator_->RecordOutputDuration(*buffer);
  111. return PostDecodeAction::DELIVER;
  112. }
  113. void DecoderStreamTraits<DemuxerStream::AUDIO>::OnConfigChanged(
  114. const DecoderConfigType& config) {
  115. // Reset validator with the latest config. Also ensures that we do not attempt
  116. // to match timestamps across config boundaries.
  117. audio_ts_validator_ =
  118. std::make_unique<AudioTimestampValidator>(config, media_log_);
  119. }
  120. void DecoderStreamTraits<DemuxerStream::AUDIO>::OnOutputReady(
  121. OutputType* buffer) {}
  122. // Video decoder stream traits implementation.
  123. // static
  124. std::string DecoderStreamTraits<DemuxerStream::VIDEO>::ToString() {
  125. return "video";
  126. }
  127. // static
  128. bool DecoderStreamTraits<DemuxerStream::VIDEO>::NeedsBitstreamConversion(
  129. DecoderType* decoder) {
  130. return decoder->NeedsBitstreamConversion();
  131. }
  132. // static
  133. scoped_refptr<DecoderStreamTraits<DemuxerStream::VIDEO>::OutputType>
  134. DecoderStreamTraits<DemuxerStream::VIDEO>::CreateEOSOutput() {
  135. return OutputType::CreateEOSFrame();
  136. }
  137. void DecoderStreamTraits<DemuxerStream::VIDEO>::SetIsPlatformDecoder(
  138. bool is_platform_decoder) {
  139. stats_.video_pipeline_info.is_platform_decoder = is_platform_decoder;
  140. }
  141. void DecoderStreamTraits<DemuxerStream::VIDEO>::SetIsDecryptingDemuxerStream(
  142. bool is_dds) {
  143. stats_.video_pipeline_info.has_decrypting_demuxer_stream = is_dds;
  144. }
  145. void DecoderStreamTraits<DemuxerStream::VIDEO>::SetEncryptionType(
  146. EncryptionType encryption_type) {
  147. stats_.video_pipeline_info.encryption_type = encryption_type;
  148. }
  149. DecoderStreamTraits<DemuxerStream::VIDEO>::DecoderStreamTraits(
  150. MediaLog* media_log)
  151. // Randomly selected number of samples to keep.
  152. : keyframe_distance_average_(16) {
  153. weak_this_ = weak_factory_.GetWeakPtr();
  154. }
  155. DecoderStreamTraits<DemuxerStream::VIDEO>::DecoderConfigType
  156. DecoderStreamTraits<DemuxerStream::VIDEO>::GetDecoderConfig(
  157. DemuxerStream* stream) {
  158. return stream->video_decoder_config();
  159. }
  160. void DecoderStreamTraits<DemuxerStream::VIDEO>::ReportStatistics(
  161. const StatisticsCB& statistics_cb,
  162. int bytes_decoded) {
  163. stats_.video_bytes_decoded = bytes_decoded;
  164. if (keyframe_distance_average_.count()) {
  165. stats_.video_keyframe_distance_average =
  166. keyframe_distance_average_.Average();
  167. } else {
  168. // Before we have enough keyframes to calculate the average distance, we
  169. // will assume the average keyframe distance is infinitely large.
  170. stats_.video_keyframe_distance_average = base::TimeDelta::Max();
  171. }
  172. statistics_cb.Run(stats_);
  173. }
  174. void DecoderStreamTraits<DemuxerStream::VIDEO>::InitializeDecoder(
  175. DecoderType* decoder,
  176. const DecoderConfigType& config,
  177. bool low_delay,
  178. CdmContext* cdm_context,
  179. InitCB init_cb,
  180. const OutputCB& output_cb,
  181. const WaitingCB& waiting_cb) {
  182. DCHECK(config.IsValidConfig());
  183. stats_.video_pipeline_info.decoder_type = VideoDecoderType::kUnknown;
  184. transform_ = config.video_transformation();
  185. // |decoder| is owned by a DecoderSelector and will stay
  186. // alive at least until |init_cb| is finished executing.
  187. decoder->Initialize(
  188. config, low_delay, cdm_context,
  189. base::BindOnce(
  190. &DecoderStreamTraits<DemuxerStream::VIDEO>::OnDecoderInitialized,
  191. weak_this_, base::Unretained(decoder), std::move(init_cb)),
  192. output_cb, waiting_cb);
  193. }
  194. void DecoderStreamTraits<DemuxerStream::VIDEO>::OnDecoderInitialized(
  195. DecoderType* decoder,
  196. InitCB cb,
  197. DecoderStatus result) {
  198. if (result.is_ok()) {
  199. stats_.video_pipeline_info.decoder_type = decoder->GetDecoderType();
  200. DVLOG(2) << stats_.video_pipeline_info.decoder_type;
  201. } else {
  202. DVLOG(2) << "Decoder initialization failed.";
  203. }
  204. std::move(cb).Run(result);
  205. }
  206. void DecoderStreamTraits<DemuxerStream::VIDEO>::OnStreamReset(
  207. DemuxerStream* stream) {
  208. DCHECK(stream);
  209. last_keyframe_timestamp_ = base::TimeDelta();
  210. frame_metadata_.clear();
  211. }
  212. void DecoderStreamTraits<DemuxerStream::VIDEO>::OnDecode(
  213. const DecoderBuffer& buffer) {
  214. if (buffer.end_of_stream()) {
  215. last_keyframe_timestamp_ = base::TimeDelta();
  216. return;
  217. }
  218. frame_metadata_[buffer.timestamp()] = {
  219. buffer.discard_padding().first == kInfiniteDuration, // should_drop
  220. buffer.duration(), // duration
  221. base::TimeTicks::Now(), // decode_begin_time
  222. };
  223. if (!buffer.is_key_frame())
  224. return;
  225. base::TimeDelta current_frame_timestamp = buffer.timestamp();
  226. if (last_keyframe_timestamp_.is_zero()) {
  227. last_keyframe_timestamp_ = current_frame_timestamp;
  228. return;
  229. }
  230. const base::TimeDelta frame_distance =
  231. current_frame_timestamp - last_keyframe_timestamp_;
  232. last_keyframe_timestamp_ = current_frame_timestamp;
  233. keyframe_distance_average_.AddSample(frame_distance);
  234. }
  235. PostDecodeAction DecoderStreamTraits<DemuxerStream::VIDEO>::OnDecodeDone(
  236. OutputType* buffer) {
  237. auto it = frame_metadata_.find(buffer->timestamp());
  238. // If the frame isn't in |frame_metadata_| it probably was erased below on a
  239. // previous cycle. We could drop these, but today our video algorithm will put
  240. // them back into sorted order or drop the frame if a later frame has already
  241. // been rendered.
  242. if (it == frame_metadata_.end())
  243. return PostDecodeAction::DELIVER;
  244. // Add a timestamp here to enable buffering delay measurements down the line.
  245. buffer->metadata().decode_begin_time = it->second.decode_begin_time;
  246. buffer->metadata().decode_end_time = base::TimeTicks::Now();
  247. auto action = it->second.should_drop ? PostDecodeAction::DROP
  248. : PostDecodeAction::DELIVER;
  249. // Provide duration information to help the rendering algorithm on the very
  250. // first and very last frames.
  251. if (it->second.duration != kNoTimestamp)
  252. buffer->metadata().frame_duration = it->second.duration;
  253. // We erase from the beginning onward to our target frame since frames should
  254. // be returned in presentation order. It's possible to accumulate entries in
  255. // this queue if playback begins at a non-keyframe; those frames may never be
  256. // returned from the decoder.
  257. frame_metadata_.erase(frame_metadata_.begin(), it + 1);
  258. return action;
  259. }
  260. void DecoderStreamTraits<DemuxerStream::VIDEO>::OnOutputReady(
  261. OutputType* buffer) {
  262. buffer->metadata().transformation = transform_;
  263. if (!buffer->metadata().decode_begin_time.has_value())
  264. return;
  265. // Tag buffer with elapsed time since creation.
  266. buffer->metadata().processing_time =
  267. base::TimeTicks::Now() - *buffer->metadata().decode_begin_time;
  268. }
  269. void DecoderStreamTraits<DemuxerStream::VIDEO>::SetPreferNonPlatformDecoders(
  270. bool prefer) {
  271. prefer_non_platform_decoders_ = prefer;
  272. }
  273. bool DecoderStreamTraits<DemuxerStream::VIDEO>::GetPreferNonPlatformDecoders()
  274. const {
  275. return prefer_non_platform_decoders_;
  276. }
  277. } // namespace media