Statistics
| Branch: | Revision:

ffmpeg / libavfilter / libmpcodecs / mp_image.c @ e4852fb3

History | View | Annotate | Download (6.4 KB)

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 "libmpcodecs/img_format.h"
30
#include "libmpcodecs/mp_image.h"
31

    
32
#include "libvo/fastmemcpy.h"
33
#include "libavutil/mem.h"
34

    
35
void mp_image_alloc_planes(mp_image_t *mpi) {
36
  // IF09 - allocate space for 4. plane delta info - unused
37
  if (mpi->imgfmt == IMGFMT_IF09) {
38
    mpi->planes[0]=av_malloc(mpi->bpp*mpi->width*(mpi->height+2)/8+
39
                            mpi->chroma_width*mpi->chroma_height);
40
  } else
41
    mpi->planes[0]=av_malloc(mpi->bpp*mpi->width*(mpi->height+2)/8);
42
  if (mpi->flags&MP_IMGFLAG_PLANAR) {
43
    int bpp = IMGFMT_IS_YUVP16(mpi->imgfmt)? 2 : 1;
44
    // YV12/I420/YVU9/IF09. feel free to add other planar formats here...
45
    mpi->stride[0]=mpi->stride[3]=bpp*mpi->width;
46
    if(mpi->num_planes > 2){
47
      mpi->stride[1]=mpi->stride[2]=bpp*mpi->chroma_width;
48
      if(mpi->flags&MP_IMGFLAG_SWAPPED){
49
        // I420/IYUV  (Y,U,V)
50
        mpi->planes[1]=mpi->planes[0]+mpi->stride[0]*mpi->height;
51
        mpi->planes[2]=mpi->planes[1]+mpi->stride[1]*mpi->chroma_height;
52
        if (mpi->num_planes > 3)
53
            mpi->planes[3]=mpi->planes[2]+mpi->stride[2]*mpi->chroma_height;
54
      } else {
55
        // YV12,YVU9,IF09  (Y,V,U)
56
        mpi->planes[2]=mpi->planes[0]+mpi->stride[0]*mpi->height;
57
        mpi->planes[1]=mpi->planes[2]+mpi->stride[1]*mpi->chroma_height;
58
        if (mpi->num_planes > 3)
59
            mpi->planes[3]=mpi->planes[1]+mpi->stride[1]*mpi->chroma_height;
60
      }
61
    } else {
62
      // NV12/NV21
63
      mpi->stride[1]=mpi->chroma_width;
64
      mpi->planes[1]=mpi->planes[0]+mpi->stride[0]*mpi->height;
65
    }
66
  } else {
67
    mpi->stride[0]=mpi->width*mpi->bpp/8;
68
    if (mpi->flags & MP_IMGFLAG_RGB_PALETTE)
69
      mpi->planes[1] = av_malloc(1024);
70
  }
71
  mpi->flags|=MP_IMGFLAG_ALLOCATED;
72
}
73

    
74
mp_image_t* alloc_mpi(int w, int h, unsigned long int fmt) {
75
  mp_image_t* mpi = new_mp_image(w,h);
76

    
77
  mp_image_setfmt(mpi,fmt);
78
  mp_image_alloc_planes(mpi);
79

    
80
  return mpi;
81
}
82

    
83
void copy_mpi(mp_image_t *dmpi, mp_image_t *mpi) {
84
  if(mpi->flags&MP_IMGFLAG_PLANAR){
85
    memcpy_pic(dmpi->planes[0],mpi->planes[0], mpi->w, mpi->h,
86
               dmpi->stride[0],mpi->stride[0]);
87
    memcpy_pic(dmpi->planes[1],mpi->planes[1], mpi->chroma_width, mpi->chroma_height,
88
               dmpi->stride[1],mpi->stride[1]);
89
    memcpy_pic(dmpi->planes[2], mpi->planes[2], mpi->chroma_width, mpi->chroma_height,
90
               dmpi->stride[2],mpi->stride[2]);
91
  } else {
92
    memcpy_pic(dmpi->planes[0],mpi->planes[0],
93
               mpi->w*(dmpi->bpp/8), mpi->h,
94
               dmpi->stride[0],mpi->stride[0]);
95
  }
96
}
97

    
98
void mp_image_setfmt(mp_image_t* mpi,unsigned int out_fmt){
99
    mpi->flags&=~(MP_IMGFLAG_PLANAR|MP_IMGFLAG_YUV|MP_IMGFLAG_SWAPPED);
100
    mpi->imgfmt=out_fmt;
101
    // compressed formats
102
    if(out_fmt == IMGFMT_MPEGPES ||
103
       out_fmt == IMGFMT_ZRMJPEGNI || out_fmt == IMGFMT_ZRMJPEGIT || out_fmt == IMGFMT_ZRMJPEGIB ||
104
       IMGFMT_IS_HWACCEL(out_fmt)){
105
        mpi->bpp=0;
106
        return;
107
    }
108
    mpi->num_planes=1;
109
    if (IMGFMT_IS_RGB(out_fmt)) {
110
        if (IMGFMT_RGB_DEPTH(out_fmt) < 8 && !(out_fmt&128))
111
            mpi->bpp = IMGFMT_RGB_DEPTH(out_fmt);
112
        else
113
            mpi->bpp=(IMGFMT_RGB_DEPTH(out_fmt)+7)&(~7);
114
        return;
115
    }
116
    if (IMGFMT_IS_BGR(out_fmt)) {
117
        if (IMGFMT_BGR_DEPTH(out_fmt) < 8 && !(out_fmt&128))
118
            mpi->bpp = IMGFMT_BGR_DEPTH(out_fmt);
119
        else
120
            mpi->bpp=(IMGFMT_BGR_DEPTH(out_fmt)+7)&(~7);
121
        mpi->flags|=MP_IMGFLAG_SWAPPED;
122
        return;
123
    }
124
    mpi->flags|=MP_IMGFLAG_YUV;
125
    mpi->num_planes=3;
126
    if (mp_get_chroma_shift(out_fmt, NULL, NULL)) {
127
        mpi->flags|=MP_IMGFLAG_PLANAR;
128
        mpi->bpp = mp_get_chroma_shift(out_fmt, &mpi->chroma_x_shift, &mpi->chroma_y_shift);
129
        mpi->chroma_width  = mpi->width  >> mpi->chroma_x_shift;
130
        mpi->chroma_height = mpi->height >> mpi->chroma_y_shift;
131
    }
132
    switch(out_fmt){
133
    case IMGFMT_I420:
134
    case IMGFMT_IYUV:
135
        mpi->flags|=MP_IMGFLAG_SWAPPED;
136
    case IMGFMT_YV12:
137
        return;
138
    case IMGFMT_420A:
139
    case IMGFMT_IF09:
140
        mpi->num_planes=4;
141
    case IMGFMT_YVU9:
142
    case IMGFMT_444P:
143
    case IMGFMT_422P:
144
    case IMGFMT_411P:
145
    case IMGFMT_440P:
146
    case IMGFMT_444P16_LE:
147
    case IMGFMT_444P16_BE:
148
    case IMGFMT_422P16_LE:
149
    case IMGFMT_422P16_BE:
150
    case IMGFMT_420P16_LE:
151
    case IMGFMT_420P16_BE:
152
        return;
153
    case IMGFMT_Y800:
154
    case IMGFMT_Y8:
155
        /* they're planar ones, but for easier handling use them as packed */
156
        mpi->flags&=~MP_IMGFLAG_PLANAR;
157
        mpi->num_planes=1;
158
        return;
159
    case IMGFMT_UYVY:
160
        mpi->flags|=MP_IMGFLAG_SWAPPED;
161
    case IMGFMT_YUY2:
162
        mpi->bpp=16;
163
        mpi->num_planes=1;
164
        return;
165
    case IMGFMT_NV12:
166
        mpi->flags|=MP_IMGFLAG_SWAPPED;
167
    case IMGFMT_NV21:
168
        mpi->flags|=MP_IMGFLAG_PLANAR;
169
        mpi->bpp=12;
170
        mpi->num_planes=2;
171
        mpi->chroma_width=(mpi->width>>0);
172
        mpi->chroma_height=(mpi->height>>1);
173
        mpi->chroma_x_shift=0;
174
        mpi->chroma_y_shift=1;
175
        return;
176
    }
177
    mp_msg(MSGT_DECVIDEO,MSGL_WARN,"mp_image: unknown out_fmt: 0x%X\n",out_fmt);
178
    mpi->bpp=0;
179
}
180

    
181
mp_image_t* new_mp_image(int w,int h){
182
    mp_image_t* mpi = malloc(sizeof(mp_image_t));
183
    if(!mpi) return NULL; // error!
184
    memset(mpi,0,sizeof(mp_image_t));
185
    mpi->width=mpi->w=w;
186
    mpi->height=mpi->h=h;
187
    return mpi;
188
}
189

    
190
void free_mp_image(mp_image_t* mpi){
191
    if(!mpi) return;
192
    if(mpi->flags&MP_IMGFLAG_ALLOCATED){
193
        /* becouse we allocate the whole image in once */
194
        av_free(mpi->planes[0]);
195
        if (mpi->flags & MP_IMGFLAG_RGB_PALETTE)
196
            av_free(mpi->planes[1]);
197
    }
198
    free(mpi);
199
}
200