vp9_decoder.cc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. // Copyright 2015 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/gpu/vp9_decoder.h"
  5. #include <memory>
  6. #include "base/bind.h"
  7. #include "base/feature_list.h"
  8. #include "base/logging.h"
  9. #include "base/metrics/histogram_functions.h"
  10. #include "build/build_config.h"
  11. #include "build/chromeos_buildflags.h"
  12. #include "media/base/limits.h"
  13. #include "media/base/media_switches.h"
  14. #include "media/gpu/vp9_decoder.h"
  15. namespace media {
  16. namespace {
  17. bool GetSpatialLayerFrameSize(const DecoderBuffer& decoder_buffer,
  18. std::vector<uint32_t>& frame_sizes) {
  19. frame_sizes.clear();
  20. const uint32_t* cue_data =
  21. reinterpret_cast<const uint32_t*>(decoder_buffer.side_data());
  22. if (!cue_data)
  23. return true;
  24. bool enable_vp9_ksvc =
  25. // On windows, currently only d3d11 supports decoding VP9 kSVC stream, we
  26. // shouldn't combine the switch kD3D11Vp9kSVCHWDecoding to kVp9kSVCHWDecoding
  27. // due to we want keep returning false to MediaCapability.
  28. #if BUILDFLAG(IS_WIN)
  29. base::FeatureList::IsEnabled(media::kD3D11Vp9kSVCHWDecoding);
  30. #elif BUILDFLAG(IS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY)
  31. // V4L2 stateless API decoder is not capable of decoding VP9 k-SVC stream.
  32. false;
  33. #else
  34. base::FeatureList::IsEnabled(media::kVp9kSVCHWDecoding);
  35. #endif
  36. if (!enable_vp9_ksvc) {
  37. DLOG(ERROR) << "Vp9 k-SVC hardware decoding is disabled";
  38. return false;
  39. }
  40. size_t num_of_layers = decoder_buffer.side_data_size() / sizeof(uint32_t);
  41. if (num_of_layers > 3u) {
  42. DLOG(WARNING) << "The maximum number of spatial layers in VP9 is three";
  43. return false;
  44. }
  45. frame_sizes = std::vector<uint32_t>(cue_data, cue_data + num_of_layers);
  46. return true;
  47. }
  48. VideoCodecProfile VP9ProfileToVideoCodecProfile(uint8_t profile) {
  49. switch (profile) {
  50. case 0:
  51. return VP9PROFILE_PROFILE0;
  52. case 1:
  53. return VP9PROFILE_PROFILE1;
  54. case 2:
  55. return VP9PROFILE_PROFILE2;
  56. case 3:
  57. return VP9PROFILE_PROFILE3;
  58. default:
  59. return VIDEO_CODEC_PROFILE_UNKNOWN;
  60. }
  61. }
  62. bool IsValidBitDepth(uint8_t bit_depth, VideoCodecProfile profile) {
  63. // Spec 7.2.
  64. switch (profile) {
  65. case VP9PROFILE_PROFILE0:
  66. case VP9PROFILE_PROFILE1:
  67. return bit_depth == 8u;
  68. case VP9PROFILE_PROFILE2:
  69. case VP9PROFILE_PROFILE3:
  70. return bit_depth == 10u || bit_depth == 12u;
  71. default:
  72. NOTREACHED();
  73. return false;
  74. }
  75. }
  76. VideoChromaSampling GetVP9ChromaSampling(const Vp9FrameHeader& frame_header) {
  77. // Spec section 7.2.2
  78. uint8_t subsampling_x = frame_header.subsampling_x;
  79. uint8_t subsampling_y = frame_header.subsampling_y;
  80. if (subsampling_x == 0 && subsampling_y == 0) {
  81. return VideoChromaSampling::k444;
  82. } else if (subsampling_x == 1u && subsampling_y == 0u) {
  83. return VideoChromaSampling::k422;
  84. } else if (subsampling_x == 1u && subsampling_y == 1u) {
  85. return VideoChromaSampling::k420;
  86. } else {
  87. DLOG(WARNING) << "Unknown chroma sampling format.";
  88. return VideoChromaSampling::kUnknown;
  89. }
  90. }
  91. } // namespace
  92. VP9Decoder::VP9Accelerator::VP9Accelerator() {}
  93. VP9Decoder::VP9Accelerator::~VP9Accelerator() {}
  94. bool VP9Decoder::VP9Accelerator::SupportsContextProbabilityReadback() const {
  95. return false;
  96. }
  97. VP9Decoder::VP9Decoder(std::unique_ptr<VP9Accelerator> accelerator,
  98. VideoCodecProfile profile,
  99. const VideoColorSpace& container_color_space)
  100. : state_(kNeedStreamMetadata),
  101. container_color_space_(container_color_space),
  102. // TODO(hiroh): Set profile to UNKNOWN.
  103. profile_(profile),
  104. accelerator_(std::move(accelerator)),
  105. parser_(accelerator_->NeedsCompressedHeaderParsed(),
  106. accelerator_->SupportsContextProbabilityReadback()) {}
  107. VP9Decoder::~VP9Decoder() = default;
  108. void VP9Decoder::SetStream(int32_t id, const DecoderBuffer& decoder_buffer) {
  109. const uint8_t* ptr = decoder_buffer.data();
  110. const size_t size = decoder_buffer.data_size();
  111. const DecryptConfig* decrypt_config = decoder_buffer.decrypt_config();
  112. DCHECK(ptr);
  113. DCHECK(size);
  114. DVLOG(4) << "New input stream id: " << id << " at: " << (void*)ptr
  115. << " size: " << size;
  116. stream_id_ = id;
  117. std::vector<uint32_t> frame_sizes;
  118. if (!GetSpatialLayerFrameSize(decoder_buffer, frame_sizes)) {
  119. SetError();
  120. return;
  121. }
  122. parser_.SetStream(ptr, size, frame_sizes,
  123. decrypt_config ? decrypt_config->Clone() : nullptr);
  124. }
  125. bool VP9Decoder::Flush() {
  126. DVLOG(2) << "Decoder flush";
  127. Reset();
  128. return true;
  129. }
  130. void VP9Decoder::Reset() {
  131. curr_frame_hdr_ = nullptr;
  132. decrypt_config_.reset();
  133. pending_pic_.reset();
  134. ref_frames_.Clear();
  135. parser_.Reset();
  136. if (state_ == kDecoding) {
  137. state_ = kAfterReset;
  138. }
  139. }
  140. VP9Decoder::DecodeResult VP9Decoder::Decode() {
  141. while (true) {
  142. if (state_ == kError)
  143. return kDecodeError;
  144. // If we have a pending picture to decode, try that first.
  145. if (pending_pic_) {
  146. VP9Accelerator::Status status =
  147. DecodeAndOutputPicture(std::move(pending_pic_));
  148. if (status == VP9Accelerator::Status::kFail) {
  149. SetError();
  150. return kDecodeError;
  151. }
  152. if (status == VP9Accelerator::Status::kTryAgain)
  153. return kTryAgain;
  154. }
  155. // Read a new frame header if one is not awaiting decoding already.
  156. if (!curr_frame_hdr_) {
  157. gfx::Size allocate_size;
  158. std::unique_ptr<Vp9FrameHeader> hdr(new Vp9FrameHeader());
  159. Vp9Parser::Result res =
  160. parser_.ParseNextFrame(hdr.get(), &allocate_size, &decrypt_config_);
  161. switch (res) {
  162. case Vp9Parser::kOk:
  163. curr_frame_hdr_ = std::move(hdr);
  164. curr_frame_size_ = allocate_size;
  165. break;
  166. case Vp9Parser::kEOStream:
  167. return kRanOutOfStreamData;
  168. case Vp9Parser::kInvalidStream:
  169. DVLOG(1) << "Error parsing stream";
  170. SetError();
  171. return kDecodeError;
  172. case Vp9Parser::kAwaitingRefresh:
  173. DVLOG(4) << "Awaiting context update";
  174. return kNeedContextUpdate;
  175. }
  176. }
  177. if (state_ != kDecoding) {
  178. // Not kDecoding, so we need a resume point (a keyframe), as we are after
  179. // reset or at the beginning of the stream. Drop anything that is not
  180. // a keyframe in such case, and continue looking for a keyframe.
  181. // Only exception is when the stream/sequence starts with an Intra only
  182. // frame.
  183. if (curr_frame_hdr_->IsKeyframe() ||
  184. (curr_frame_hdr_->IsIntra() && pic_size_.IsEmpty())) {
  185. state_ = kDecoding;
  186. } else {
  187. curr_frame_hdr_.reset();
  188. decrypt_config_.reset();
  189. continue;
  190. }
  191. }
  192. if (curr_frame_hdr_->show_existing_frame) {
  193. // This frame header only instructs us to display one of the
  194. // previously-decoded frames, but has no frame data otherwise. Display
  195. // and continue decoding subsequent frames.
  196. size_t frame_to_show = curr_frame_hdr_->frame_to_show_map_idx;
  197. if (frame_to_show >= kVp9NumRefFrames ||
  198. !ref_frames_.GetFrame(frame_to_show)) {
  199. DVLOG(1) << "Request to show an invalid frame";
  200. SetError();
  201. return kDecodeError;
  202. }
  203. // Duplicate the VP9Picture and set the current bitstream id to keep the
  204. // correct timestamp.
  205. scoped_refptr<VP9Picture> pic =
  206. ref_frames_.GetFrame(frame_to_show)->Duplicate();
  207. if (pic == nullptr) {
  208. DVLOG(1) << "Failed to duplicate the VP9Picture.";
  209. SetError();
  210. return kDecodeError;
  211. }
  212. pic->set_bitstream_id(stream_id_);
  213. if (!accelerator_->OutputPicture(std::move(pic))) {
  214. SetError();
  215. return kDecodeError;
  216. }
  217. curr_frame_hdr_.reset();
  218. decrypt_config_.reset();
  219. continue;
  220. }
  221. gfx::Size new_pic_size = curr_frame_size_;
  222. gfx::Rect new_render_rect(curr_frame_hdr_->render_width,
  223. curr_frame_hdr_->render_height);
  224. // For safety, check the validity of render size or leave it as pic size.
  225. if (!gfx::Rect(new_pic_size).Contains(new_render_rect)) {
  226. DVLOG(1) << "Render size exceeds picture size. render size: "
  227. << new_render_rect.ToString()
  228. << ", picture size: " << new_pic_size.ToString();
  229. new_render_rect = gfx::Rect(new_pic_size);
  230. }
  231. VideoCodecProfile new_profile =
  232. VP9ProfileToVideoCodecProfile(curr_frame_hdr_->profile);
  233. if (new_profile == VIDEO_CODEC_PROFILE_UNKNOWN) {
  234. VLOG(1) << "Invalid profile: " << curr_frame_hdr_->profile;
  235. return kDecodeError;
  236. }
  237. if (!IsValidBitDepth(curr_frame_hdr_->bit_depth, new_profile)) {
  238. DVLOG(1) << "Invalid bit depth="
  239. << base::strict_cast<int>(curr_frame_hdr_->bit_depth)
  240. << ", profile=" << GetProfileName(new_profile);
  241. return kDecodeError;
  242. }
  243. VideoChromaSampling new_chroma_sampling =
  244. GetVP9ChromaSampling(*curr_frame_hdr_);
  245. if (new_chroma_sampling != chroma_sampling_) {
  246. chroma_sampling_ = new_chroma_sampling;
  247. base::UmaHistogramEnumeration(
  248. "Media.PlatformVideoDecoding.ChromaSampling", chroma_sampling_);
  249. }
  250. if (chroma_sampling_ != VideoChromaSampling::k420) {
  251. DVLOG(1) << "Only YUV 4:2:0 is supported";
  252. return kDecodeError;
  253. }
  254. DCHECK(!new_pic_size.IsEmpty());
  255. if (new_pic_size != pic_size_ || new_profile != profile_ ||
  256. curr_frame_hdr_->bit_depth != bit_depth_) {
  257. DVLOG(1) << "New profile: " << GetProfileName(new_profile)
  258. << ", New resolution: " << new_pic_size.ToString()
  259. << ", New bit depth: "
  260. << base::strict_cast<int>(curr_frame_hdr_->bit_depth);
  261. if (!curr_frame_hdr_->IsKeyframe() &&
  262. !(curr_frame_hdr_->IsIntra() && pic_size_.IsEmpty())) {
  263. // TODO(posciak): This is doable, but requires a few modifications to
  264. // VDA implementations to allow multiple picture buffer sets in flight.
  265. // http://crbug.com/832264
  266. DVLOG(1) << "Resolution change currently supported for keyframes and "
  267. "sequence begins with Intra only when there is no prior "
  268. "frames in the context";
  269. if (++size_change_failure_counter_ > kVPxMaxNumOfSizeChangeFailures) {
  270. SetError();
  271. return kDecodeError;
  272. }
  273. curr_frame_hdr_.reset();
  274. decrypt_config_.reset();
  275. return kRanOutOfStreamData;
  276. }
  277. // TODO(posciak): This requires us to be on a keyframe (see above) and is
  278. // required, because VDA clients expect all surfaces to be returned before
  279. // they can cycle surface sets after receiving kConfigChange.
  280. // This is only an implementation detail of VDAs and can be improved.
  281. ref_frames_.Clear();
  282. pic_size_ = new_pic_size;
  283. visible_rect_ = new_render_rect;
  284. profile_ = new_profile;
  285. bit_depth_ = curr_frame_hdr_->bit_depth;
  286. size_change_failure_counter_ = 0;
  287. return kConfigChange;
  288. }
  289. scoped_refptr<VP9Picture> pic = accelerator_->CreateVP9Picture();
  290. if (!pic) {
  291. return kRanOutOfSurfaces;
  292. }
  293. DVLOG(2) << "Render resolution: " << new_render_rect.ToString();
  294. pic->set_visible_rect(new_render_rect);
  295. pic->set_bitstream_id(stream_id_);
  296. pic->set_decrypt_config(std::move(decrypt_config_));
  297. // For VP9, container color spaces override video stream color spaces.
  298. if (container_color_space_.IsSpecified())
  299. pic->set_colorspace(container_color_space_);
  300. else if (curr_frame_hdr_)
  301. pic->set_colorspace(curr_frame_hdr_->GetColorSpace());
  302. pic->frame_hdr = std::move(curr_frame_hdr_);
  303. VP9Accelerator::Status status = DecodeAndOutputPicture(std::move(pic));
  304. if (status == VP9Accelerator::Status::kFail) {
  305. SetError();
  306. return kDecodeError;
  307. }
  308. if (status == VP9Accelerator::Status::kTryAgain)
  309. return kTryAgain;
  310. }
  311. }
  312. void VP9Decoder::UpdateFrameContext(
  313. scoped_refptr<VP9Picture> pic,
  314. Vp9Parser::ContextRefreshCallback context_refresh_cb) {
  315. DCHECK(context_refresh_cb);
  316. Vp9FrameContext frame_ctx;
  317. memset(&frame_ctx, 0, sizeof(frame_ctx));
  318. if (!accelerator_->GetFrameContext(std::move(pic), &frame_ctx)) {
  319. SetError();
  320. return;
  321. }
  322. std::move(context_refresh_cb).Run(frame_ctx);
  323. }
  324. VP9Decoder::VP9Accelerator::Status VP9Decoder::DecodeAndOutputPicture(
  325. scoped_refptr<VP9Picture> pic) {
  326. DCHECK(!pic_size_.IsEmpty());
  327. DCHECK(pic->frame_hdr);
  328. base::OnceClosure done_cb;
  329. Vp9Parser::ContextRefreshCallback context_refresh_cb =
  330. parser_.GetContextRefreshCb(pic->frame_hdr->frame_context_idx);
  331. if (context_refresh_cb) {
  332. done_cb =
  333. base::BindOnce(&VP9Decoder::UpdateFrameContext, base::Unretained(this),
  334. pic, std::move(context_refresh_cb));
  335. }
  336. const Vp9Parser::Context& context = parser_.context();
  337. VP9Accelerator::Status status = accelerator_->SubmitDecode(
  338. pic, context.segmentation(), context.loop_filter(), ref_frames_,
  339. std::move(done_cb));
  340. if (status != VP9Accelerator::Status::kOk) {
  341. if (status == VP9Accelerator::Status::kTryAgain)
  342. pending_pic_ = std::move(pic);
  343. return status;
  344. }
  345. if (pic->frame_hdr->show_frame) {
  346. if (!accelerator_->OutputPicture(pic))
  347. return VP9Accelerator::Status::kFail;
  348. }
  349. ref_frames_.Refresh(std::move(pic));
  350. return status;
  351. }
  352. void VP9Decoder::SetError() {
  353. Reset();
  354. state_ = kError;
  355. }
  356. gfx::Size VP9Decoder::GetPicSize() const {
  357. return pic_size_;
  358. }
  359. gfx::Rect VP9Decoder::GetVisibleRect() const {
  360. return visible_rect_;
  361. }
  362. VideoCodecProfile VP9Decoder::GetProfile() const {
  363. return profile_;
  364. }
  365. uint8_t VP9Decoder::GetBitDepth() const {
  366. return bit_depth_;
  367. }
  368. VideoChromaSampling VP9Decoder::GetChromaSampling() const {
  369. return chroma_sampling_;
  370. }
  371. size_t VP9Decoder::GetRequiredNumOfPictures() const {
  372. constexpr size_t kPicsInPipeline = limits::kMaxVideoFrames + 1;
  373. return kPicsInPipeline + GetNumReferenceFrames();
  374. }
  375. size_t VP9Decoder::GetNumReferenceFrames() const {
  376. // Maximum number of reference frames
  377. return kVp9NumRefFrames;
  378. }
  379. } // namespace media