Line data Source code
1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #include "ChromiumCDMVideoDecoder.h"
8 : #include "ChromiumCDMProxy.h"
9 : #include "content_decryption_module.h"
10 : #include "GMPService.h"
11 : #include "GMPVideoDecoder.h"
12 : #include "MP4Decoder.h"
13 : #include "VPXDecoder.h"
14 :
15 : namespace mozilla {
16 :
17 0 : ChromiumCDMVideoDecoder::ChromiumCDMVideoDecoder(
18 : const GMPVideoDecoderParams& aParams,
19 0 : CDMProxy* aCDMProxy)
20 0 : : mCDMParent(aCDMProxy->AsChromiumCDMProxy()->GetCDMParent())
21 : , mConfig(aParams.mConfig)
22 : , mCrashHelper(aParams.mCrashHelper)
23 : , mGMPThread(GetGMPAbstractThread())
24 0 : , mImageContainer(aParams.mImageContainer)
25 : {
26 0 : }
27 :
28 0 : ChromiumCDMVideoDecoder::~ChromiumCDMVideoDecoder()
29 : {
30 0 : }
31 :
32 : static uint32_t
33 0 : ToCDMH264Profile(uint8_t aProfile)
34 : {
35 0 : switch (aProfile) {
36 : case 66:
37 0 : return cdm::VideoDecoderConfig::kH264ProfileBaseline;
38 : case 77:
39 0 : return cdm::VideoDecoderConfig::kH264ProfileMain;
40 : case 88:
41 0 : return cdm::VideoDecoderConfig::kH264ProfileExtended;
42 : case 100:
43 0 : return cdm::VideoDecoderConfig::kH264ProfileHigh;
44 : case 110:
45 0 : return cdm::VideoDecoderConfig::kH264ProfileHigh10;
46 : case 122:
47 0 : return cdm::VideoDecoderConfig::kH264ProfileHigh422;
48 : case 144:
49 0 : return cdm::VideoDecoderConfig::kH264ProfileHigh444Predictive;
50 : }
51 0 : return cdm::VideoDecoderConfig::kUnknownVideoCodecProfile;
52 : }
53 :
54 : RefPtr<MediaDataDecoder::InitPromise>
55 0 : ChromiumCDMVideoDecoder::Init()
56 : {
57 0 : if (!mCDMParent) {
58 : // Must have failed to get the CDMParent from the ChromiumCDMProxy
59 : // in our constructor; the MediaKeys must have shut down the CDM
60 : // before we had a chance to start up the decoder.
61 : return InitPromise::CreateAndReject(
62 0 : NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
63 : }
64 :
65 0 : gmp::CDMVideoDecoderConfig config;
66 0 : if (MP4Decoder::IsH264(mConfig.mMimeType)) {
67 0 : config.mCodec() = cdm::VideoDecoderConfig::kCodecH264;
68 0 : config.mProfile() =
69 0 : ToCDMH264Profile(mConfig.mExtraData->SafeElementAt(1, 0));
70 0 : config.mExtraData() = *mConfig.mExtraData;
71 0 : mConvertToAnnexB = true;
72 0 : } else if (VPXDecoder::IsVP8(mConfig.mMimeType)) {
73 0 : config.mCodec() = cdm::VideoDecoderConfig::kCodecVp8;
74 0 : config.mProfile() = cdm::VideoDecoderConfig::kProfileNotNeeded;
75 0 : } else if (VPXDecoder::IsVP9(mConfig.mMimeType)) {
76 0 : config.mCodec() = cdm::VideoDecoderConfig::kCodecVp9;
77 0 : config.mProfile() = cdm::VideoDecoderConfig::kProfileNotNeeded;
78 : } else {
79 : return MediaDataDecoder::InitPromise::CreateAndReject(
80 0 : NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
81 : }
82 0 : config.mImageWidth() = mConfig.mImage.width;
83 0 : config.mImageHeight() = mConfig.mImage.height;
84 :
85 0 : RefPtr<gmp::ChromiumCDMParent> cdm = mCDMParent;
86 0 : VideoInfo info = mConfig;
87 0 : RefPtr<layers::ImageContainer> imageContainer = mImageContainer;
88 : return InvokeAsync(
89 0 : mGMPThread, __func__, [cdm, config, info, imageContainer]() {
90 : return cdm->InitializeVideoDecoder(config, info, imageContainer);
91 0 : });
92 : }
93 :
94 : const char*
95 0 : ChromiumCDMVideoDecoder::GetDescriptionName() const
96 : {
97 0 : return "Chromium CDM video decoder";
98 : }
99 :
100 : MediaDataDecoder::ConversionRequired
101 0 : ChromiumCDMVideoDecoder::NeedsConversion() const
102 : {
103 0 : return mConvertToAnnexB ? ConversionRequired::kNeedAnnexB
104 0 : : ConversionRequired::kNeedNone;
105 : }
106 :
107 : RefPtr<MediaDataDecoder::DecodePromise>
108 0 : ChromiumCDMVideoDecoder::Decode(MediaRawData* aSample)
109 : {
110 0 : RefPtr<gmp::ChromiumCDMParent> cdm = mCDMParent;
111 0 : RefPtr<MediaRawData> sample = aSample;
112 0 : return InvokeAsync(mGMPThread, __func__, [cdm, sample]() {
113 : return cdm->DecryptAndDecodeFrame(sample);
114 0 : });
115 : }
116 :
117 : RefPtr<MediaDataDecoder::FlushPromise>
118 0 : ChromiumCDMVideoDecoder::Flush()
119 : {
120 0 : MOZ_ASSERT(mCDMParent);
121 0 : RefPtr<gmp::ChromiumCDMParent> cdm = mCDMParent;
122 : return InvokeAsync(
123 0 : mGMPThread, __func__, [cdm]() { return cdm->FlushVideoDecoder(); });
124 : }
125 :
126 : RefPtr<MediaDataDecoder::DecodePromise>
127 0 : ChromiumCDMVideoDecoder::Drain()
128 : {
129 0 : MOZ_ASSERT(mCDMParent);
130 0 : RefPtr<gmp::ChromiumCDMParent> cdm = mCDMParent;
131 0 : return InvokeAsync(mGMPThread, __func__, [cdm]() { return cdm->Drain(); });
132 : }
133 :
134 : RefPtr<ShutdownPromise>
135 0 : ChromiumCDMVideoDecoder::Shutdown()
136 : {
137 0 : if (!mCDMParent) {
138 : // Must have failed to get the CDMParent from the ChromiumCDMProxy
139 : // in our constructor; the MediaKeys must have shut down the CDM
140 : // before we had a chance to start up the decoder.
141 0 : return ShutdownPromise::CreateAndResolve(true, __func__);
142 : }
143 0 : RefPtr<gmp::ChromiumCDMParent> cdm = mCDMParent;
144 : return InvokeAsync(
145 0 : mGMPThread, __func__, [cdm]() { return cdm->ShutdownVideoDecoder(); });
146 : }
147 :
148 : } // namespace mozilla
|