1 /* 2 ** 3 ** Copyright (C) 2008 The Android Open Source Project 4 ** 5 ** Licensed under the Apache License, Version 2.0 (the "License"); 6 ** you may not use this file except in compliance with the License. 7 ** You may obtain a copy of the License at 8 ** 9 ** http://www.apache.org/licenses/LICENSE-2.0 10 ** 11 ** Unless required by applicable law or agreed to in writing, software 12 ** distributed under the License is distributed on an "AS IS" BASIS, 13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 ** See the License for the specific language governing permissions and 15 ** limitations under the License. 16 */ 17 18 #ifndef ANDROID_VIDEO_FRAME_H 19 #define ANDROID_VIDEO_FRAME_H 20 21 #include <stdint.h> 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <utils/Log.h> 25 26 namespace android { 27 28 // Represents a color converted (RGB-based) video frame 29 // with bitmap pixels stored in FrameBuffer 30 class VideoFrame 31 { 32 public: 33 // Construct a VideoFrame object with the specified parameters, 34 // will allocate frame buffer if |allocate| is set to true, will 35 // allocate buffer to hold ICC data if |iccData| and |iccSize| 36 // indicate its presence. VideoFrame(uint32_t width,uint32_t height,uint32_t displayWidth,uint32_t displayHeight,uint32_t angle,uint32_t bpp,bool allocate,const void * iccData,size_t iccSize)37 VideoFrame(uint32_t width, uint32_t height, 38 uint32_t displayWidth, uint32_t displayHeight, 39 uint32_t angle, uint32_t bpp, bool allocate, 40 const void *iccData, size_t iccSize): 41 mWidth(width), mHeight(height), 42 mDisplayWidth(displayWidth), mDisplayHeight(displayHeight), 43 mRotationAngle(angle), mBytesPerPixel(bpp), mRowBytes(bpp * width), 44 mSize(0), mIccSize(0), mReserved(0), mData(0), mIccData(0) { 45 if (allocate) { 46 mSize = mRowBytes * mHeight; 47 mData = new uint8_t[mSize]; 48 if (mData == NULL) { 49 mSize = 0; 50 } 51 } 52 53 if (iccData != NULL && iccSize > 0) { 54 mIccSize = iccSize; 55 mIccData = new uint8_t[iccSize]; 56 if (mIccData != NULL) { 57 memcpy(mIccData, iccData, iccSize); 58 } else { 59 mIccSize = 0; 60 } 61 } 62 } 63 64 // Deep copy of both the information fields and the frame data VideoFrame(const VideoFrame & copy)65 VideoFrame(const VideoFrame& copy) { 66 copyInfoOnly(copy); 67 68 mSize = copy.mSize; 69 mData = NULL; // initialize it first 70 if (mSize > 0 && copy.mData != NULL) { 71 mData = new uint8_t[mSize]; 72 if (mData != NULL) { 73 memcpy(mData, copy.mData, mSize); 74 } else { 75 mSize = 0; 76 } 77 } 78 79 mIccSize = copy.mIccSize; 80 mIccData = NULL; // initialize it first 81 if (mIccSize > 0 && copy.mIccData != NULL) { 82 mIccData = new uint8_t[mIccSize]; 83 if (mIccData != NULL) { 84 memcpy(mIccData, copy.mIccData, mIccSize); 85 } else { 86 mIccSize = 0; 87 } 88 } 89 } 90 ~VideoFrame()91 ~VideoFrame() { 92 if (mData != 0) { 93 delete[] mData; 94 } 95 if (mIccData != 0) { 96 delete[] mIccData; 97 } 98 } 99 100 // Copy |copy| to a flattened VideoFrame in IMemory, 'this' must point to 101 // a chunk of memory back by IMemory of size at least getFlattenedSize() 102 // of |copy|. copyFlattened(const VideoFrame & copy)103 void copyFlattened(const VideoFrame& copy) { 104 copyInfoOnly(copy); 105 106 mSize = copy.mSize; 107 mData = NULL; // initialize it first 108 if (copy.mSize > 0 && copy.mData != NULL) { 109 memcpy(getFlattenedData(), copy.mData, copy.mSize); 110 } 111 112 mIccSize = copy.mIccSize; 113 mIccData = NULL; // initialize it first 114 if (copy.mIccSize > 0 && copy.mIccData != NULL) { 115 memcpy(getFlattenedIccData(), copy.mIccData, copy.mIccSize); 116 } 117 } 118 119 // Calculate the flattened size to put it in IMemory getFlattenedSize()120 size_t getFlattenedSize() const { 121 return sizeof(VideoFrame) + mSize + mIccSize; 122 } 123 124 // Get the pointer to the frame data in a flattened VideoFrame in IMemory getFlattenedData()125 uint8_t* getFlattenedData() const { 126 return (uint8_t*)this + sizeof(VideoFrame); 127 } 128 129 // Get the pointer to the ICC data in a flattened VideoFrame in IMemory getFlattenedIccData()130 uint8_t* getFlattenedIccData() const { 131 return (uint8_t*)this + sizeof(VideoFrame) + mSize; 132 } 133 134 // Intentional public access modifier: 135 uint32_t mWidth; // Decoded image width before rotation 136 uint32_t mHeight; // Decoded image height before rotation 137 uint32_t mDisplayWidth; // Display width before rotation 138 uint32_t mDisplayHeight; // Display height before rotation 139 int32_t mRotationAngle; // Rotation angle, clockwise, should be multiple of 90 140 uint32_t mBytesPerPixel; // Number of bytes per pixel 141 uint32_t mRowBytes; // Number of bytes per row before rotation 142 uint32_t mSize; // Number of bytes in mData 143 uint32_t mIccSize; // Number of bytes in mIccData 144 uint32_t mReserved; // (padding to make mData 64-bit aligned) 145 146 // mData should be 64-bit aligned to prevent additional padding 147 uint8_t* mData; // Actual binary data 148 // pad structure so it's the same size on 64-bit and 32-bit 149 char mPadding[8 - sizeof(mData)]; 150 151 // mIccData should be 64-bit aligned to prevent additional padding 152 uint8_t* mIccData; // Actual binary data 153 // pad structure so it's the same size on 64-bit and 32-bit 154 char mIccPadding[8 - sizeof(mIccData)]; 155 156 private: 157 // 158 // Utility methods used only within VideoFrame struct 159 // 160 161 // Copy the information fields only copyInfoOnly(const VideoFrame & copy)162 void copyInfoOnly(const VideoFrame& copy) { 163 mWidth = copy.mWidth; 164 mHeight = copy.mHeight; 165 mDisplayWidth = copy.mDisplayWidth; 166 mDisplayHeight = copy.mDisplayHeight; 167 mRotationAngle = copy.mRotationAngle; 168 mBytesPerPixel = copy.mBytesPerPixel; 169 mRowBytes = copy.mRowBytes; 170 } 171 }; 172 173 }; // namespace android 174 175 #endif // ANDROID_VIDEO_FRAME_H 176