Commit | Line | Data |
---|---|---|
2ba45a60 DM |
1 | /* |
2 | * This file is part of MPlayer. | |
3 | * | |
4 | * MPlayer is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License as published by | |
6 | * the Free Software Foundation; either version 2 of the License, or | |
7 | * (at your option) any later version. | |
8 | * | |
9 | * MPlayer is distributed in the hope that it will be useful, | |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | * GNU General Public License for more details. | |
13 | * | |
14 | * You should have received a copy of the GNU General Public License along | |
15 | * with MPlayer; if not, write to the Free Software Foundation, Inc., | |
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
17 | */ | |
18 | ||
19 | #include "config.h" | |
20 | ||
21 | #include <stdio.h> | |
22 | #include <stdlib.h> | |
23 | #include <string.h> | |
24 | ||
25 | #if HAVE_MALLOC_H | |
26 | #include <malloc.h> | |
27 | #endif | |
28 | ||
29 | #include "img_format.h" | |
30 | #include "mp_image.h" | |
31 | ||
32 | #include "libvo/fastmemcpy.h" | |
33 | //#include "libavutil/mem.h" | |
34 | #include "libavutil/imgutils.h" | |
35 | ||
36 | void ff_mp_image_alloc_planes(mp_image_t *mpi) { | |
37 | uint32_t temp[256]; | |
38 | if (avpriv_set_systematic_pal2(temp, ff_mp2ff_pix_fmt(mpi->imgfmt)) >= 0) | |
39 | mpi->flags |= MP_IMGFLAG_RGB_PALETTE; | |
40 | ||
41 | // IF09 - allocate space for 4. plane delta info - unused | |
42 | if (mpi->imgfmt == IMGFMT_IF09) { | |
43 | mpi->planes[0]=av_malloc(mpi->bpp*mpi->width*(mpi->height+2)/8+ | |
44 | mpi->chroma_width*mpi->chroma_height); | |
45 | } else | |
46 | mpi->planes[0]=av_malloc(mpi->bpp*mpi->width*(mpi->height+2)/8); | |
47 | if (mpi->flags&MP_IMGFLAG_PLANAR) { | |
48 | int bpp = IMGFMT_IS_YUVP16(mpi->imgfmt)? 2 : 1; | |
49 | // YV12/I420/YVU9/IF09. feel free to add other planar formats here... | |
50 | mpi->stride[0]=mpi->stride[3]=bpp*mpi->width; | |
51 | if(mpi->num_planes > 2){ | |
52 | mpi->stride[1]=mpi->stride[2]=bpp*mpi->chroma_width; | |
53 | if(mpi->flags&MP_IMGFLAG_SWAPPED){ | |
54 | // I420/IYUV (Y,U,V) | |
55 | mpi->planes[1]=mpi->planes[0]+mpi->stride[0]*mpi->height; | |
56 | mpi->planes[2]=mpi->planes[1]+mpi->stride[1]*mpi->chroma_height; | |
57 | if (mpi->num_planes > 3) | |
58 | mpi->planes[3]=mpi->planes[2]+mpi->stride[2]*mpi->chroma_height; | |
59 | } else { | |
60 | // YV12,YVU9,IF09 (Y,V,U) | |
61 | mpi->planes[2]=mpi->planes[0]+mpi->stride[0]*mpi->height; | |
62 | mpi->planes[1]=mpi->planes[2]+mpi->stride[1]*mpi->chroma_height; | |
63 | if (mpi->num_planes > 3) | |
64 | mpi->planes[3]=mpi->planes[1]+mpi->stride[1]*mpi->chroma_height; | |
65 | } | |
66 | } else { | |
67 | // NV12/NV21 | |
68 | mpi->stride[1]=mpi->chroma_width; | |
69 | mpi->planes[1]=mpi->planes[0]+mpi->stride[0]*mpi->height; | |
70 | } | |
71 | } else { | |
72 | mpi->stride[0]=mpi->width*mpi->bpp/8; | |
73 | if (mpi->flags & MP_IMGFLAG_RGB_PALETTE) { | |
74 | mpi->planes[1] = av_malloc(1024); | |
75 | memcpy(mpi->planes[1], temp, 1024); | |
76 | } | |
77 | } | |
78 | mpi->flags|=MP_IMGFLAG_ALLOCATED; | |
79 | } | |
80 | ||
81 | mp_image_t* ff_alloc_mpi(int w, int h, unsigned long int fmt) { | |
82 | mp_image_t* mpi = ff_new_mp_image(w,h); | |
83 | ||
84 | ff_mp_image_setfmt(mpi,fmt); | |
85 | ff_mp_image_alloc_planes(mpi); | |
86 | ||
87 | return mpi; | |
88 | } | |
89 | ||
90 | void ff_copy_mpi(mp_image_t *dmpi, mp_image_t *mpi) { | |
91 | if(mpi->flags&MP_IMGFLAG_PLANAR){ | |
92 | memcpy_pic(dmpi->planes[0],mpi->planes[0], mpi->w, mpi->h, | |
93 | dmpi->stride[0],mpi->stride[0]); | |
94 | memcpy_pic(dmpi->planes[1],mpi->planes[1], mpi->chroma_width, mpi->chroma_height, | |
95 | dmpi->stride[1],mpi->stride[1]); | |
96 | memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->chroma_width, mpi->chroma_height, | |
97 | dmpi->stride[2],mpi->stride[2]); | |
98 | } else { | |
99 | memcpy_pic(dmpi->planes[0],mpi->planes[0], | |
100 | mpi->w*(dmpi->bpp/8), mpi->h, | |
101 | dmpi->stride[0],mpi->stride[0]); | |
102 | } | |
103 | } | |
104 | ||
105 | void ff_mp_image_setfmt(mp_image_t* mpi,unsigned int out_fmt){ | |
106 | mpi->flags&=~(MP_IMGFLAG_PLANAR|MP_IMGFLAG_YUV|MP_IMGFLAG_SWAPPED); | |
107 | mpi->imgfmt=out_fmt; | |
108 | // compressed formats | |
109 | if(out_fmt == IMGFMT_MPEGPES || | |
110 | out_fmt == IMGFMT_ZRMJPEGNI || out_fmt == IMGFMT_ZRMJPEGIT || out_fmt == IMGFMT_ZRMJPEGIB || | |
111 | IMGFMT_IS_HWACCEL(out_fmt)){ | |
112 | mpi->bpp=0; | |
113 | return; | |
114 | } | |
115 | mpi->num_planes=1; | |
116 | if (IMGFMT_IS_RGB(out_fmt)) { | |
117 | if (IMGFMT_RGB_DEPTH(out_fmt) < 8 && !(out_fmt&128)) | |
118 | mpi->bpp = IMGFMT_RGB_DEPTH(out_fmt); | |
119 | else | |
120 | mpi->bpp=(IMGFMT_RGB_DEPTH(out_fmt)+7)&(~7); | |
121 | return; | |
122 | } | |
123 | if (IMGFMT_IS_BGR(out_fmt)) { | |
124 | if (IMGFMT_BGR_DEPTH(out_fmt) < 8 && !(out_fmt&128)) | |
125 | mpi->bpp = IMGFMT_BGR_DEPTH(out_fmt); | |
126 | else | |
127 | mpi->bpp=(IMGFMT_BGR_DEPTH(out_fmt)+7)&(~7); | |
128 | mpi->flags|=MP_IMGFLAG_SWAPPED; | |
129 | return; | |
130 | } | |
131 | if (IMGFMT_IS_XYZ(out_fmt)) { | |
132 | mpi->bpp=3*((IMGFMT_XYZ_DEPTH(out_fmt) + 7) & ~7); | |
133 | return; | |
134 | } | |
135 | mpi->num_planes=3; | |
136 | if (out_fmt == IMGFMT_GBR24P) { | |
137 | mpi->bpp=24; | |
138 | mpi->flags|=MP_IMGFLAG_PLANAR; | |
139 | return; | |
140 | } else if (out_fmt == IMGFMT_GBR12P) { | |
141 | mpi->bpp=36; | |
142 | mpi->flags|=MP_IMGFLAG_PLANAR; | |
143 | return; | |
144 | } else if (out_fmt == IMGFMT_GBR14P) { | |
145 | mpi->bpp=42; | |
146 | mpi->flags|=MP_IMGFLAG_PLANAR; | |
147 | return; | |
148 | } | |
149 | mpi->flags|=MP_IMGFLAG_YUV; | |
150 | if (ff_mp_get_chroma_shift(out_fmt, NULL, NULL, NULL)) { | |
151 | mpi->flags|=MP_IMGFLAG_PLANAR; | |
152 | mpi->bpp = ff_mp_get_chroma_shift(out_fmt, &mpi->chroma_x_shift, &mpi->chroma_y_shift, NULL); | |
153 | mpi->chroma_width = mpi->width >> mpi->chroma_x_shift; | |
154 | mpi->chroma_height = mpi->height >> mpi->chroma_y_shift; | |
155 | } | |
156 | switch(out_fmt){ | |
157 | case IMGFMT_I420: | |
158 | case IMGFMT_IYUV: | |
159 | mpi->flags|=MP_IMGFLAG_SWAPPED; | |
160 | case IMGFMT_YV12: | |
161 | return; | |
162 | case IMGFMT_420A: | |
163 | case IMGFMT_422A: | |
164 | case IMGFMT_444A: | |
165 | case IMGFMT_IF09: | |
166 | mpi->num_planes=4; | |
167 | case IMGFMT_YVU9: | |
168 | case IMGFMT_444P: | |
169 | case IMGFMT_422P: | |
170 | case IMGFMT_411P: | |
171 | case IMGFMT_440P: | |
172 | case IMGFMT_444P16_LE: | |
173 | case IMGFMT_444P16_BE: | |
174 | case IMGFMT_444P14_LE: | |
175 | case IMGFMT_444P14_BE: | |
176 | case IMGFMT_444P12_LE: | |
177 | case IMGFMT_444P12_BE: | |
178 | case IMGFMT_444P10_LE: | |
179 | case IMGFMT_444P10_BE: | |
180 | case IMGFMT_444P9_LE: | |
181 | case IMGFMT_444P9_BE: | |
182 | case IMGFMT_422P16_LE: | |
183 | case IMGFMT_422P16_BE: | |
184 | case IMGFMT_422P14_LE: | |
185 | case IMGFMT_422P14_BE: | |
186 | case IMGFMT_422P12_LE: | |
187 | case IMGFMT_422P12_BE: | |
188 | case IMGFMT_422P10_LE: | |
189 | case IMGFMT_422P10_BE: | |
190 | case IMGFMT_422P9_LE: | |
191 | case IMGFMT_422P9_BE: | |
192 | case IMGFMT_420P16_LE: | |
193 | case IMGFMT_420P16_BE: | |
194 | case IMGFMT_420P14_LE: | |
195 | case IMGFMT_420P14_BE: | |
196 | case IMGFMT_420P12_LE: | |
197 | case IMGFMT_420P12_BE: | |
198 | case IMGFMT_420P10_LE: | |
199 | case IMGFMT_420P10_BE: | |
200 | case IMGFMT_420P9_LE: | |
201 | case IMGFMT_420P9_BE: | |
202 | return; | |
203 | case IMGFMT_Y16_LE: | |
204 | case IMGFMT_Y16_BE: | |
205 | mpi->bpp=16; | |
206 | case IMGFMT_Y800: | |
207 | case IMGFMT_Y8: | |
208 | /* they're planar ones, but for easier handling use them as packed */ | |
209 | mpi->flags&=~MP_IMGFLAG_PLANAR; | |
210 | mpi->num_planes=1; | |
211 | return; | |
212 | case IMGFMT_Y8A: | |
213 | mpi->num_planes=2; | |
214 | return; | |
215 | case IMGFMT_UYVY: | |
216 | mpi->flags|=MP_IMGFLAG_SWAPPED; | |
217 | case IMGFMT_YUY2: | |
218 | mpi->chroma_x_shift = 1; | |
219 | mpi->bpp=16; | |
220 | mpi->num_planes=1; | |
221 | return; | |
222 | case IMGFMT_NV12: | |
223 | mpi->flags|=MP_IMGFLAG_SWAPPED; | |
224 | case IMGFMT_NV21: | |
225 | mpi->flags|=MP_IMGFLAG_PLANAR; | |
226 | mpi->bpp=12; | |
227 | mpi->num_planes=2; | |
228 | mpi->chroma_width=(mpi->width>>0); | |
229 | mpi->chroma_height=(mpi->height>>1); | |
230 | mpi->chroma_x_shift=0; | |
231 | mpi->chroma_y_shift=1; | |
232 | return; | |
233 | } | |
234 | ff_mp_msg(MSGT_DECVIDEO,MSGL_WARN,"mp_image: unknown out_fmt: 0x%X\n",out_fmt); | |
235 | mpi->bpp=0; | |
236 | } | |
237 | ||
238 | mp_image_t* ff_new_mp_image(int w,int h){ | |
239 | mp_image_t* mpi = malloc(sizeof(mp_image_t)); | |
240 | if(!mpi) return NULL; // error! | |
241 | memset(mpi,0,sizeof(mp_image_t)); | |
242 | mpi->width=mpi->w=w; | |
243 | mpi->height=mpi->h=h; | |
244 | return mpi; | |
245 | } | |
246 | ||
247 | void ff_free_mp_image(mp_image_t* mpi){ | |
248 | if(!mpi) return; | |
249 | if(mpi->flags&MP_IMGFLAG_ALLOCATED){ | |
250 | /* because we allocate the whole image at once */ | |
251 | av_free(mpi->planes[0]); | |
252 | if (mpi->flags & MP_IMGFLAG_RGB_PALETTE) | |
253 | av_free(mpi->planes[1]); | |
254 | } | |
255 | free(mpi); | |
256 | } | |
257 |