1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/media/VideoSegment.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,140 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.7 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef MOZILLA_VIDEOSEGMENT_H_ 1.10 +#define MOZILLA_VIDEOSEGMENT_H_ 1.11 + 1.12 +#include "MediaSegment.h" 1.13 +#include "nsCOMPtr.h" 1.14 +#include "gfxPoint.h" 1.15 +#include "nsAutoPtr.h" 1.16 +#include "ImageContainer.h" 1.17 + 1.18 +namespace mozilla { 1.19 + 1.20 +namespace layers { 1.21 +class Image; 1.22 +} 1.23 + 1.24 +class VideoFrame { 1.25 +public: 1.26 + typedef mozilla::layers::Image Image; 1.27 + 1.28 + VideoFrame(already_AddRefed<Image>& aImage, const gfxIntSize& aIntrinsicSize); 1.29 + VideoFrame(); 1.30 + ~VideoFrame(); 1.31 + 1.32 + bool operator==(const VideoFrame& aFrame) const 1.33 + { 1.34 + return mIntrinsicSize == aFrame.mIntrinsicSize && 1.35 + mForceBlack == aFrame.mForceBlack && 1.36 + ((mForceBlack && aFrame.mForceBlack) || mImage == aFrame.mImage); 1.37 + } 1.38 + bool operator!=(const VideoFrame& aFrame) const 1.39 + { 1.40 + return !operator==(aFrame); 1.41 + } 1.42 + 1.43 + Image* GetImage() const { return mImage; } 1.44 + void SetForceBlack(bool aForceBlack) { mForceBlack = aForceBlack; } 1.45 + bool GetForceBlack() const { return mForceBlack; } 1.46 + const gfxIntSize& GetIntrinsicSize() const { return mIntrinsicSize; } 1.47 + void SetNull(); 1.48 + void TakeFrom(VideoFrame* aFrame); 1.49 + 1.50 +protected: 1.51 + // mImage can be null to indicate "no video" (aka "empty frame"). It can 1.52 + // still have an intrinsic size in this case. 1.53 + nsRefPtr<Image> mImage; 1.54 + // The desired size to render the video frame at. 1.55 + gfxIntSize mIntrinsicSize; 1.56 + bool mForceBlack; 1.57 +}; 1.58 + 1.59 +struct VideoChunk { 1.60 + VideoChunk(); 1.61 + ~VideoChunk(); 1.62 + void SliceTo(TrackTicks aStart, TrackTicks aEnd) 1.63 + { 1.64 + NS_ASSERTION(aStart >= 0 && aStart < aEnd && aEnd <= mDuration, 1.65 + "Slice out of bounds"); 1.66 + mDuration = aEnd - aStart; 1.67 + } 1.68 + TrackTicks GetDuration() const { return mDuration; } 1.69 + bool CanCombineWithFollowing(const VideoChunk& aOther) const 1.70 + { 1.71 + return aOther.mFrame == mFrame; 1.72 + } 1.73 + bool IsNull() const { return !mFrame.GetImage(); } 1.74 + void SetNull(TrackTicks aDuration) 1.75 + { 1.76 + mDuration = aDuration; 1.77 + mFrame.SetNull(); 1.78 + mTimeStamp = TimeStamp(); 1.79 + } 1.80 + void SetForceBlack(bool aForceBlack) { mFrame.SetForceBlack(aForceBlack); } 1.81 + 1.82 + size_t SizeOfExcludingThisIfUnshared(MallocSizeOf aMallocSizeOf) const 1.83 + { 1.84 + // Future: 1.85 + // - mFrame 1.86 + return 0; 1.87 + } 1.88 + 1.89 + TrackTicks mDuration; 1.90 + VideoFrame mFrame; 1.91 + mozilla::TimeStamp mTimeStamp; 1.92 +}; 1.93 + 1.94 +class VideoSegment : public MediaSegmentBase<VideoSegment, VideoChunk> { 1.95 +public: 1.96 + typedef mozilla::layers::Image Image; 1.97 + typedef mozilla::gfx::IntSize IntSize; 1.98 + 1.99 + VideoSegment(); 1.100 + ~VideoSegment(); 1.101 + 1.102 + void AppendFrame(already_AddRefed<Image>&& aImage, TrackTicks aDuration, 1.103 + const IntSize& aIntrinsicSize); 1.104 + const VideoFrame* GetFrameAt(TrackTicks aOffset, TrackTicks* aStart = nullptr) 1.105 + { 1.106 + VideoChunk* c = FindChunkContaining(aOffset, aStart); 1.107 + if (!c) { 1.108 + return nullptr; 1.109 + } 1.110 + return &c->mFrame; 1.111 + } 1.112 + const VideoFrame* GetLastFrame(TrackTicks* aStart = nullptr) 1.113 + { 1.114 + VideoChunk* c = GetLastChunk(); 1.115 + if (!c) { 1.116 + return nullptr; 1.117 + } 1.118 + if (aStart) { 1.119 + *aStart = mDuration - c->mDuration; 1.120 + } 1.121 + return &c->mFrame; 1.122 + } 1.123 + // Override default impl 1.124 + virtual void ReplaceWithDisabled() MOZ_OVERRIDE { 1.125 + for (ChunkIterator i(*this); 1.126 + !i.IsEnded(); i.Next()) { 1.127 + VideoChunk& chunk = *i; 1.128 + chunk.SetForceBlack(true); 1.129 + } 1.130 + } 1.131 + 1.132 + // Segment-generic methods not in MediaSegmentBase 1.133 + static Type StaticType() { return VIDEO; } 1.134 + 1.135 + virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE 1.136 + { 1.137 + return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); 1.138 + } 1.139 +}; 1.140 + 1.141 +} 1.142 + 1.143 +#endif /* MOZILLA_VIDEOSEGMENT_H_ */