1 /***************************************************************************
2     \author  MEan (C) 2003-20010 by mean fixounet@free.fr
3  ***************************************************************************/
4 /***************************************************************************
5  *                                                                         *
6  *   This program is free software; you can redistribute it and/or modify  *
7  *   it under the terms of the GNU General Public License as published by  *
8  *   the Free Software Foundation; either version 2 of the License, or     *
9  *   (at your option) any later version.                                   *
10  *                                                                         *
11  ***************************************************************************/
12 
13 
14 #include "ADM_default.h"
15 #include "ADM_image.h"
16 extern "C"
17 {
18 #include "libavutil/imgutils.h"
19 }
20 
21 static uint32_t imgMaxMem=0;
22 static uint32_t imgCurMem=0;
23 static uint32_t imgMaxNb=0;
24 static uint32_t imgCurNb=0;
25 
ADMImage_stat(void)26 void ADMImage_stat( void )
27 {
28 	printf("\nImages stat:\n");
29 	printf("___________\n");
30 	printf("Max memory consumed (MB)     : %" PRIu32"\n",imgMaxMem>>20);
31 	printf("Current memory consumed (MB) : %" PRIu32"\n",imgCurMem>>20);
32 	printf("Max image used               : %" PRIu32"\n",imgMaxNb);
33 	printf("Cur image used               : %" PRIu32"\n",imgCurNb);
34 
35 }
36 /**
37     \fn ADMImage
38     \brief ctor
39 */
ADMImage(uint32_t width,uint32_t height,ADM_IMAGE_TYPE type)40 ADMImage::ADMImage(uint32_t width, uint32_t height,ADM_IMAGE_TYPE type)
41 {
42         refType=ADM_HW_NONE;
43         memset(&refDescriptor,0,sizeof(refDescriptor));
44 
45         _width=width;
46         _height=height;
47         _Qp=2;
48         flags=0;
49         _aspect=ADM_ASPECT_1_1;
50         imgCurNb++;
51         if(imgCurNb>imgMaxNb)
52             imgMaxNb=imgCurNb;
53         _noPicture=0;
54         _colorspace=ADM_COLOR_YV12;
55         Pts=0;
56         _imageType=type;
57         quant=NULL;
58         _qStride=0;
59         _qSize=0;
60         _alpha=NULL;
61         _alphaStride=0;
62 };
63 /**
64     \fn ADMImage
65     \brief dtor
66 
67 */
~ADMImage()68 ADMImage::~ADMImage()
69 {
70     imgCurNb--;
71     hwDecRefCount();
72 }
73 /**
74     \fn hwIncRefCount
75     \brief hwIncRefCount
76 
77 */
78 
hwIncRefCount(void)79  bool            ADMImage::hwIncRefCount(void)
80 {
81         if(refType==ADM_HW_NONE) return true;
82         ADM_assert(refDescriptor.refMarkUsed);
83         return refDescriptor.refMarkUsed(refDescriptor.refCodec,refDescriptor.refHwImage);
84 }
85 /**
86     \fn hwDecRefCount
87     \brief hwDecRefCount
88 
89 */
90 
hwDecRefCount(void)91  bool            ADMImage::hwDecRefCount(void)
92 {
93         if(refType==ADM_HW_NONE) return true;
94         ADM_assert(refDescriptor.refMarkUnused);
95         bool r=refDescriptor.refMarkUnused(refDescriptor.refCodec,refDescriptor.refHwImage);
96         refType=ADM_HW_NONE;
97         return r;
98 
99 }
100 /**
101     \fn    hwDownloadFromRef
102     \brief Convert an HW ref image to a regular image
103 
104 */
hwDownloadFromRef(void)105  bool            ADMImage::hwDownloadFromRef(void)
106 {
107 bool r=false;
108         if(refType==ADM_HW_NONE) return true;
109         ADM_assert(refDescriptor.refDownload);
110         r=refDescriptor.refDownload(this,refDescriptor.refCodec,refDescriptor.refHwImage);
111         hwDecRefCount();
112         refType=ADM_HW_NONE;
113         return r;
114 
115 }
116 
117 /**
118  * 		\fn BitBlitAlpha
119  * 		\brief Alpha blit from dst to src
120  */
BitBlitAlpha(uint8_t * dst,uint32_t pitchDst,uint8_t * src,uint32_t pitchSrc,uint32_t width,uint32_t height,uint32_t alpha)121 bool BitBlitAlpha(uint8_t *dst, uint32_t pitchDst,uint8_t *src,uint32_t pitchSrc,
122 		uint32_t width, uint32_t height,uint32_t alpha)
123 {
124 
125     for(int y=0;y<height;y++)
126     {
127     	for(int x=0;x<width;x++)
128     	{
129     		uint32_t s=src[x],d=dst[x];
130 
131     		d=s*alpha+(255-alpha)*d;
132     		d>>=8;
133     		dst[x]=d;
134     	}
135         src+=pitchSrc;
136         dst+=pitchDst;
137     }
138     return 1;
139 }
140 /**
141  *
142  * @param dst
143  * @param pitchDst
144  * @param src
145  * @param pitchSrc
146  * @param width
147  * @param height
148  * @return
149  */
BitBlit(uint8_t * dst,uint32_t pitchDst,uint8_t * src,uint32_t pitchSrc,uint32_t width,uint32_t height)150 bool BitBlit(uint8_t *dst, uint32_t pitchDst,uint8_t *src,uint32_t pitchSrc,uint32_t width, uint32_t height)
151 {
152 #if 1
153     // ffmpeg makes it better
154      av_image_copy_plane(dst, (int) pitchDst,
155                          src, (int) pitchSrc,
156                          width, height);
157 #else
158     for(int y=0;y<height;y++)
159     {
160         memcpy(dst,src,width);
161         src+=pitchSrc;
162         dst+=pitchDst;
163     }
164 #endif
165   return 1;
166 }
167 //****************************************
168 /**
169     \fn ADMImageDefault
170     \brief ctor
171 
172 */
ADMImageDefault(uint32_t w,uint32_t h)173 ADMImageDefault::ADMImageDefault(uint32_t w, uint32_t h) : ADMImage(w,h,ADM_IMAGE_DEFAULT)
174 {
175     uint32_t pitch=(w+31)&(~31);
176     uint32_t allocatedHeight=(h+31)&(~31);
177     data.setSize(32+(pitch*allocatedHeight*3)/2);
178     _planes[0]=data.at(0);
179     _planes[1]=data.at(pitch*allocatedHeight);
180     _planes[2]=data.at((pitch*allocatedHeight*5)>>2);
181     _planeStride[0]=pitch;
182     _planeStride[1]=pitch/2;
183     _planeStride[2]=pitch/2;
184 }
185 /**
186     \fn ADMImageDefault
187     \brief dtor
188 */
~ADMImageDefault()189 ADMImageDefault::~ADMImageDefault()
190 {
191     data.clean();
192 }
193 /**
194  *
195  * @return
196  */
isWrittable(void)197 bool           ADMImageDefault::isWrittable(void)
198 {
199         return true;
200 }
201 /**
202  */
addAlphaChannel(void)203 bool           ADMImageDefault::addAlphaChannel(void)
204 {
205     int paddedWidth=(_width+15)& ~15;
206     alphaChannel.setSize(paddedWidth*_height);
207     _alpha=alphaChannel.at(0);
208     _alphaStride=paddedWidth;
209     return true;
210 }
211 
212 /**
213  *
214  * @param plane
215  * @return
216  */
GetPitch(ADM_PLANE plane)217 uint32_t       ADMImageDefault::GetPitch(ADM_PLANE plane)
218 {
219     if(plane==PLANAR_ALPHA)
220         return _alphaStride;
221     return _planeStride[plane];
222 }
223 /**
224  *
225  * @param plane
226  * @return
227  */
GetWritePtr(ADM_PLANE plane)228 uint8_t        *ADMImageDefault::GetWritePtr(ADM_PLANE plane)
229 {
230     return GetReadPtr(plane);
231 }
232 /**
233  *
234  * @param plane
235  * @return
236  */
GetReadPtr(ADM_PLANE plane)237 uint8_t        *ADMImageDefault::GetReadPtr(ADM_PLANE plane)
238 {
239     if(plane==PLANAR_ALPHA)
240         return _alpha;
241     return _planes[plane];
242 }
243 //****************************************
244 /**
245     \fn ADMImageRef
246     \brief ctor
247 
248 */
ADMImageRef(uint32_t w,uint32_t h)249 ADMImageRef::ADMImageRef(uint32_t w, uint32_t h) : ADMImage(w,h,ADM_IMAGE_REF)
250 {
251     _planes[0]=_planes[1]=_planes[2]=NULL;
252     _planeStride[0]=_planeStride[1]=_planeStride[2]=0;
253 }
254 /**
255     \fn ADMImageRef
256     \brief dtor
257 */
~ADMImageRef()258 ADMImageRef::~ADMImageRef()
259 {
260 }
isWrittable(void)261 bool           ADMImageRef::isWrittable(void)
262 {
263         return false;
264 }
GetPitch(ADM_PLANE plane)265 uint32_t       ADMImageRef::GetPitch(ADM_PLANE plane)
266 {
267     if(plane==PLANAR_ALPHA)
268         return _alphaStride;
269     return _planeStride[plane];
270  }
271 /**
272  *
273  * @param plane
274  * @return
275  */
276 // Cannot write to a ref, the buffer does not belong to us...
GetWritePtr(ADM_PLANE plane)277 uint8_t        *ADMImageRef::GetWritePtr(ADM_PLANE plane)
278 {
279         return NULL;
280 }
281 /**
282  *
283  * @param plane
284  * @return
285  */
GetReadPtr(ADM_PLANE plane)286 uint8_t        *ADMImageRef::GetReadPtr(ADM_PLANE plane)
287 {
288     return _planes[plane];
289 }
290 /**
291  *
292  * @param plane
293  * @return
294  */
GetHeight(ADM_PLANE plane)295 int             ADMImage::GetHeight(ADM_PLANE plane)
296 {
297     if(plane==PLANAR_Y  || plane==PLANAR_ALPHA)
298         return _height;
299     return _height/2;
300 }
301 /**
302  *
303  * @param plane
304  * @return
305  */
GetWidth(ADM_PLANE plane)306 int             ADMImage::GetWidth(ADM_PLANE plane)
307 {
308     if(plane==PLANAR_Y || plane==PLANAR_ALPHA)
309         return _width;
310     return _width/2;
311 }
312 /**
313  *
314  * @param pitches
315  * @return
316  */
GetPitches(int * pitches)317 bool            ADMImage::GetPitches(int *pitches)
318 {
319     pitches[0]=GetPitch(PLANAR_Y);
320     pitches[1]=GetPitch(PLANAR_U);
321     pitches[2]=GetPitch(PLANAR_V);
322     return true;
323 }
324 /**
325  *
326  * @param planes
327  * @return
328  */
GetWritePlanes(uint8_t ** planes)329 bool            ADMImage::GetWritePlanes(uint8_t **planes)
330 {
331     planes[0]=GetWritePtr(PLANAR_Y);
332     planes[1]=GetWritePtr(PLANAR_U);
333     planes[2]=GetWritePtr(PLANAR_V);
334     return true;
335 }
336 /**
337  *
338  * @param planes
339  * @return
340  */
GetReadPlanes(uint8_t ** planes)341 bool            ADMImage::GetReadPlanes(uint8_t **planes)
342 {
343     planes[0]=GetReadPtr(PLANAR_Y);
344     planes[1]=GetReadPtr(PLANAR_U);
345     planes[2]=GetReadPtr(PLANAR_V);
346     return true;
347 }
348 
349 
350 //EOF
351