/src/mozilla-central/dom/media/mp4/DecoderData.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
2 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
3 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 | | |
5 | | #include "Adts.h" |
6 | | #include "AnnexB.h" |
7 | | #include "BufferReader.h" |
8 | | #include "DecoderData.h" |
9 | | #include "mozilla/ArrayUtils.h" |
10 | | #include "mozilla/EndianUtils.h" |
11 | | #include "VideoUtils.h" |
12 | | |
13 | | // OpusDecoder header is really needed only by MP4 in rust |
14 | | #include "OpusDecoder.h" |
15 | | #include "mp4parse.h" |
16 | | |
17 | | using mozilla::media::TimeUnit; |
18 | | |
19 | | namespace mozilla |
20 | | { |
21 | | |
22 | | mozilla::Result<mozilla::Ok, nsresult> |
23 | | CryptoFile::DoUpdate(const uint8_t* aData, size_t aLength) |
24 | 0 | { |
25 | 0 | BufferReader reader(aData, aLength); |
26 | 0 | while (reader.Remaining()) { |
27 | 0 | PsshInfo psshInfo; |
28 | 0 | if (!reader.ReadArray(psshInfo.uuid, 16)) { |
29 | 0 | return mozilla::Err(NS_ERROR_FAILURE); |
30 | 0 | } |
31 | 0 | |
32 | 0 | if (!reader.CanReadType<uint32_t>()) { |
33 | 0 | return mozilla::Err(NS_ERROR_FAILURE); |
34 | 0 | } |
35 | 0 | auto length = reader.ReadType<uint32_t>(); |
36 | 0 |
|
37 | 0 | if (!reader.ReadArray(psshInfo.data, length)) { |
38 | 0 | return mozilla::Err(NS_ERROR_FAILURE); |
39 | 0 | } |
40 | 0 | pssh.AppendElement(psshInfo); |
41 | 0 | } |
42 | 0 | return mozilla::Ok(); |
43 | 0 | } |
44 | | |
45 | | bool |
46 | | MP4AudioInfo::IsValid() const |
47 | 0 | { |
48 | 0 | return mChannels > 0 && mRate > 0 && |
49 | 0 | // Accept any mime type here, but if it's aac, validate the profile. |
50 | 0 | (!mMimeType.EqualsLiteral("audio/mp4a-latm") || |
51 | 0 | mProfile > 0 || mExtendedProfile > 0); |
52 | 0 | } |
53 | | |
54 | | static void |
55 | | UpdateTrackProtectedInfo(mozilla::TrackInfo& aConfig, |
56 | | const Mp4parseSinfInfo& aSinf) |
57 | 0 | { |
58 | 0 | if (aSinf.is_encrypted != 0) { |
59 | 0 | aConfig.mCrypto.mValid = true; |
60 | 0 | aConfig.mCrypto.mMode = aSinf.is_encrypted; |
61 | 0 | aConfig.mCrypto.mIVSize = aSinf.iv_size; |
62 | 0 | aConfig.mCrypto.mKeyId.AppendElements(aSinf.kid.data, aSinf.kid.length); |
63 | 0 | } |
64 | 0 | } |
65 | | |
66 | | void |
67 | | MP4AudioInfo::Update(const Mp4parseTrackInfo* track, |
68 | | const Mp4parseTrackAudioInfo* audio) |
69 | 0 | { |
70 | 0 | UpdateTrackProtectedInfo(*this, audio->protected_data); |
71 | 0 |
|
72 | 0 | if (track->codec == MP4PARSE_CODEC_OPUS) { |
73 | 0 | mMimeType = NS_LITERAL_CSTRING("audio/opus"); |
74 | 0 | // The Opus decoder expects the container's codec delay or |
75 | 0 | // pre-skip value, in microseconds, as a 64-bit int at the |
76 | 0 | // start of the codec-specific config blob. |
77 | 0 | if (audio->codec_specific_config.data && |
78 | 0 | audio->codec_specific_config.length >= 12) { |
79 | 0 | uint16_t preskip = mozilla::LittleEndian::readUint16( |
80 | 0 | audio->codec_specific_config.data + 10); |
81 | 0 | mozilla::OpusDataDecoder::AppendCodecDelay( |
82 | 0 | mCodecSpecificConfig, mozilla::FramesToUsecs(preskip, 48000).value()); |
83 | 0 | } else { |
84 | 0 | // This file will error later as it will be rejected by the opus decoder. |
85 | 0 | mozilla::OpusDataDecoder::AppendCodecDelay(mCodecSpecificConfig, 0); |
86 | 0 | } |
87 | 0 | } else if (track->codec == MP4PARSE_CODEC_AAC) { |
88 | 0 | mMimeType = NS_LITERAL_CSTRING("audio/mp4a-latm"); |
89 | 0 | } else if (track->codec == MP4PARSE_CODEC_FLAC) { |
90 | 0 | mMimeType = NS_LITERAL_CSTRING("audio/flac"); |
91 | 0 | } else if (track->codec == MP4PARSE_CODEC_MP3) { |
92 | 0 | mMimeType = NS_LITERAL_CSTRING("audio/mpeg"); |
93 | 0 | } |
94 | 0 |
|
95 | 0 | mRate = audio->sample_rate; |
96 | 0 | mChannels = audio->channels; |
97 | 0 | mBitDepth = audio->bit_depth; |
98 | 0 | mExtendedProfile = audio->profile; |
99 | 0 | mDuration = TimeUnit::FromMicroseconds(track->duration); |
100 | 0 | mMediaTime = TimeUnit::FromMicroseconds(track->media_time); |
101 | 0 | mTrackId = track->track_id; |
102 | 0 |
|
103 | 0 | // In stagefright, mProfile is kKeyAACProfile, mExtendedProfile is kKeyAACAOT. |
104 | 0 | // Both are from audioObjectType in AudioSpecificConfig. |
105 | 0 | if (audio->profile <= 4) { |
106 | 0 | mProfile = audio->profile; |
107 | 0 | } |
108 | 0 |
|
109 | 0 | if (audio->extra_data.length > 0) { |
110 | 0 | mExtraData->AppendElements(audio->extra_data.data, |
111 | 0 | audio->extra_data.length); |
112 | 0 | } |
113 | 0 |
|
114 | 0 | if (audio->codec_specific_config.length > 0) { |
115 | 0 | mCodecSpecificConfig->AppendElements(audio->codec_specific_config.data, |
116 | 0 | audio->codec_specific_config.length); |
117 | 0 | } |
118 | 0 | } |
119 | | |
120 | | void |
121 | | MP4VideoInfo::Update(const Mp4parseTrackInfo* track, |
122 | | const Mp4parseTrackVideoInfo* video) |
123 | 0 | { |
124 | 0 | UpdateTrackProtectedInfo(*this, video->protected_data); |
125 | 0 | if (track->codec == MP4PARSE_CODEC_AVC) { |
126 | 0 | mMimeType = NS_LITERAL_CSTRING("video/avc"); |
127 | 0 | } else if (track->codec == MP4PARSE_CODEC_VP9) { |
128 | 0 | mMimeType = NS_LITERAL_CSTRING("video/vp9"); |
129 | 0 | } else if (track->codec == MP4PARSE_CODEC_AV1) { |
130 | 0 | mMimeType = NS_LITERAL_CSTRING("video/av1"); |
131 | 0 | } else if (track->codec == MP4PARSE_CODEC_MP4V) { |
132 | 0 | mMimeType = NS_LITERAL_CSTRING("video/mp4v-es"); |
133 | 0 | } |
134 | 0 | mTrackId = track->track_id; |
135 | 0 | mDuration = TimeUnit::FromMicroseconds(track->duration); |
136 | 0 | mMediaTime = TimeUnit::FromMicroseconds(track->media_time); |
137 | 0 | mDisplay.width = video->display_width; |
138 | 0 | mDisplay.height = video->display_height; |
139 | 0 | mImage.width = video->image_width; |
140 | 0 | mImage.height = video->image_height; |
141 | 0 | mRotation = ToSupportedRotation(video->rotation); |
142 | 0 | if (video->extra_data.data) { |
143 | 0 | mExtraData->AppendElements(video->extra_data.data, video->extra_data.length); |
144 | 0 | } |
145 | 0 | } |
146 | | |
147 | | bool |
148 | | MP4VideoInfo::IsValid() const |
149 | 0 | { |
150 | 0 | return (mDisplay.width > 0 && mDisplay.height > 0) || |
151 | 0 | (mImage.width > 0 && mImage.height > 0); |
152 | 0 | } |
153 | | |
154 | | } |