Statistics
| Branch: | Revision:

ffmpeg / libavcodec / raw.c @ 6c949d12

History | View | Annotate | Download (5.07 KB)

1
/*
2
 * Raw Video Codec
3
 * Copyright (c) 2001 Fabrice Bellard.
4
 *
5
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
7
 * License as published by the Free Software Foundation; either
8
 * version 2 of the License, or (at your option) any later version.
9
 *
10
 * This library is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General Public
16
 * License along with this library; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 */
19
 
20
/**
21
 * @file raw.c
22
 * Raw Video Codec
23
 */
24
 
25
#include "avcodec.h"
26

    
27

    
28
typedef struct PixleFormatTag {
29
    int pix_fmt;
30
    unsigned int fourcc;
31
} PixelFormatTag;
32

    
33
const PixelFormatTag pixelFormatTags[] = {
34
    { PIX_FMT_YUV422, MKTAG('Y', '4', '2', '2') },
35
    { -1, 0 },
36
};
37

    
38
static int findPixelFormat(unsigned int fourcc)
39
{
40
    const PixelFormatTag * tags = pixelFormatTags;
41
    while (tags->pix_fmt >= 0) {
42
        if (tags->fourcc == fourcc)
43
            return tags->pix_fmt;
44
        tags++;
45
    }
46
    return PIX_FMT_YUV420P;
47
}
48

    
49

    
50
typedef struct RawVideoContext {
51
    unsigned char * buffer;  /* block of memory for holding one frame */
52
    unsigned char * p;       /* current position in buffer */
53
    int             length;  /* number of bytes in buffer */
54
} RawVideoContext;
55

    
56

    
57
static int raw_init(AVCodecContext *avctx)
58
{
59
    RawVideoContext *context = avctx->priv_data;
60

    
61
    if (avctx->codec_tag) {
62
            avctx->pix_fmt = findPixelFormat(avctx->codec_tag);
63
    }
64

    
65
        context->length = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height);
66
        context->buffer = av_malloc(context->length);
67
        context->p      = context->buffer;
68

    
69
    if (! context->buffer) {
70
        return -1;
71
    }
72

    
73
    return 0;
74
}
75

    
76
static int raw_decode(AVCodecContext *avctx,
77
                            void *data, int *data_size,
78
                            uint8_t *buf, int buf_size)
79
{
80
    RawVideoContext *context = avctx->priv_data;
81
    int bytesNeeded;
82

    
83
    AVPicture * picture = (AVPicture *) data;
84

    
85
    /* Early out without copy if packet size == frame size */
86
    if (buf_size == context->length  &&  context->p == context->buffer) {
87
        avpicture_fill(picture, buf, avctx->pix_fmt, avctx->width, avctx->height);
88
        *data_size = sizeof(AVPicture);
89
        return buf_size;
90
    }
91

    
92
    bytesNeeded = context->length - (context->p - context->buffer);
93
    if (buf_size < bytesNeeded) {
94
        memcpy(context->p, buf, buf_size);
95
        context->p += buf_size;
96
        *data_size = 0;
97
        return buf_size;
98
    }
99

    
100
    memcpy(context->p, buf, bytesNeeded);
101
    context->p = context->buffer;
102
    avpicture_fill(picture, context->buffer, avctx->pix_fmt, avctx->width, avctx->height);
103
    *data_size = sizeof(AVPicture);
104
    return bytesNeeded;
105
}
106

    
107
static int raw_close(AVCodecContext *avctx)
108
{
109
    RawVideoContext *context = avctx->priv_data;
110

    
111
    av_freep(& context->buffer);
112

    
113
    return 0;
114
}
115

    
116
static int raw_encode(AVCodecContext *avctx,
117
                            unsigned char *frame, int buf_size, void *data)
118
{
119
        AVPicture * picture = data;
120

    
121
    unsigned char *src;
122
        unsigned char *dest = frame;
123
    int i, j;
124

    
125
        int w = avctx->width;
126
        int h = avctx->height;
127
        int size = avpicture_get_size(avctx->pix_fmt, w, h);
128

    
129
    if (size > buf_size) {
130
        return -1;
131
    }
132

    
133
    switch(avctx->pix_fmt) {
134
    case PIX_FMT_YUV420P:
135
        for(i=0;i<3;i++) {
136
            if (i == 1) {
137
                w >>= 1;
138
                h >>= 1;
139
            }
140
            src = picture->data[i];
141
            for(j=0;j<h;j++) {
142
                memcpy(dest, src, w);
143
                dest += w;
144
                src += picture->linesize[i];
145
            }
146
        }
147
        break;
148
    case PIX_FMT_YUV422P:
149
        for(i=0;i<3;i++) {
150
            if (i == 1) {
151
                w >>= 1;
152
            }
153
            src = picture->data[i];
154
            for(j=0;j<h;j++) {
155
                memcpy(dest, src, w);
156
                dest += w;
157
                src += picture->linesize[i];
158
            }
159
        }
160
        break;
161
    case PIX_FMT_YUV444P:
162
        for(i=0;i<3;i++) {
163
            src = picture->data[i];
164
            for(j=0;j<h;j++) {
165
                memcpy(dest, src, w);
166
                dest += w;
167
                src += picture->linesize[i];
168
            }
169
        }
170
        break;
171
    case PIX_FMT_YUV422:
172
        src = picture->data[0];
173
        for(j=0;j<h;j++) {
174
            memcpy(dest, src, w * 2);
175
            dest += w * 2;
176
            src += picture->linesize[0];
177
        }
178
        break;
179
    case PIX_FMT_RGB24:
180
    case PIX_FMT_BGR24:
181
        src = picture->data[0];
182
        for(j=0;j<h;j++) {
183
            memcpy(dest, src, w * 3);
184
            dest += w * 3;
185
            src += picture->linesize[0];
186
        }
187
        break;
188
    default:
189
        return -1;
190
    }
191

    
192
    return size;
193
}
194

    
195

    
196
AVCodec rawvideo_codec = {
197
    "rawvideo",
198
    CODEC_TYPE_VIDEO,
199
    CODEC_ID_RAWVIDEO,
200
    sizeof(RawVideoContext),
201
    raw_init,
202
    raw_encode,
203
    raw_close,
204
    raw_decode,
205
};