diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp index ab0cb924a3..23222d0ffa 100644 --- a/dom/html/HTMLMediaElement.cpp +++ b/dom/html/HTMLMediaElement.cpp @@ -1874,11 +1874,11 @@ HTMLMediaElement::CaptureStreamInternal(bool aFinishWhenEnded) if (mReadyState >= HAVE_METADATA) { // Expose the tracks to JS directly. if (HasAudio()) { - TrackID audioTrackId = mMediaInfo.mAudio.mTrackInfo.mOutputId; + TrackID audioTrackId = mMediaInfo.mAudio.mTrackId; out->mStream->CreateDOMTrack(audioTrackId, MediaSegment::AUDIO); } if (HasVideo()) { - TrackID videoTrackId = mMediaInfo.mVideo.mTrackInfo.mOutputId; + TrackID videoTrackId = mMediaInfo.mVideo.mTrackId; out->mStream->CreateDOMTrack(videoTrackId, MediaSegment::VIDEO); } } @@ -3172,11 +3172,11 @@ void HTMLMediaElement::MetadataLoaded(const MediaInfo* aInfo, // Expose the tracks to JS directly. for (OutputMediaStream& out : mOutputStreams) { if (aInfo->HasAudio()) { - TrackID audioTrackId = aInfo->mAudio.mTrackInfo.mOutputId; + TrackID audioTrackId = aInfo->mAudio.mTrackId; out.mStream->CreateDOMTrack(audioTrackId, MediaSegment::AUDIO); } if (aInfo->HasVideo()) { - TrackID videoTrackId = aInfo->mVideo.mTrackInfo.mOutputId; + TrackID videoTrackId = aInfo->mVideo.mTrackId; out.mStream->CreateDOMTrack(videoTrackId, MediaSegment::VIDEO); } } diff --git a/dom/media/MediaDecoder.cpp b/dom/media/MediaDecoder.cpp index 239df3bb3e..3694c88f25 100644 --- a/dom/media/MediaDecoder.cpp +++ b/dom/media/MediaDecoder.cpp @@ -1908,7 +1908,7 @@ MediaDecoder::ConstructMediaTracks() AudioTrackList* audioList = element->AudioTracks(); if (audioList && mInfo->HasAudio()) { - TrackInfo info = mInfo->mAudio.mTrackInfo; + const TrackInfo& info = mInfo->mAudio; nsRefPtr track = MediaTrackList::CreateAudioTrack( info.mId, info.mKind, info.mLabel, info.mLanguage, info.mEnabled); @@ -1917,7 +1917,7 @@ MediaDecoder::ConstructMediaTracks() VideoTrackList* videoList = element->VideoTracks(); if (videoList && mInfo->HasVideo()) { - TrackInfo info = mInfo->mVideo.mTrackInfo; + const TrackInfo& info = mInfo->mVideo; nsRefPtr track = MediaTrackList::CreateVideoTrack( info.mId, info.mKind, info.mLabel, info.mLanguage); diff --git a/dom/media/MediaDecoderStateMachine.cpp b/dom/media/MediaDecoderStateMachine.cpp index 3659782443..4009f1fad9 100644 --- a/dom/media/MediaDecoderStateMachine.cpp +++ b/dom/media/MediaDecoderStateMachine.cpp @@ -410,7 +410,7 @@ void MediaDecoderStateMachine::SendStreamData() if (!stream->mStreamInitialized) { if (mInfo.HasAudio()) { - TrackID audioTrackId = mInfo.mAudio.mTrackInfo.mOutputId; + TrackID audioTrackId = mInfo.mAudio.mTrackId; AudioSegment* audio = new AudioSegment(); mediaStream->AddAudioTrack(audioTrackId, mInfo.mAudio.mRate, 0, audio, SourceMediaStream::ADDTRACK_QUEUED); @@ -419,7 +419,7 @@ void MediaDecoderStateMachine::SendStreamData() stream->mNextAudioTime = mStartTime + stream->mInitialTime; } if (mInfo.HasVideo()) { - TrackID videoTrackId = mInfo.mVideo.mTrackInfo.mOutputId; + TrackID videoTrackId = mInfo.mVideo.mTrackId; VideoSegment* video = new VideoSegment(); mediaStream->AddTrack(videoTrackId, 0, video, SourceMediaStream::ADDTRACK_QUEUED); @@ -438,7 +438,7 @@ void MediaDecoderStateMachine::SendStreamData() if (mInfo.HasAudio()) { MOZ_ASSERT(stream->mNextAudioTime != -1, "Should've been initialized"); - TrackID audioTrackId = mInfo.mAudio.mTrackInfo.mOutputId; + TrackID audioTrackId = mInfo.mAudio.mTrackId; nsAutoTArray,10> audio; // It's OK to hold references to the AudioData because AudioData // is ref-counted. @@ -464,7 +464,7 @@ void MediaDecoderStateMachine::SendStreamData() if (mInfo.HasVideo()) { MOZ_ASSERT(stream->mNextVideoTime != -1, "Should've been initialized"); - TrackID videoTrackId = mInfo.mVideo.mTrackInfo.mOutputId; + TrackID videoTrackId = mInfo.mVideo.mTrackId; nsAutoTArray,10> video; // It's OK to hold references to the VideoData because VideoData // is ref-counted. @@ -575,7 +575,7 @@ bool MediaDecoderStateMachine::HaveEnoughDecodedAudio(int64_t aAmpleAudioUSecs) if (stream && stream->mStreamInitialized && !stream->mHaveSentFinishAudio) { MOZ_ASSERT(mInfo.HasAudio()); - TrackID audioTrackId = mInfo.mAudio.mTrackInfo.mOutputId; + TrackID audioTrackId = mInfo.mAudio.mTrackId; if (!stream->mStream->HaveEnoughBuffered(audioTrackId)) { return false; } @@ -598,7 +598,7 @@ bool MediaDecoderStateMachine::HaveEnoughDecodedVideo() if (stream && stream->mStreamInitialized && !stream->mHaveSentFinishVideo) { MOZ_ASSERT(mInfo.HasVideo()); - TrackID videoTrackId = mInfo.mVideo.mTrackInfo.mOutputId; + TrackID videoTrackId = mInfo.mVideo.mTrackId; if (!stream->mStream->HaveEnoughBuffered(videoTrackId)) { return false; } diff --git a/dom/media/MediaInfo.h b/dom/media/MediaInfo.h index 990d43eab7..8ed16ece59 100644 --- a/dom/media/MediaInfo.h +++ b/dom/media/MediaInfo.h @@ -6,64 +6,125 @@ #if !defined(MediaInfo_h) #define MediaInfo_h -#include "nsSize.h" #include "nsRect.h" -#include "ImageTypes.h" +#include "nsRefPtr.h" +#include "nsSize.h" #include "nsString.h" #include "nsTArray.h" +#include "ImageTypes.h" +#include "MediaData.h" #include "StreamBuffer.h" // for TrackID namespace mozilla { -struct TrackInfo { - void Init(const nsAString& aId, +class TrackInfo { +public: + enum TrackType { + kUndefinedTrack, + kAudioTrack, + kVideoTrack, + kTextTrack + }; + TrackInfo(TrackType aType, + const nsAString& aId, const nsAString& aKind, const nsAString& aLabel, const nsAString& aLanguage, bool aEnabled, - TrackID aOutputId = TRACK_INVALID) + TrackID aTrackId = TRACK_INVALID) + : mId(aId) + , mKind(aKind) + , mLabel(aLabel) + , mLanguage(aLanguage) + , mEnabled(aEnabled) + , mTrackId(aTrackId) + , mDuration(0) + , mMediaTime(0) + , mType(aType) + { + } + + // Only used for backward compatibility. Do not use in new code. + void Init(TrackType aType, + const nsAString& aId, + const nsAString& aKind, + const nsAString& aLabel, + const nsAString& aLanguage, + bool aEnabled, + TrackID aTrackId = TRACK_INVALID) { mId = aId; mKind = aKind; mLabel = aLabel; mLanguage = aLanguage; mEnabled = aEnabled; - mOutputId = aOutputId; + mTrackId = aTrackId; + mType = aType; } + // Fields common with MediaTrack object. nsString mId; nsString mKind; nsString mLabel; nsString mLanguage; bool mEnabled; - TrackID mOutputId; + + TrackID mTrackId; + + nsAutoCString mMimeType; + int64_t mDuration; + int64_t mMediaTime; + CryptoTrack mCrypto; + + bool IsAudio() const + { + return mType == kAudioTrack; + } + bool IsVideo() const + { + return mType == kVideoTrack; + } + bool IsText() const + { + return mType == kTextTrack; + } + TrackType GetType() const + { + return mType; + } + bool virtual IsValid() const = 0; + +private: + TrackType mType; }; // Stores info relevant to presenting media frames. -class VideoInfo { -private: - void Init(int32_t aWidth, int32_t aHeight, bool aHasVideo) - { - mDisplay = nsIntSize(aWidth, aHeight); - mStereoMode = StereoMode::MONO; - mHasVideo = aHasVideo; - mIsHardwareAccelerated = false; - - // TODO: TrackInfo should be initialized by its specific codec decoder. - // This following call should be removed once we have that implemented. - mTrackInfo.Init(NS_LITERAL_STRING("2"), NS_LITERAL_STRING("main"), - EmptyString(), EmptyString(), true, 2); - } - +class VideoInfo : public TrackInfo { public: VideoInfo() + : VideoInfo(0, 0, false) { - Init(0, 0, false); } VideoInfo(int32_t aWidth, int32_t aHeight) + : VideoInfo(aWidth, aHeight, true) { - Init(aWidth, aHeight, true); + } + + VideoInfo(int32_t aWidth, int32_t aHeight, bool aHasVideo) + : TrackInfo(kVideoTrack, NS_LITERAL_STRING("2"), NS_LITERAL_STRING("main"), + EmptyString(), EmptyString(), true, 2) + , mDisplay(nsIntSize(aWidth, aHeight)) + , mStereoMode(StereoMode::MONO) + , mImage(nsIntSize(aWidth, aHeight)) + , mExtraData(new DataBuffer) + , mHasVideo(aHasVideo) + { + } + + virtual bool IsValid() const override + { + return mDisplay.width > 0 && mDisplay.height > 0; } // Size in pixels at which the video is rendered. This is after it has @@ -73,25 +134,31 @@ public: // Indicates the frame layout for single track stereo videos. StereoMode mStereoMode; + // Size in pixels of decoded video's image. + nsIntSize mImage; + + nsRefPtr mExtraData; + // True if we have an active video bitstream. bool mHasVideo; - TrackInfo mTrackInfo; - bool mIsHardwareAccelerated; }; -class AudioInfo { +class AudioInfo : public TrackInfo { public: AudioInfo() - : mRate(44100) - , mChannels(2) + : TrackInfo(kAudioTrack, NS_LITERAL_STRING("1"), NS_LITERAL_STRING("main"), + EmptyString(), EmptyString(), true, 1) + , mRate(0) + , mChannels(0) + , mBitDepth(0) + , mProfile(0) + , mExtendedProfile(0) + , mCodecSpecificConfig(new DataBuffer) + , mExtraData(new DataBuffer) , mHasAudio(false) { - // TODO: TrackInfo should be initialized by its specific codec decoder. - // This following call should be removed once we have that implemented. - mTrackInfo.Init(NS_LITERAL_STRING("1"), NS_LITERAL_STRING("main"), - EmptyString(), EmptyString(), true, 1); } // Sample rate. @@ -100,10 +167,25 @@ public: // Number of audio channels. uint32_t mChannels; + // Bits per sample. + uint32_t mBitDepth; + + // Codec profile. + int8_t mProfile; + + // Extended codec profile. + int8_t mExtendedProfile; + + nsRefPtr mCodecSpecificConfig; + nsRefPtr mExtraData; + + virtual bool IsValid() const override + { + return mChannels > 0 && mRate > 0; + } + // True if we have an active audio bitstream. bool mHasAudio; - - TrackInfo mTrackInfo; }; class EncryptionInfo { diff --git a/dom/media/ogg/OggReader.cpp b/dom/media/ogg/OggReader.cpp index cb7b0329d3..8b18712413 100644 --- a/dom/media/ogg/OggReader.cpp +++ b/dom/media/ogg/OggReader.cpp @@ -111,7 +111,10 @@ static const nsString GetKind(const nsCString& aRole) return EmptyString(); } -static void InitTrack(MessageField* aMsgInfo, TrackInfo* aInfo, bool aEnable) +static void InitTrack(TrackInfo::TrackType aTrackType, + MessageField* aMsgInfo, + TrackInfo* aInfo, + bool aEnable) { MOZ_ASSERT(aMsgInfo); MOZ_ASSERT(aInfo); @@ -120,7 +123,8 @@ static void InitTrack(MessageField* aMsgInfo, TrackInfo* aInfo, bool aEnable) nsCString* sRole = aMsgInfo->mValuesStore.Get(eRole); nsCString* sTitle = aMsgInfo->mValuesStore.Get(eTitle); nsCString* sLanguage = aMsgInfo->mValuesStore.Get(eLanguage); - aInfo->Init(sName? NS_ConvertUTF8toUTF16(*sName):EmptyString(), + aInfo->Init(aTrackType, + sName? NS_ConvertUTF8toUTF16(*sName):EmptyString(), sRole? GetKind(*sRole):EmptyString(), sTitle? NS_ConvertUTF8toUTF16(*sTitle):EmptyString(), sLanguage? NS_ConvertUTF8toUTF16(*sLanguage):EmptyString(), @@ -322,7 +326,10 @@ void OggReader::SetupMediaTracksInfo(const nsTArray& aSerials) } if (msgInfo) { - InitTrack(msgInfo, &mInfo.mVideo.mTrackInfo, mTheoraState == theoraState); + InitTrack(TrackInfo::kVideoTrack, + msgInfo, + &mInfo.mVideo, + mTheoraState == theoraState); } nsIntRect picture = nsIntRect(theoraState->mInfo.pic_x, @@ -343,7 +350,10 @@ void OggReader::SetupMediaTracksInfo(const nsTArray& aSerials) } if (msgInfo) { - InitTrack(msgInfo, &mInfo.mAudio.mTrackInfo, mVorbisState == vorbisState); + InitTrack(TrackInfo::kAudioTrack, + msgInfo, + &mInfo.mAudio, + mVorbisState == vorbisState); } mInfo.mAudio.mHasAudio = true; @@ -356,7 +366,10 @@ void OggReader::SetupMediaTracksInfo(const nsTArray& aSerials) } if (msgInfo) { - InitTrack(msgInfo, &mInfo.mAudio.mTrackInfo, mOpusState == opusState); + InitTrack(TrackInfo::kAudioTrack, + msgInfo, + &mInfo.mAudio, + mOpusState == opusState); } mInfo.mAudio.mHasAudio = true; @@ -784,7 +797,7 @@ bool OggReader::ReadOggChain() LOG(PR_LOG_DEBUG, ("New vorbis ogg link, serial=%d\n", mVorbisSerial)); if (msgInfo) { - InitTrack(msgInfo, &mInfo.mAudio.mTrackInfo, true); + InitTrack(TrackInfo::kAudioTrack, msgInfo, &mInfo.mAudio, true); } mInfo.mAudio.mRate = newVorbisState->mInfo.rate; mInfo.mAudio.mChannels = newVorbisState->mInfo.channels; @@ -800,7 +813,7 @@ bool OggReader::ReadOggChain() SetupTargetOpus(newOpusState); if (msgInfo) { - InitTrack(msgInfo, &mInfo.mAudio.mTrackInfo, true); + InitTrack(TrackInfo::kAudioTrack, msgInfo, &mInfo.mAudio, true); } mInfo.mAudio.mRate = newOpusState->mRate; mInfo.mAudio.mChannels = newOpusState->mChannels;