Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit d9995b9

Browse files
author
Bryce Van Dyk
committed
Bug 1513042 - Update mp4parse-rust to v0.11.2. r=jya
Update mp4parse-rust update script and pull the new version. This update changes the mp4parse C-API. Specifically, each track can now have multiple sample descriptions. Previously we'd just exposed the first for the entire track, and if others were available they were not exposed via the API. Because of the API change, we update the C++ interface with mp4parse-rust. We now inspect the sample info to make sure they're consistent with the parsers expectations: - Only a single codec is present for a track, multiple codecs in a track will result in us returning an error. - Only 0 or 1 crypto info is present for a track, more than one set of info will result in us returning an error. We still generalize some of the first sample info to the samples of the track, as we did before this patch. However, we will now catch the above cases explicitly. We now handle crypto information if it is not present on the first sample info. The parser will iterate through sample infos and use the first set of crypto info it finds (and fail if it finds 2+). Differential Revision: https://phabricator.services.mozilla.com/D14107 --HG-- extra : moz-landing-system : lando
1 parent 0f41ddb commit d9995b9

13 files changed

Lines changed: 1037 additions & 420 deletions

File tree

Cargo.lock

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dom/media/mp4/DecoderData.cpp

Lines changed: 106 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -57,81 +57,150 @@ static void UpdateTrackProtectedInfo(mozilla::TrackInfo& aConfig,
5757
}
5858
}
5959

60-
void MP4AudioInfo::Update(const Mp4parseTrackInfo* track,
61-
const Mp4parseTrackAudioInfo* audio) {
62-
UpdateTrackProtectedInfo(*this, audio->protected_data);
60+
MediaResult MP4AudioInfo::Update(const Mp4parseTrackInfo* track,
61+
const Mp4parseTrackAudioInfo* audio) {
62+
MOZ_DIAGNOSTIC_ASSERT(audio->sample_info_count > 0,
63+
"Must have at least one audio sample info");
64+
if (audio->sample_info_count == 0) {
65+
return MediaResult(
66+
NS_ERROR_DOM_MEDIA_METADATA_ERR,
67+
RESULT_DETAIL("Got 0 audio sample info while updating audio track"));
68+
}
69+
70+
bool hasCrypto = false;
71+
Mp4parseCodec codecType = audio->sample_info[0].codec_type;
72+
for (uint32_t i = 0; i < audio->sample_info_count; i++) {
73+
if (audio->sample_info[0].codec_type != codecType) {
74+
// Different codecs in a single track. We don't handle this.
75+
return MediaResult(
76+
NS_ERROR_DOM_MEDIA_METADATA_ERR,
77+
RESULT_DETAIL(
78+
"Multiple codecs encountered while updating audio track"));
79+
}
6380

64-
if (track->codec == MP4PARSE_CODEC_OPUS) {
81+
// Update our encryption info if any is present on the sample info.
82+
if (audio->sample_info[i].protected_data.is_encrypted) {
83+
if (hasCrypto) {
84+
// Multiple crypto entries found. We don't handle this.
85+
return MediaResult(
86+
NS_ERROR_DOM_MEDIA_METADATA_ERR,
87+
RESULT_DETAIL(
88+
"Multiple crypto info encountered while updating audio track"));
89+
}
90+
UpdateTrackProtectedInfo(*this, audio->sample_info[i].protected_data);
91+
hasCrypto = true;
92+
}
93+
}
94+
95+
// We assume that the members of the first sample info are representative of
96+
// the entire track. This code will need to be updated should this assumption
97+
// ever not hold. E.g. if we need to handle different codecs in a single
98+
// track, or if we have different numbers or channels in a single track.
99+
Mp4parseByteData codecSpecificConfig =
100+
audio->sample_info[0].codec_specific_config;
101+
if (codecType == MP4PARSE_CODEC_OPUS) {
65102
mMimeType = NS_LITERAL_CSTRING("audio/opus");
66103
// The Opus decoder expects the container's codec delay or
67104
// pre-skip value, in microseconds, as a 64-bit int at the
68105
// start of the codec-specific config blob.
69-
if (audio->codec_specific_config.data &&
70-
audio->codec_specific_config.length >= 12) {
71-
uint16_t preskip = mozilla::LittleEndian::readUint16(
72-
audio->codec_specific_config.data + 10);
106+
if (codecSpecificConfig.data && codecSpecificConfig.length >= 12) {
107+
uint16_t preskip =
108+
mozilla::LittleEndian::readUint16(codecSpecificConfig.data + 10);
73109
mozilla::OpusDataDecoder::AppendCodecDelay(
74110
mCodecSpecificConfig, mozilla::FramesToUsecs(preskip, 48000).value());
75111
} else {
76112
// This file will error later as it will be rejected by the opus decoder.
77113
mozilla::OpusDataDecoder::AppendCodecDelay(mCodecSpecificConfig, 0);
78114
}
79-
} else if (track->codec == MP4PARSE_CODEC_AAC) {
115+
} else if (codecType == MP4PARSE_CODEC_AAC) {
80116
mMimeType = NS_LITERAL_CSTRING("audio/mp4a-latm");
81-
} else if (track->codec == MP4PARSE_CODEC_FLAC) {
117+
} else if (codecType == MP4PARSE_CODEC_FLAC) {
82118
mMimeType = NS_LITERAL_CSTRING("audio/flac");
83-
} else if (track->codec == MP4PARSE_CODEC_MP3) {
119+
} else if (codecType == MP4PARSE_CODEC_MP3) {
84120
mMimeType = NS_LITERAL_CSTRING("audio/mpeg");
85121
}
86122

87-
mRate = audio->sample_rate;
88-
mChannels = audio->channels;
89-
mBitDepth = audio->bit_depth;
90-
mExtendedProfile = audio->extended_profile;
123+
mRate = audio->sample_info[0].sample_rate;
124+
mChannels = audio->sample_info[0].channels;
125+
mBitDepth = audio->sample_info[0].bit_depth;
126+
mExtendedProfile = audio->sample_info[0].extended_profile;
91127
mDuration = TimeUnit::FromMicroseconds(track->duration);
92128
mMediaTime = TimeUnit::FromMicroseconds(track->media_time);
93129
mTrackId = track->track_id;
94130

95131
// In stagefright, mProfile is kKeyAACProfile, mExtendedProfile is kKeyAACAOT.
96-
if (audio->profile <= 4) {
97-
mProfile = audio->profile;
132+
if (audio->sample_info[0].profile <= 4) {
133+
mProfile = audio->sample_info[0].profile;
98134
}
99135

100-
if (audio->extra_data.length > 0) {
101-
mExtraData->AppendElements(audio->extra_data.data,
102-
audio->extra_data.length);
136+
Mp4parseByteData extraData = audio->sample_info[0].extra_data;
137+
// If length is 0 we append nothing
138+
mExtraData->AppendElements(extraData.data, extraData.length);
139+
mCodecSpecificConfig->AppendElements(codecSpecificConfig.data,
140+
codecSpecificConfig.length);
141+
return NS_OK;
142+
}
143+
144+
MediaResult MP4VideoInfo::Update(const Mp4parseTrackInfo* track,
145+
const Mp4parseTrackVideoInfo* video) {
146+
MOZ_DIAGNOSTIC_ASSERT(video->sample_info_count > 0,
147+
"Must have at least one video sample info");
148+
if (video->sample_info_count == 0) {
149+
return MediaResult(
150+
NS_ERROR_DOM_MEDIA_METADATA_ERR,
151+
RESULT_DETAIL("Got 0 audio sample info while updating video track"));
103152
}
104153

105-
if (audio->codec_specific_config.length > 0) {
106-
mCodecSpecificConfig->AppendElements(audio->codec_specific_config.data,
107-
audio->codec_specific_config.length);
154+
bool hasCrypto = false;
155+
Mp4parseCodec codecType = video->sample_info[0].codec_type;
156+
for (uint32_t i = 0; i < video->sample_info_count; i++) {
157+
if (video->sample_info[0].codec_type != codecType) {
158+
// Different codecs in a single track. We don't handle this.
159+
return MediaResult(
160+
NS_ERROR_DOM_MEDIA_METADATA_ERR,
161+
RESULT_DETAIL(
162+
"Multiple codecs encountered while updating video track"));
163+
}
164+
165+
// Update our encryption info if any is present on the sample info.
166+
if (video->sample_info[i].protected_data.is_encrypted) {
167+
if (hasCrypto) {
168+
// Multiple crypto entries found. We don't handle this.
169+
return MediaResult(
170+
NS_ERROR_DOM_MEDIA_METADATA_ERR,
171+
RESULT_DETAIL(
172+
"Multiple crypto info encountered while updating video track"));
173+
}
174+
UpdateTrackProtectedInfo(*this, video->sample_info[i].protected_data);
175+
hasCrypto = true;
176+
}
108177
}
109-
}
110178

111-
void MP4VideoInfo::Update(const Mp4parseTrackInfo* track,
112-
const Mp4parseTrackVideoInfo* video) {
113-
UpdateTrackProtectedInfo(*this, video->protected_data);
114-
if (track->codec == MP4PARSE_CODEC_AVC) {
179+
// We assume that the members of the first sample info are representative of
180+
// the entire track. This code will need to be updated should this assumption
181+
// ever not hold. E.g. if we need to handle different codecs in a single
182+
// track, or if we have different numbers or channels in a single track.
183+
if (codecType == MP4PARSE_CODEC_AVC) {
115184
mMimeType = NS_LITERAL_CSTRING("video/avc");
116-
} else if (track->codec == MP4PARSE_CODEC_VP9) {
185+
} else if (codecType == MP4PARSE_CODEC_VP9) {
117186
mMimeType = NS_LITERAL_CSTRING("video/vp9");
118-
} else if (track->codec == MP4PARSE_CODEC_AV1) {
187+
} else if (codecType == MP4PARSE_CODEC_AV1) {
119188
mMimeType = NS_LITERAL_CSTRING("video/av1");
120-
} else if (track->codec == MP4PARSE_CODEC_MP4V) {
189+
} else if (codecType == MP4PARSE_CODEC_MP4V) {
121190
mMimeType = NS_LITERAL_CSTRING("video/mp4v-es");
122191
}
123192
mTrackId = track->track_id;
124193
mDuration = TimeUnit::FromMicroseconds(track->duration);
125194
mMediaTime = TimeUnit::FromMicroseconds(track->media_time);
126195
mDisplay.width = video->display_width;
127196
mDisplay.height = video->display_height;
128-
mImage.width = video->image_width;
129-
mImage.height = video->image_height;
197+
mImage.width = video->sample_info[0].image_width;
198+
mImage.height = video->sample_info[0].image_height;
130199
mRotation = ToSupportedRotation(video->rotation);
131-
if (video->extra_data.data) {
132-
mExtraData->AppendElements(video->extra_data.data,
133-
video->extra_data.length);
134-
}
200+
Mp4parseByteData extraData = video->sample_info[0].extra_data;
201+
// If length is 0 we append nothing
202+
mExtraData->AppendElements(extraData.data, extraData.length);
203+
return NS_OK;
135204
}
136205

137206
bool MP4VideoInfo::IsValid() const {

dom/media/mp4/DecoderData.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define DECODER_DATA_H_
77

88
#include "MediaInfo.h"
9+
#include "MediaResult.h"
910
#include "mozilla/RefPtr.h"
1011
#include "mozilla/Result.h"
1112
#include "mozilla/Types.h"
@@ -53,8 +54,8 @@ class MP4AudioInfo : public mozilla::AudioInfo {
5354
public:
5455
MP4AudioInfo() = default;
5556

56-
void Update(const Mp4parseTrackInfo* track,
57-
const Mp4parseTrackAudioInfo* audio);
57+
MediaResult Update(const Mp4parseTrackInfo* track,
58+
const Mp4parseTrackAudioInfo* audio);
5859

5960
virtual bool IsValid() const override;
6061
};
@@ -63,8 +64,8 @@ class MP4VideoInfo : public mozilla::VideoInfo {
6364
public:
6465
MP4VideoInfo() = default;
6566

66-
void Update(const Mp4parseTrackInfo* track,
67-
const Mp4parseTrackVideoInfo* video);
67+
MediaResult Update(const Mp4parseTrackInfo* track,
68+
const Mp4parseTrackVideoInfo* video);
6869

6970
virtual bool IsValid() const override;
7071
};

0 commit comments

Comments
 (0)