Coverage Report

Created: 2018-09-25 14:53

/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
}