LCOV - code coverage report
Current view: top level - media/libstagefright/binding - DecoderData.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 129 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 13 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 "mp4_demuxer/Adts.h"
       6             : #include "mp4_demuxer/AnnexB.h"
       7             : #include "mp4_demuxer/ByteReader.h"
       8             : #include "mp4_demuxer/DecoderData.h"
       9             : #include <media/stagefright/foundation/ABitReader.h>
      10             : #include "media/stagefright/MetaData.h"
      11             : #include "media/stagefright/MediaDefs.h"
      12             : #include "media/stagefright/Utils.h"
      13             : #include "mozilla/ArrayUtils.h"
      14             : #include "include/ESDS.h"
      15             : 
      16             : // OpusDecoder header is really needed only by MP4 in rust
      17             : #include "OpusDecoder.h"
      18             : #include "mp4parse.h"
      19             : 
      20             : using namespace stagefright;
      21             : using mozilla::media::TimeUnit;
      22             : 
      23             : namespace mp4_demuxer
      24             : {
      25             : 
      26             : static int32_t
      27           0 : FindInt32(const MetaData* mMetaData, uint32_t mKey)
      28             : {
      29             :   int32_t value;
      30           0 :   if (!mMetaData->findInt32(mKey, &value))
      31           0 :     return 0;
      32           0 :   return value;
      33             : }
      34             : 
      35             : static int64_t
      36           0 : FindInt64(const MetaData* mMetaData, uint32_t mKey)
      37             : {
      38             :   int64_t value;
      39           0 :   if (!mMetaData->findInt64(mKey, &value))
      40           0 :     return 0;
      41           0 :   return value;
      42             : }
      43             : 
      44             : template <typename T, size_t N>
      45             : static bool
      46             : FindData(const MetaData* aMetaData, uint32_t aKey, mozilla::Vector<T, N>* aDest)
      47             : {
      48             :   const void* data;
      49             :   size_t size;
      50             :   uint32_t type;
      51             : 
      52             :   aDest->clear();
      53             :   // There's no point in checking that the type matches anything because it
      54             :   // isn't set consistently in the MPEG4Extractor.
      55             :   if (!aMetaData->findData(aKey, &type, &data, &size) || size % sizeof(T)) {
      56             :     return false;
      57             :   }
      58             : 
      59             :   aDest->append(reinterpret_cast<const T*>(data), size / sizeof(T));
      60             :   return true;
      61             : }
      62             : 
      63             : template <typename T>
      64             : static bool
      65           0 : FindData(const MetaData* aMetaData, uint32_t aKey, nsTArray<T>* aDest)
      66             : {
      67             :   const void* data;
      68             :   size_t size;
      69             :   uint32_t type;
      70             : 
      71           0 :   aDest->Clear();
      72             :   // There's no point in checking that the type matches anything because it
      73             :   // isn't set consistently in the MPEG4Extractor.
      74           0 :   if (!aMetaData->findData(aKey, &type, &data, &size) || size % sizeof(T)) {
      75           0 :     return false;
      76             :   }
      77             : 
      78           0 :   aDest->AppendElements(reinterpret_cast<const T*>(data), size / sizeof(T));
      79           0 :   return true;
      80             : }
      81             : 
      82             : static bool
      83           0 : FindData(const MetaData* aMetaData, uint32_t aKey, mozilla::MediaByteBuffer* aDest)
      84             : {
      85           0 :   return FindData(aMetaData, aKey, static_cast<nsTArray<uint8_t>*>(aDest));
      86             : }
      87             : 
      88             : bool
      89           0 : CryptoFile::DoUpdate(const uint8_t* aData, size_t aLength)
      90             : {
      91           0 :   ByteReader reader(aData, aLength);
      92           0 :   while (reader.Remaining()) {
      93           0 :     PsshInfo psshInfo;
      94           0 :     if (!reader.ReadArray(psshInfo.uuid, 16)) {
      95           0 :       return false;
      96             :     }
      97             : 
      98           0 :     if (!reader.CanReadType<uint32_t>()) {
      99           0 :       return false;
     100             :     }
     101           0 :     auto length = reader.ReadType<uint32_t>();
     102             : 
     103           0 :     if (!reader.ReadArray(psshInfo.data, length)) {
     104           0 :       return false;
     105             :     }
     106           0 :     pssh.AppendElement(psshInfo);
     107             :   }
     108           0 :   return true;
     109             : }
     110             : 
     111             : static void
     112           0 : UpdateTrackInfo(mozilla::TrackInfo& aConfig,
     113             :                 const MetaData* aMetaData,
     114             :                 const char* aMimeType)
     115             : {
     116           0 :   mozilla::CryptoTrack& crypto = aConfig.mCrypto;
     117           0 :   aConfig.mMimeType = aMimeType;
     118             :   aConfig.mDuration = TimeUnit::FromMicroseconds(
     119           0 :     FindInt64(aMetaData, kKeyDuration));
     120             :   aConfig.mMediaTime = TimeUnit::FromMicroseconds(
     121           0 :     FindInt64(aMetaData, kKeyMediaTime));
     122           0 :   aConfig.mTrackId = FindInt32(aMetaData, kKeyTrackID);
     123           0 :   aConfig.mCrypto.mValid = aMetaData->findInt32(kKeyCryptoMode, &crypto.mMode) &&
     124           0 :     aMetaData->findInt32(kKeyCryptoDefaultIVSize, &crypto.mIVSize) &&
     125           0 :     FindData(aMetaData, kKeyCryptoKey, &crypto.mKeyId);
     126           0 : }
     127             : 
     128             : void
     129           0 : MP4AudioInfo::Update(const MetaData* aMetaData,
     130             :                      const char* aMimeType)
     131             : {
     132           0 :   UpdateTrackInfo(*this, aMetaData, aMimeType);
     133           0 :   mChannels = FindInt32(aMetaData, kKeyChannelCount);
     134           0 :   mBitDepth = FindInt32(aMetaData, kKeySampleSize);
     135           0 :   mRate = FindInt32(aMetaData, kKeySampleRate);
     136           0 :   mProfile = FindInt32(aMetaData, kKeyAACProfile);
     137             : 
     138           0 :   if (FindData(aMetaData, kKeyESDS, mExtraData)) {
     139           0 :     ESDS esds(mExtraData->Elements(), mExtraData->Length());
     140             : 
     141             :     const void* data;
     142             :     size_t size;
     143           0 :     if (esds.getCodecSpecificInfo(&data, &size) == OK) {
     144           0 :       const uint8_t* cdata = reinterpret_cast<const uint8_t*>(data);
     145           0 :       mCodecSpecificConfig->AppendElements(cdata, size);
     146           0 :       if (size > 1) {
     147           0 :         ABitReader br(cdata, size);
     148           0 :         mExtendedProfile = br.getBits(5);
     149             : 
     150           0 :         if (mExtendedProfile == 31) {  // AAC-ELD => additional 6 bits
     151           0 :           mExtendedProfile = 32 + br.getBits(6);
     152             :         }
     153             :       }
     154             :     }
     155             :   }
     156           0 : }
     157             : 
     158             : bool
     159           0 : MP4AudioInfo::IsValid() const
     160             : {
     161           0 :   return mChannels > 0 && mRate > 0 &&
     162             :          // Accept any mime type here, but if it's aac, validate the profile.
     163           0 :          (!mMimeType.Equals(MEDIA_MIMETYPE_AUDIO_AAC) ||
     164           0 :           mProfile > 0 || mExtendedProfile > 0);
     165             : }
     166             : 
     167             : void
     168           0 : MP4VideoInfo::Update(const MetaData* aMetaData, const char* aMimeType)
     169             : {
     170           0 :   UpdateTrackInfo(*this, aMetaData, aMimeType);
     171           0 :   mDisplay.width = FindInt32(aMetaData, kKeyDisplayWidth);
     172           0 :   mDisplay.height = FindInt32(aMetaData, kKeyDisplayHeight);
     173           0 :   mImage.width = FindInt32(aMetaData, kKeyWidth);
     174           0 :   mImage.height = FindInt32(aMetaData, kKeyHeight);
     175           0 :   mRotation = VideoInfo::ToSupportedRotation(FindInt32(aMetaData, kKeyRotation));
     176             : 
     177           0 :   FindData(aMetaData, kKeyAVCC, mExtraData);
     178           0 : }
     179             : 
     180             : static void
     181           0 : UpdateTrackProtectedInfo(mozilla::TrackInfo& aConfig,
     182             :                          const mp4parse_sinf_info& aSinf)
     183             : {
     184           0 :   if (aSinf.is_encrypted != 0) {
     185           0 :     aConfig.mCrypto.mValid = true;
     186           0 :     aConfig.mCrypto.mMode = aSinf.is_encrypted;
     187           0 :     aConfig.mCrypto.mIVSize = aSinf.iv_size;
     188           0 :     aConfig.mCrypto.mKeyId.AppendElements(aSinf.kid.data, aSinf.kid.length);
     189             :   }
     190           0 : }
     191             : 
     192             : void
     193           0 : MP4AudioInfo::Update(const mp4parse_track_info* track,
     194             :                      const mp4parse_track_audio_info* audio)
     195             : {
     196           0 :   UpdateTrackProtectedInfo(*this, audio->protected_data);
     197             : 
     198           0 :   if (track->codec == mp4parse_codec_OPUS) {
     199           0 :     mMimeType = NS_LITERAL_CSTRING("audio/opus");
     200             :     // The Opus decoder expects the container's codec delay or
     201             :     // pre-skip value, in microseconds, as a 64-bit int at the
     202             :     // start of the codec-specific config blob.
     203           0 :     MOZ_ASSERT(audio->extra_data.data);
     204           0 :     MOZ_ASSERT(audio->extra_data.length >= 12);
     205             :     uint16_t preskip =
     206           0 :       LittleEndian::readUint16(audio->extra_data.data + 10);
     207           0 :     OpusDataDecoder::AppendCodecDelay(mCodecSpecificConfig,
     208           0 :         mozilla::FramesToUsecs(preskip, 48000).value());
     209           0 :   } else if (track->codec == mp4parse_codec_AAC) {
     210           0 :     mMimeType = MEDIA_MIMETYPE_AUDIO_AAC;
     211           0 :   } else if (track->codec == mp4parse_codec_FLAC) {
     212           0 :     mMimeType = MEDIA_MIMETYPE_AUDIO_FLAC;
     213           0 :   } else if (track->codec == mp4parse_codec_MP3) {
     214           0 :     mMimeType = MEDIA_MIMETYPE_AUDIO_MPEG;
     215             :   }
     216             : 
     217           0 :   mRate = audio->sample_rate;
     218           0 :   mChannels = audio->channels;
     219           0 :   mBitDepth = audio->bit_depth;
     220           0 :   mExtendedProfile = audio->profile;
     221           0 :   mDuration = TimeUnit::FromMicroseconds(track->duration);
     222           0 :   mMediaTime = TimeUnit::FromMicroseconds(track->media_time);
     223           0 :   mTrackId = track->track_id;
     224             : 
     225             :   // In stagefright, mProfile is kKeyAACProfile, mExtendedProfile is kKeyAACAOT.
     226             :   // Both are from audioObjectType in AudioSpecificConfig.
     227           0 :   if (audio->profile <= 4) {
     228           0 :     mProfile = audio->profile;
     229             :   }
     230             : 
     231           0 :   if (audio->extra_data.length > 0) {
     232           0 :     mExtraData->AppendElements(audio->extra_data.data,
     233           0 :                                audio->extra_data.length);
     234             :   }
     235             : 
     236           0 :   if (audio->codec_specific_config.length > 0) {
     237           0 :     mCodecSpecificConfig->AppendElements(audio->codec_specific_config.data,
     238           0 :                                          audio->codec_specific_config.length);
     239             :   }
     240           0 : }
     241             : 
     242             : void
     243           0 : MP4VideoInfo::Update(const mp4parse_track_info* track,
     244             :                      const mp4parse_track_video_info* video)
     245             : {
     246           0 :   UpdateTrackProtectedInfo(*this, video->protected_data);
     247           0 :   if (track->codec == mp4parse_codec_AVC) {
     248           0 :     mMimeType = MEDIA_MIMETYPE_VIDEO_AVC;
     249           0 :   } else if (track->codec == mp4parse_codec_VP9) {
     250           0 :     mMimeType = NS_LITERAL_CSTRING("video/vp9");
     251           0 :   } else if (track->codec == mp4parse_codec_MP4V) {
     252           0 :     mMimeType = MEDIA_MIMETYPE_VIDEO_MPEG4;
     253             :   }
     254           0 :   mTrackId = track->track_id;
     255           0 :   mDuration = TimeUnit::FromMicroseconds(track->duration);
     256           0 :   mMediaTime = TimeUnit::FromMicroseconds(track->media_time);
     257           0 :   mDisplay.width = video->display_width;
     258           0 :   mDisplay.height = video->display_height;
     259           0 :   mImage.width = video->image_width;
     260           0 :   mImage.height = video->image_height;
     261           0 :   mRotation = ToSupportedRotation(video->rotation);
     262           0 :   if (video->extra_data.data) {
     263           0 :     mExtraData->AppendElements(video->extra_data.data, video->extra_data.length);
     264             :   }
     265           0 : }
     266             : 
     267             : bool
     268           0 : MP4VideoInfo::IsValid() const
     269             : {
     270           0 :   return (mDisplay.width > 0 && mDisplay.height > 0) ||
     271           0 :     (mImage.width > 0 && mImage.height > 0);
     272             : }
     273             : 
     274             : }

Generated by: LCOV version 1.13