VideoFrame.h revision b51ca280e6aaace44ec1d80837439b825c6fce82
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
26namespace android {
27
28// Represents a color converted (RGB-based) video frame
29// with bitmap pixels stored in FrameBuffer
30class VideoFrame
31{
32public:
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.
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
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
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|.
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
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
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
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
156private:
157    //
158    // Utility methods used only within VideoFrame struct
159    //
160
161    // Copy the information fields only
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