Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4349 Serge 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 
22
#include 
23
#include 
24
 
25
#if HAVE_MALLOC_H
26
#include 
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
    mpi->num_planes=3;
132
    if (out_fmt == IMGFMT_GBR24P) {
133
        mpi->bpp=24;
134
        mpi->flags|=MP_IMGFLAG_PLANAR;
135
        return;
136
    } else if (out_fmt == IMGFMT_GBR12P) {
137
        mpi->bpp=36;
138
        mpi->flags|=MP_IMGFLAG_PLANAR;
139
        return;
140
    } else if (out_fmt == IMGFMT_GBR14P) {
141
        mpi->bpp=42;
142
        mpi->flags|=MP_IMGFLAG_PLANAR;
143
        return;
144
    }
145
    mpi->flags|=MP_IMGFLAG_YUV;
146
    if (ff_mp_get_chroma_shift(out_fmt, NULL, NULL, NULL)) {
147
        mpi->flags|=MP_IMGFLAG_PLANAR;
148
        mpi->bpp = ff_mp_get_chroma_shift(out_fmt, &mpi->chroma_x_shift, &mpi->chroma_y_shift, NULL);
149
        mpi->chroma_width  = mpi->width  >> mpi->chroma_x_shift;
150
        mpi->chroma_height = mpi->height >> mpi->chroma_y_shift;
151
    }
152
    switch(out_fmt){
153
    case IMGFMT_I420:
154
    case IMGFMT_IYUV:
155
        mpi->flags|=MP_IMGFLAG_SWAPPED;
156
    case IMGFMT_YV12:
157
        return;
158
    case IMGFMT_420A:
159
    case IMGFMT_422A:
160
    case IMGFMT_444A:
161
    case IMGFMT_IF09:
162
        mpi->num_planes=4;
163
    case IMGFMT_YVU9:
164
    case IMGFMT_444P:
165
    case IMGFMT_422P:
166
    case IMGFMT_411P:
167
    case IMGFMT_440P:
168
    case IMGFMT_444P16_LE:
169
    case IMGFMT_444P16_BE:
170
    case IMGFMT_444P14_LE:
171
    case IMGFMT_444P14_BE:
172
    case IMGFMT_444P12_LE:
173
    case IMGFMT_444P12_BE:
174
    case IMGFMT_444P10_LE:
175
    case IMGFMT_444P10_BE:
176
    case IMGFMT_444P9_LE:
177
    case IMGFMT_444P9_BE:
178
    case IMGFMT_422P16_LE:
179
    case IMGFMT_422P16_BE:
180
    case IMGFMT_422P14_LE:
181
    case IMGFMT_422P14_BE:
182
    case IMGFMT_422P12_LE:
183
    case IMGFMT_422P12_BE:
184
    case IMGFMT_422P10_LE:
185
    case IMGFMT_422P10_BE:
186
    case IMGFMT_422P9_LE:
187
    case IMGFMT_422P9_BE:
188
    case IMGFMT_420P16_LE:
189
    case IMGFMT_420P16_BE:
190
    case IMGFMT_420P14_LE:
191
    case IMGFMT_420P14_BE:
192
    case IMGFMT_420P12_LE:
193
    case IMGFMT_420P12_BE:
194
    case IMGFMT_420P10_LE:
195
    case IMGFMT_420P10_BE:
196
    case IMGFMT_420P9_LE:
197
    case IMGFMT_420P9_BE:
198
        return;
199
    case IMGFMT_Y16_LE:
200
    case IMGFMT_Y16_BE:
201
        mpi->bpp=16;
202
    case IMGFMT_Y800:
203
    case IMGFMT_Y8:
204
        /* they're planar ones, but for easier handling use them as packed */
205
        mpi->flags&=~MP_IMGFLAG_PLANAR;
206
        mpi->num_planes=1;
207
        return;
208
    case IMGFMT_Y8A:
209
        mpi->num_planes=2;
210
        return;
211
    case IMGFMT_UYVY:
212
        mpi->flags|=MP_IMGFLAG_SWAPPED;
213
    case IMGFMT_YUY2:
214
        mpi->chroma_x_shift = 1;
215
        mpi->bpp=16;
216
        mpi->num_planes=1;
217
        return;
218
    case IMGFMT_NV12:
219
        mpi->flags|=MP_IMGFLAG_SWAPPED;
220
    case IMGFMT_NV21:
221
        mpi->flags|=MP_IMGFLAG_PLANAR;
222
        mpi->bpp=12;
223
        mpi->num_planes=2;
224
        mpi->chroma_width=(mpi->width>>0);
225
        mpi->chroma_height=(mpi->height>>1);
226
        mpi->chroma_x_shift=0;
227
        mpi->chroma_y_shift=1;
228
        return;
229
    }
230
    ff_mp_msg(MSGT_DECVIDEO,MSGL_WARN,"mp_image: unknown out_fmt: 0x%X\n",out_fmt);
231
    mpi->bpp=0;
232
}
233
 
234
mp_image_t* ff_new_mp_image(int w,int h){
235
    mp_image_t* mpi = malloc(sizeof(mp_image_t));
236
    if(!mpi) return NULL; // error!
237
    memset(mpi,0,sizeof(mp_image_t));
238
    mpi->width=mpi->w=w;
239
    mpi->height=mpi->h=h;
240
    return mpi;
241
}
242
 
243
void ff_free_mp_image(mp_image_t* mpi){
244
    if(!mpi) return;
245
    if(mpi->flags&MP_IMGFLAG_ALLOCATED){
246
        /* becouse we allocate the whole image in once */
247
        av_free(mpi->planes[0]);
248
        if (mpi->flags & MP_IMGFLAG_RGB_PALETTE)
249
            av_free(mpi->planes[1]);
250
    }
251
    free(mpi);
252
}
253