Home | History | Annotate | Download | only in stagefright
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 // A container class to hold YUV data and provide various utilities,
     18 // e.g. to set/get pixel values.
     19 // Supported formats:
     20 //  - YUV420 Planar
     21 //  - YUV420 Semi Planar
     22 //
     23 //  Currently does not support variable strides.
     24 //
     25 //  Implementation: Two simple abstractions are done to simplify access
     26 //  to YUV channels for different formats:
     27 //  - initializeYUVPointers() sets up pointers (mYdata, mUdata, mVdata) to
     28 //  point to the right start locations of the different channel data depending
     29 //  on the format.
     30 //  - getOffsets() returns the correct offset for the different channels
     31 //  depending on the format.
     32 //  Location of any pixel's YUV channels can then be easily computed using these.
     33 //
     34 
     35 #ifndef YUV_IMAGE_H_
     36 
     37 #define YUV_IMAGE_H_
     38 
     39 #include <stdint.h>
     40 #include <cstring>
     41 
     42 namespace android {
     43 
     44 class Rect;
     45 
     46 class YUVImage {
     47 public:
     48     // Supported YUV formats
     49     enum YUVFormat {
     50         YUV420Planar,
     51         YUV420SemiPlanar
     52     };
     53 
     54     // Constructs an image with the given size, format. Also allocates and owns
     55     // the required memory.
     56     YUVImage(YUVFormat yuvFormat, int32_t width, int32_t height);
     57 
     58     // Constructs an image with the given size, format. The memory is provided
     59     // by the caller and we don't own it.
     60     YUVImage(YUVFormat yuvFormat, int32_t width, int32_t height, uint8_t *buffer);
     61 
     62     // Destructor to delete the memory if it owns it.
     63     ~YUVImage();
     64 
     65     // Returns the size of the buffer required to store the YUV data for the given
     66     // format and geometry. Useful when the caller wants to allocate the requisite
     67     // memory.
     68     static size_t bufferSize(YUVFormat yuvFormat, int32_t width, int32_t height);
     69 
     70     int32_t width() const {return mWidth;}
     71     int32_t height() const {return mHeight;}
     72 
     73     // Returns true if pixel is the range [0, width-1] x [0, height-1]
     74     // and false otherwise.
     75     bool validPixel(int32_t x, int32_t y) const;
     76 
     77     // Get the pixel YUV value at pixel (x,y).
     78     // Note that the range of x is [0, width-1] and the range of y is [0, height-1].
     79     // Returns true if get was successful and false otherwise.
     80     bool getPixelValue(int32_t x, int32_t y,
     81             uint8_t *yPtr, uint8_t *uPtr, uint8_t *vPtr) const;
     82 
     83     // Set the pixel YUV value at pixel (x,y).
     84     // Note that the range of x is [0, width-1] and the range of y is [0, height-1].
     85     // Returns true if set was successful and false otherwise.
     86     bool setPixelValue(int32_t x, int32_t y,
     87             uint8_t yValue, uint8_t uValue, uint8_t vValue);
     88 
     89     // Uses memcpy to copy an entire row of data
     90     static void fastCopyRectangle420Planar(
     91             const Rect& srcRect,
     92             int32_t destStartX, int32_t destStartY,
     93             const YUVImage &srcImage, YUVImage &destImage);
     94 
     95     // Uses memcpy to copy an entire row of data
     96     static void fastCopyRectangle420SemiPlanar(
     97             const Rect& srcRect,
     98             int32_t destStartX, int32_t destStartY,
     99             const YUVImage &srcImage, YUVImage &destImage);
    100 
    101     // Tries to use memcopy to copy entire rows of data.
    102     // Returns false if fast copy is not possible for the passed image formats.
    103     static bool fastCopyRectangle(
    104             const Rect& srcRect,
    105             int32_t destStartX, int32_t destStartY,
    106             const YUVImage &srcImage, YUVImage &destImage);
    107 
    108     // Convert the given YUV value to RGB.
    109     void yuv2rgb(uint8_t yValue, uint8_t uValue, uint8_t vValue,
    110         uint8_t *r, uint8_t *g, uint8_t *b) const;
    111 
    112     // Write the image to a human readable PPM file.
    113     // Returns true if write was succesful and false otherwise.
    114     bool writeToPPM(const char *filename) const;
    115 
    116 private:
    117     // YUV Format of the image.
    118     YUVFormat mYUVFormat;
    119 
    120     int32_t mWidth;
    121     int32_t mHeight;
    122 
    123     // Pointer to the memory buffer.
    124     uint8_t *mBuffer;
    125 
    126     // Boolean telling whether we own the memory buffer.
    127     bool mOwnBuffer;
    128 
    129     // Pointer to start of the Y data plane.
    130     uint8_t *mYdata;
    131 
    132     // Pointer to start of the U data plane. Note that in case of interleaved formats like
    133     // YUV420 semiplanar, mUdata points to the start of the U data in the UV plane.
    134     uint8_t *mUdata;
    135 
    136     // Pointer to start of the V data plane. Note that in case of interleaved formats like
    137     // YUV420 semiplanar, mVdata points to the start of the V data in the UV plane.
    138     uint8_t *mVdata;
    139 
    140     // Initialize the pointers mYdata, mUdata, mVdata to point to the right locations for
    141     // the given format and geometry.
    142     // Returns true if initialize was succesful and false otherwise.
    143     bool initializeYUVPointers();
    144 
    145     // For the given pixel location, this returns the offset of the location of y, u and v
    146     // data from the corresponding base pointers -- mYdata, mUdata, mVdata.
    147     // Note that the range of x is [0, width-1] and the range of y is [0, height-1].
    148     // Returns true if getting offsets was succesful and false otherwise.
    149     bool getOffsets(int32_t x, int32_t y,
    150         int32_t *yOffset, int32_t *uOffset, int32_t *vOffset) const;
    151 
    152     // Returns the offset increments incurred in going from one data row to the next data row
    153     // for the YUV channels. Note that this corresponds to data rows and not pixel rows.
    154     // E.g. depending on formats, U/V channels may have only one data row corresponding
    155     // to two pixel rows.
    156     bool getOffsetIncrementsPerDataRow(
    157         int32_t *yDataOffsetIncrement,
    158         int32_t *uDataOffsetIncrement,
    159         int32_t *vDataOffsetIncrement) const;
    160 
    161     // Given the offset return the address of the corresponding channel's data.
    162     uint8_t* getYAddress(int32_t offset) const;
    163     uint8_t* getUAddress(int32_t offset) const;
    164     uint8_t* getVAddress(int32_t offset) const;
    165 
    166     // Given the pixel location, returns the address of the corresponding channel's data.
    167     // Note that the range of x is [0, width-1] and the range of y is [0, height-1].
    168     bool getYUVAddresses(int32_t x, int32_t y,
    169         uint8_t **yAddr, uint8_t **uAddr, uint8_t **vAddr) const;
    170 
    171     // Disallow implicit casting and copying.
    172     YUVImage(const YUVImage &);
    173     YUVImage &operator=(const YUVImage &);
    174 };
    175 
    176 }  // namespace android
    177 
    178 #endif  // YUV_IMAGE_H_
    179