1 // Copyright (c) 2017 Intel Corporation
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in all
11 // copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 // SOFTWARE.
20 
21 #ifndef __UMC_VIDEO_DATA_H__
22 #define __UMC_VIDEO_DATA_H__
23 
24 #include "umc_defs.h"
25 #include "umc_structures.h"
26 #include "umc_media_data.h"
27 
28 /*
29     USAGE MODEL:
30     I. Initialization of VideoData parameters. It has to be done after construction
31       or after Close.
32       A. Simplest case. No additional planes, planes have equal bitdepth.
33         1. Set required alignment for data with SetAlignment. Default is the sample size.
34         2. Init(w,h,ColorFormat[,bitdepth]). Default bitdepth is derived from format.
35       B. Advanced case
36         1. Init(w,h,nplanes[,bitdepth]) and SetAlignment if required before or after.
37         2. Modify bitdepth or sample size for planes where necessary
38         3. Call SetColorFormat. It is the only moment to call this method.
39       This stage fill all internal information about planes, including pitches.
40       After this no more changes to parameters shall be introduced.
41       Function GetMappingSize can be called now to determine required quantity of memory
42       for all planes taking into account current alignment. All other Get methods except
43       of GetPlanePointer are possible to use.
44 
45     II. Link to memory. These operations assign all plane pointers. After that
46       MediaData::GetDataPointer will return aligned beginning of the first plane,
47       MediaData::GetDataSize will return value equal to MappingSize,
48       MediaData::GetBufferPointer can differ from DataPointer due to aligning
49       Two ways:
50       A. Allocation using Alloc. BufferSize will be MappingSize + alignment.
51       B. Call SetBufferPointer(bufsize). After that BufferSize will be bufsize.
52       Method ReleaseImage cancels this operations (unlink from memory).
53       These methods only work with continuously located planes.
54 
55     III. Operations which don't change plane parameters, like SetFrameType, can be used at
56       any moment. Operations SetPlanePointer and SetPlanePitch allow working with separate
57       planes or without specified ColorFormat but have to be used with care. Functions like
58       GetMappingSize and GetPlaneInfo can provide incorrect results.
59 
60     Note:
61     parent class methods GetDataPointer, MoveDataPointer operator= shouldn't be used.
62 */
63 
64 namespace UMC
65 {
66 
67 enum PictureStructure
68 {
69     PS_TOP_FIELD                = 1,
70     PS_BOTTOM_FIELD             = 2,
71     PS_FRAME                    = PS_TOP_FIELD | PS_BOTTOM_FIELD,
72     PS_TOP_FIELD_FIRST          = PS_FRAME | 4,
73     PS_BOTTOM_FIELD_FIRST       = PS_FRAME | 8
74 };
75 
76 struct LVASurface
77 {
78     int32_t index;
79     void*  data;
80 };
81 // converts display aspect ratio to pixel AR
82 // or vise versa with exchanged width and height
83 Status DARtoPAR(int32_t width, int32_t height, int32_t dar_h, int32_t dar_v,
84                 int32_t *par_h, int32_t *par_v);
85 
86 class VideoData : public MediaData
87 {
88   DYNAMIC_CAST_DECL(VideoData, MediaData)
89 
90 public:
91     struct PlaneInfo
92     {
93         uint8_t*   m_pPlane;         // pointer to plane data
94         mfxSize m_ippSize;        // width and height of the plane
95         int32_t   m_iSampleSize;    // sample size (in bytes)
96         int32_t   m_iSamples;       // number of samples per plane element
97         int32_t   m_iBitDepth;      // number of significant bits per sample (should be <= 8*m_iSampleSize)
98         size_t   m_nPitch;         // plane pitch (should be >= width*m_iSamples*m_iSampleSize)
99         size_t   m_nOffset;        // Offset from the beginning of aligned memory block
100         size_t   m_nMemSize;       // size of occupied memory (pitch*height)
101         int32_t   m_iWidthDiv;      // Horizontal downsampling factor
102         int32_t   m_iHeightDiv;     // Vertical downsampling factor
103     };
104 
105     // Default constructor
106     VideoData(void);
107     // Destructor
108     virtual
109     ~VideoData(void);
110 
111     // operator=
112     VideoData & operator = (const VideoData &par);
113 
114     // Initialize. Only remembers image characteristics for future.
115     virtual
116     Status Init(int32_t iWidth,
117                 int32_t iHeight,
118                 ColorFormat cFormat,
119                 int32_t iBitDepth = 0);
120 
121     // Initialize. Only remembers image characteristics for future.
122     // Should be followed by SetColorFormat
123     virtual
124     Status Init(int32_t iWidth,
125                 int32_t iHeight,
126                 int32_t iPlanes,
127                 int32_t iBitDepth = 8);
128 
129     // Allocate buffer for video data and initialize it.
130     virtual
131     Status Alloc(size_t requredSize = 0);
132 
133     // Reset all plane pointers, release memory if allocated by Alloc
134     virtual
135     Status ReleaseImage(void);
136 
137     // Release video data and all internal memory. Inherited.
138     virtual
139     Status Close(void);
140 
141     // Set buffer pointer, assign all pointers. Inherited.
142     // VideoData parameters must have been prepared
143     virtual
144     Status SetBufferPointer(uint8_t *pbBuffer, size_t nSize);
145 
146     // Set common Alignment
147     Status SetAlignment(int32_t iAlignment);
148     // Get Alignment
149     inline
150     int32_t GetAlignment(void) const;
151 
152     // Set plane destination pointer
153     Status SetPlanePointer(void *pDest, int32_t iPlaneNumber);
154     // Get plane destination pointer
155     inline
156       void *GetPlanePointer(int32_t iPlaneNumber);
157 
158     // Set image dimensions
159     Status SetImageSize(int32_t width, int32_t height);
160 
161     // Set plane pitch
162     Status SetPlanePitch(size_t nPitch, int32_t iPlaneNumber);
163     // Get plane pitch
164     inline
165     size_t GetPlanePitch(int32_t iPlaneNumber) const;
166 
167     // Set plane bitdepth
168     Status SetPlaneBitDepth(int32_t iBitDepth, int32_t iPlaneNumber);
169     // Get plane bitdepth
170     inline
171     int32_t GetPlaneBitDepth(int32_t iPlaneNumber) const;
172 
173     // Set plane sample size
174     Status SetPlaneSampleSize(int32_t iSampleSize, int32_t iPlaneNumber);
175     // Get plane sample size
176     inline
177     int32_t GetPlaneSampleSize(int32_t iPlaneNumber) const;
178 
179     // Set color format and planes' information
180     Status SetColorFormat(ColorFormat cFormat);
181     // Get color format
182     inline
183     ColorFormat GetColorFormat(void) const;
184 
185     // Set aspect Ratio
186     inline
187     Status SetAspectRatio(int32_t iHorzAspect, int32_t iVertAspect);
188     // Get aspect Ratio
189     inline
190     Status GetAspectRatio(int32_t *piHorzAspect, int32_t *piVertAspect) const;
191 
192     // Set picture structure
193     inline
194     Status SetPictureStructure(PictureStructure picStructure);
195     // Get picture structure
196     inline
197     PictureStructure GetPictureStructure(void) const;
198     // Convert to other picture structure
199     Status ConvertPictureStructure(PictureStructure newPicStructure);
200 
201     inline
202     int32_t GetNumPlanes(void) const;
203     inline
204     int32_t GetWidth(void) const;
205     inline
206     int32_t GetHeight(void) const;
207 
208     // fills PlaneInfo structure
209     Status GetPlaneInfo(PlaneInfo* pInfo, int32_t iPlaneNumber);
210 
211     // Returns the needed size of a buffer for mapping.
212     virtual
213     size_t GetMappingSize() const;
214 
215     // links plane pointers to surface using provided pitch
216     // all pitches and plane info are updated according to current
217     // color format.
218     // Works only with FourCC formats, which define planes location,
219     // like YV12 or NV12.
220     virtual
221     Status SetSurface(void* ptr, size_t nPitch);
222 
223     // Calculate pitch from mapping size
224     virtual
225     size_t GetPitchFromMappingSize(size_t mappingSize) const;
226 
227     // Crop
228     virtual Status Crop(UMC::sRECT CropArea);
229 
230 protected:
231 
232     PlaneInfo*       m_pPlaneData;    // pointer to allocated planes info
233 
234     int32_t           m_iPlanes;       // number of planes
235 
236     mfxSize         m_ippSize;       // dimension of the image
237 
238     ColorFormat      m_ColorFormat;   // color format of image
239     PictureStructure m_picStructure;  // variants: progressive frame, top first, bottom first, only top, only bottom
240 
241     int32_t           m_iHorzAspect;   // aspect ratio: pixel width/height proportion
242     int32_t           m_iVertAspect;   // default 1,1 - square pixels
243 
244     int32_t           m_iAlignment;    // default 1
245     uint8_t*           m_pbAllocated;   // pointer to allocated image buffer
246 
247 private:
248   // Declare private copy constructor to avoid accidental assignment
249   // and klocwork complaining.
250   VideoData(const VideoData &);
251 };
252 
253 // Get Alignment
254 inline
GetAlignment(void)255 int32_t VideoData::GetAlignment(void) const
256 {
257   return m_iAlignment;
258 } // int32_t VideoData::GetAlignment(void)
259 
260 inline
GetPlanePointer(int32_t iPlaneNumber)261 void* VideoData::GetPlanePointer(int32_t iPlaneNumber)
262 {
263     // check error(s)
264     if ((m_iPlanes <= iPlaneNumber) ||
265         (0 > iPlaneNumber) ||
266         (NULL == m_pPlaneData))
267         return NULL;
268 
269     return m_pPlaneData[iPlaneNumber].m_pPlane;
270 
271 } // void *VideoData::GetPlanePointer(int32_t iPlaneNumber)
272 
273 inline
GetPlaneBitDepth(int32_t iPlaneNumber)274 int32_t VideoData::GetPlaneBitDepth(int32_t iPlaneNumber) const
275 {
276     // check error(s)
277     if ((m_iPlanes <= iPlaneNumber) ||
278         (0 > iPlaneNumber) ||
279         (NULL == m_pPlaneData))
280         return 0;
281 
282   return m_pPlaneData[iPlaneNumber].m_iBitDepth;
283 
284 } // int32_t VideoData::GetPlaneBitDepth(int32_t iPlaneNumber)
285 
286 inline
GetPlaneSampleSize(int32_t iPlaneNumber)287 int32_t VideoData::GetPlaneSampleSize(int32_t iPlaneNumber) const
288 {
289     // check error(s)
290     if ((m_iPlanes <= iPlaneNumber) ||
291         (0 > iPlaneNumber) ||
292         (NULL == m_pPlaneData))
293         return 0;
294 
295   return m_pPlaneData[iPlaneNumber].m_iSampleSize;
296 
297 } // int32_t VideoData::GetPlaneSampleSize(int32_t iPlaneNumber)
298 
299 inline
GetPlanePitch(int32_t iPlaneNumber)300 size_t VideoData::GetPlanePitch(int32_t iPlaneNumber) const
301 {
302     // check error(s)
303     if ((m_iPlanes <= iPlaneNumber) ||
304         (0 > iPlaneNumber) ||
305         (NULL == m_pPlaneData))
306         return 0;
307 
308   return m_pPlaneData[iPlaneNumber].m_nPitch;
309 
310 } // size_t VideoData::GetPlanePitch(int32_t iPlaneNumber)
311 
312 inline
GetColorFormat(void)313 ColorFormat VideoData::GetColorFormat(void) const
314 {
315     return m_ColorFormat;
316 
317 } // ColorFormat VideoData::GetColorFormat(void)
318 
319 inline
SetAspectRatio(int32_t iHorzAspect,int32_t iVertAspect)320 Status VideoData::SetAspectRatio(int32_t iHorzAspect, int32_t iVertAspect)
321 {
322     if ((1 > iHorzAspect) || (1 > iVertAspect))
323         return UMC_ERR_INVALID_STREAM;
324 
325     m_iHorzAspect = iHorzAspect;
326     m_iVertAspect = iVertAspect;
327 
328     return UMC_OK;
329 
330 } // Status VideoData::SetAspectRatio(int32_t iHorzAspect, int32_t iVertAspect)
331 
332 inline
GetAspectRatio(int32_t * piHorzAspect,int32_t * piVertAspect)333 Status VideoData::GetAspectRatio(int32_t *piHorzAspect, int32_t *piVertAspect) const
334 {
335     if ((NULL == piHorzAspect) ||
336         (NULL == piVertAspect))
337         return UMC_ERR_NULL_PTR;
338 
339     *piHorzAspect = m_iHorzAspect;
340     *piVertAspect = m_iVertAspect;
341 
342     return UMC_OK;
343 
344 } // Status VideoData::GetAspectRatio(int32_t *piHorzAspect, int32_t *piVertAspect)
345 
346 inline
SetPictureStructure(PictureStructure picStructure)347 Status VideoData::SetPictureStructure(PictureStructure picStructure)
348 {
349     if ((PS_TOP_FIELD != picStructure) &&
350         (PS_BOTTOM_FIELD != picStructure) &&
351         (PS_FRAME != picStructure) &&
352         (PS_TOP_FIELD_FIRST != picStructure) &&
353         (PS_BOTTOM_FIELD_FIRST != picStructure))
354         return UMC_ERR_INVALID_STREAM;
355 
356     m_picStructure = picStructure;
357 
358     return UMC_OK;
359 
360 } // Status VideoData::SetPictureStructure(PictureStructure picStructure)
361 
362 inline
GetPictureStructure(void)363 PictureStructure VideoData::GetPictureStructure(void) const
364 {
365     return m_picStructure;
366 
367 } // PictureStructure VideoData::GetPictureStructure(void)
368 
369 inline
GetNumPlanes(void)370 int32_t VideoData::GetNumPlanes(void) const
371 {
372     return m_iPlanes;
373 
374 } // int32_t VideoData::GetNumPlanes(void)
375 
376 inline
GetWidth(void)377 int32_t VideoData::GetWidth(void) const
378 {
379     return m_ippSize.width;
380 
381 } // int32_t VideoData::GetWidth(void)
382 
383 inline
GetHeight(void)384 int32_t VideoData::GetHeight(void) const
385 {
386     return m_ippSize.height;
387 
388 } // int32_t VideoData::GetHeight(void)
389 
390 } // namespace UMC
391 
392 #endif // __UMC_VIDEO_DATA_H__
393