1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/media/MediaData.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,270 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 +#if !defined(MediaData_h) 1.10 +#define MediaData_h 1.11 + 1.12 +#include "nsSize.h" 1.13 +#include "mozilla/gfx/Rect.h" 1.14 +#include "nsRect.h" 1.15 +#include "AudioSampleFormat.h" 1.16 +#include "nsIMemoryReporter.h" 1.17 +#include "SharedBuffer.h" 1.18 + 1.19 +namespace mozilla { 1.20 + 1.21 +namespace layers { 1.22 +class Image; 1.23 +class ImageContainer; 1.24 +} 1.25 + 1.26 +// Container that holds media samples. 1.27 +class MediaData { 1.28 +public: 1.29 + 1.30 + enum Type { 1.31 + AUDIO_SAMPLES = 0, 1.32 + VIDEO_FRAME = 1 1.33 + }; 1.34 + 1.35 + MediaData(Type aType, 1.36 + int64_t aOffset, 1.37 + int64_t aTimestamp, 1.38 + int64_t aDuration) 1.39 + : mType(aType) 1.40 + , mOffset(aOffset) 1.41 + , mTime(aTimestamp) 1.42 + , mDuration(aDuration) 1.43 + {} 1.44 + 1.45 + virtual ~MediaData() {} 1.46 + 1.47 + // Type of contained data. 1.48 + const Type mType; 1.49 + 1.50 + // Approximate byte offset where this data was demuxed from its media. 1.51 + const int64_t mOffset; 1.52 + 1.53 + // Start time of sample, in microseconds. 1.54 + const int64_t mTime; 1.55 + 1.56 + // Duration of sample, in microseconds. 1.57 + const int64_t mDuration; 1.58 + 1.59 + int64_t GetEndTime() const { return mTime + mDuration; } 1.60 + 1.61 +}; 1.62 + 1.63 +// Holds chunk a decoded audio frames. 1.64 +class AudioData : public MediaData { 1.65 +public: 1.66 + 1.67 + AudioData(int64_t aOffset, 1.68 + int64_t aTime, 1.69 + int64_t aDuration, 1.70 + uint32_t aFrames, 1.71 + AudioDataValue* aData, 1.72 + uint32_t aChannels) 1.73 + : MediaData(AUDIO_SAMPLES, aOffset, aTime, aDuration) 1.74 + , mFrames(aFrames) 1.75 + , mChannels(aChannels) 1.76 + , mAudioData(aData) 1.77 + { 1.78 + MOZ_COUNT_CTOR(AudioData); 1.79 + } 1.80 + 1.81 + ~AudioData() 1.82 + { 1.83 + MOZ_COUNT_DTOR(AudioData); 1.84 + } 1.85 + 1.86 + size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const { 1.87 + size_t size = aMallocSizeOf(this) + aMallocSizeOf(mAudioData); 1.88 + if (mAudioBuffer) { 1.89 + size += mAudioBuffer->SizeOfIncludingThis(aMallocSizeOf); 1.90 + } 1.91 + return size; 1.92 + } 1.93 + 1.94 + // If mAudioBuffer is null, creates it from mAudioData. 1.95 + void EnsureAudioBuffer(); 1.96 + 1.97 + const uint32_t mFrames; 1.98 + const uint32_t mChannels; 1.99 + // At least one of mAudioBuffer/mAudioData must be non-null. 1.100 + // mChannels channels, each with mFrames frames 1.101 + nsRefPtr<SharedBuffer> mAudioBuffer; 1.102 + // mFrames frames, each with mChannels values 1.103 + nsAutoArrayPtr<AudioDataValue> mAudioData; 1.104 +}; 1.105 + 1.106 +namespace layers { 1.107 +class TextureClient; 1.108 +class PlanarYCbCrImage; 1.109 +} 1.110 + 1.111 +class VideoInfo; 1.112 + 1.113 +// Holds a decoded video frame, in YCbCr format. These are queued in the reader. 1.114 +class VideoData : public MediaData { 1.115 +public: 1.116 + typedef gfx::IntRect IntRect; 1.117 + typedef gfx::IntSize IntSize; 1.118 + typedef layers::ImageContainer ImageContainer; 1.119 + typedef layers::Image Image; 1.120 + typedef layers::PlanarYCbCrImage PlanarYCbCrImage; 1.121 + 1.122 + // YCbCr data obtained from decoding the video. The index's are: 1.123 + // 0 = Y 1.124 + // 1 = Cb 1.125 + // 2 = Cr 1.126 + struct YCbCrBuffer { 1.127 + struct Plane { 1.128 + uint8_t* mData; 1.129 + uint32_t mWidth; 1.130 + uint32_t mHeight; 1.131 + uint32_t mStride; 1.132 + uint32_t mOffset; 1.133 + uint32_t mSkip; 1.134 + }; 1.135 + 1.136 + Plane mPlanes[3]; 1.137 + }; 1.138 + 1.139 + // Constructs a VideoData object. If aImage is nullptr, creates a new Image 1.140 + // holding a copy of the YCbCr data passed in aBuffer. If aImage is not 1.141 + // nullptr, it's stored as the underlying video image and aBuffer is assumed 1.142 + // to point to memory within aImage so no copy is made. aTimecode is a codec 1.143 + // specific number representing the timestamp of the frame of video data. 1.144 + // Returns nsnull if an error occurs. This may indicate that memory couldn't 1.145 + // be allocated to create the VideoData object, or it may indicate some 1.146 + // problem with the input data (e.g. negative stride). 1.147 + static VideoData* Create(VideoInfo& aInfo, 1.148 + ImageContainer* aContainer, 1.149 + Image* aImage, 1.150 + int64_t aOffset, 1.151 + int64_t aTime, 1.152 + int64_t aDuration, 1.153 + const YCbCrBuffer &aBuffer, 1.154 + bool aKeyframe, 1.155 + int64_t aTimecode, 1.156 + const IntRect& aPicture); 1.157 + 1.158 + // Variant that always makes a copy of aBuffer 1.159 + static VideoData* Create(VideoInfo& aInfo, 1.160 + ImageContainer* aContainer, 1.161 + int64_t aOffset, 1.162 + int64_t aTime, 1.163 + int64_t aDuration, 1.164 + const YCbCrBuffer &aBuffer, 1.165 + bool aKeyframe, 1.166 + int64_t aTimecode, 1.167 + const IntRect& aPicture); 1.168 + 1.169 + // Variant to create a VideoData instance given an existing aImage 1.170 + static VideoData* Create(VideoInfo& aInfo, 1.171 + Image* aImage, 1.172 + int64_t aOffset, 1.173 + int64_t aTime, 1.174 + int64_t aDuration, 1.175 + const YCbCrBuffer &aBuffer, 1.176 + bool aKeyframe, 1.177 + int64_t aTimecode, 1.178 + const IntRect& aPicture); 1.179 + 1.180 + static VideoData* Create(VideoInfo& aInfo, 1.181 + ImageContainer* aContainer, 1.182 + int64_t aOffset, 1.183 + int64_t aTime, 1.184 + int64_t aDuration, 1.185 + layers::TextureClient* aBuffer, 1.186 + bool aKeyframe, 1.187 + int64_t aTimecode, 1.188 + const IntRect& aPicture); 1.189 + 1.190 + static VideoData* CreateFromImage(VideoInfo& aInfo, 1.191 + ImageContainer* aContainer, 1.192 + int64_t aOffset, 1.193 + int64_t aTime, 1.194 + int64_t aDuration, 1.195 + const nsRefPtr<Image>& aImage, 1.196 + bool aKeyframe, 1.197 + int64_t aTimecode, 1.198 + const IntRect& aPicture); 1.199 + 1.200 + // Creates a new VideoData identical to aOther, but with a different 1.201 + // specified duration. All data from aOther is copied into the new 1.202 + // VideoData. The new VideoData's mImage field holds a reference to 1.203 + // aOther's mImage, i.e. the Image is not copied. This function is useful 1.204 + // in reader backends that can't determine the duration of a VideoData 1.205 + // until the next frame is decoded, i.e. it's a way to change the const 1.206 + // duration field on a VideoData. 1.207 + static VideoData* ShallowCopyUpdateDuration(VideoData* aOther, 1.208 + int64_t aDuration); 1.209 + 1.210 + // Creates a new VideoData identical to aOther, but with a different 1.211 + // specified timestamp. All data from aOther is copied into the new 1.212 + // VideoData, as ShallowCopyUpdateDuration() does. 1.213 + static VideoData* ShallowCopyUpdateTimestamp(VideoData* aOther, 1.214 + int64_t aTimestamp); 1.215 + 1.216 + // Initialize PlanarYCbCrImage. Only When aCopyData is true, 1.217 + // video data is copied to PlanarYCbCrImage. 1.218 + static void SetVideoDataToImage(PlanarYCbCrImage* aVideoImage, 1.219 + VideoInfo& aInfo, 1.220 + const YCbCrBuffer &aBuffer, 1.221 + const IntRect& aPicture, 1.222 + bool aCopyData); 1.223 + 1.224 + // Constructs a duplicate VideoData object. This intrinsically tells the 1.225 + // player that it does not need to update the displayed frame when this 1.226 + // frame is played; this frame is identical to the previous. 1.227 + static VideoData* CreateDuplicate(int64_t aOffset, 1.228 + int64_t aTime, 1.229 + int64_t aDuration, 1.230 + int64_t aTimecode) 1.231 + { 1.232 + return new VideoData(aOffset, aTime, aDuration, aTimecode); 1.233 + } 1.234 + 1.235 + ~VideoData(); 1.236 + 1.237 + size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const; 1.238 + 1.239 + // Dimensions at which to display the video frame. The picture region 1.240 + // will be scaled to this size. This is should be the picture region's 1.241 + // dimensions scaled with respect to its aspect ratio. 1.242 + const IntSize mDisplay; 1.243 + 1.244 + // Codec specific internal time code. For Ogg based codecs this is the 1.245 + // granulepos. 1.246 + const int64_t mTimecode; 1.247 + 1.248 + // This frame's image. 1.249 + nsRefPtr<Image> mImage; 1.250 + 1.251 + // When true, denotes that this frame is identical to the frame that 1.252 + // came before; it's a duplicate. mBuffer will be empty. 1.253 + const bool mDuplicate; 1.254 + const bool mKeyframe; 1.255 + 1.256 +public: 1.257 + VideoData(int64_t aOffset, 1.258 + int64_t aTime, 1.259 + int64_t aDuration, 1.260 + int64_t aTimecode); 1.261 + 1.262 + VideoData(int64_t aOffset, 1.263 + int64_t aTime, 1.264 + int64_t aDuration, 1.265 + bool aKeyframe, 1.266 + int64_t aTimecode, 1.267 + IntSize aDisplay); 1.268 + 1.269 +}; 1.270 + 1.271 +} // namespace mozilla 1.272 + 1.273 +#endif // MediaData_h