comparison src/ffmpeg/libavcodec/raw.c @ 808:e8776388b02a trunk

[svn] - add ffmpeg
author nenolod
date Mon, 12 Mar 2007 11:18:54 -0700
parents
children
comparison
equal deleted inserted replaced
807:0f9c8d4d3ac4 808:e8776388b02a
1 /*
2 * Raw Video Codec
3 * Copyright (c) 2001 Fabrice Bellard.
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 /**
23 * @file raw.c
24 * Raw Video Codec
25 */
26
27 #include "avcodec.h"
28
29 typedef struct RawVideoContext {
30 unsigned char * buffer; /* block of memory for holding one frame */
31 int length; /* number of bytes in buffer */
32 AVFrame pic; ///< AVCodecContext.coded_frame
33 } RawVideoContext;
34
35 typedef struct PixelFormatTag {
36 int pix_fmt;
37 unsigned int fourcc;
38 } PixelFormatTag;
39
40 const PixelFormatTag pixelFormatTags[] = {
41 { PIX_FMT_YUV420P, MKTAG('I', '4', '2', '0') }, /* Planar formats */
42 { PIX_FMT_YUV420P, MKTAG('I', 'Y', 'U', 'V') },
43 { PIX_FMT_YUV420P, MKTAG('Y', 'V', '1', '2') },
44 { PIX_FMT_YUV410P, MKTAG('Y', 'U', 'V', '9') },
45 { PIX_FMT_YUV411P, MKTAG('Y', '4', '1', 'B') },
46 { PIX_FMT_YUV422P, MKTAG('Y', '4', '2', 'B') },
47 { PIX_FMT_GRAY8, MKTAG('Y', '8', '0', '0') },
48 { PIX_FMT_GRAY8, MKTAG(' ', ' ', 'Y', '8') },
49
50
51 { PIX_FMT_YUV422, MKTAG('Y', 'U', 'Y', '2') }, /* Packed formats */
52 { PIX_FMT_YUV422, MKTAG('Y', '4', '2', '2') },
53 { PIX_FMT_UYVY422, MKTAG('U', 'Y', 'V', 'Y') },
54 { PIX_FMT_GRAY8, MKTAG('G', 'R', 'E', 'Y') },
55
56 /* quicktime */
57 { PIX_FMT_UYVY422, MKTAG('2', 'v', 'u', 'y') },
58
59 { -1, 0 },
60 };
61
62 static int findPixelFormat(unsigned int fourcc)
63 {
64 const PixelFormatTag * tags = pixelFormatTags;
65 while (tags->pix_fmt >= 0) {
66 if (tags->fourcc == fourcc)
67 return tags->pix_fmt;
68 tags++;
69 }
70 return PIX_FMT_YUV420P;
71 }
72
73 unsigned int avcodec_pix_fmt_to_codec_tag(enum PixelFormat fmt)
74 {
75 const PixelFormatTag * tags = pixelFormatTags;
76 while (tags->pix_fmt >= 0) {
77 if (tags->pix_fmt == fmt)
78 return tags->fourcc;
79 tags++;
80 }
81 return 0;
82 }
83
84 /* RAW Decoder Implementation */
85
86 static int raw_init_decoder(AVCodecContext *avctx)
87 {
88 RawVideoContext *context = avctx->priv_data;
89
90 if (avctx->codec_tag)
91 avctx->pix_fmt = findPixelFormat(avctx->codec_tag);
92 else if (avctx->bits_per_sample){
93 switch(avctx->bits_per_sample){
94 case 8: avctx->pix_fmt= PIX_FMT_PAL8 ; break;
95 case 15: avctx->pix_fmt= PIX_FMT_RGB555; break;
96 case 16: avctx->pix_fmt= PIX_FMT_RGB565; break;
97 case 24: avctx->pix_fmt= PIX_FMT_BGR24 ; break;
98 case 32: avctx->pix_fmt= PIX_FMT_RGBA32; break;
99 }
100 }
101
102 context->length = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height);
103 context->buffer = av_malloc(context->length);
104 context->pic.pict_type = FF_I_TYPE;
105 context->pic.key_frame = 1;
106
107 avctx->coded_frame= &context->pic;
108
109 if (!context->buffer)
110 return -1;
111
112 return 0;
113 }
114
115 static void flip(AVCodecContext *avctx, AVPicture * picture){
116 if(!avctx->codec_tag && avctx->bits_per_sample && picture->linesize[2]==0){
117 picture->data[0] += picture->linesize[0] * (avctx->height-1);
118 picture->linesize[0] *= -1;
119 }
120 }
121
122 static int raw_decode(AVCodecContext *avctx,
123 void *data, int *data_size,
124 uint8_t *buf, int buf_size)
125 {
126 RawVideoContext *context = avctx->priv_data;
127
128 AVFrame * frame = (AVFrame *) data;
129 AVPicture * picture = (AVPicture *) data;
130
131 frame->interlaced_frame = avctx->coded_frame->interlaced_frame;
132 frame->top_field_first = avctx->coded_frame->top_field_first;
133
134 if(buf_size < context->length - (avctx->pix_fmt==PIX_FMT_PAL8 ? 256*4 : 0))
135 return -1;
136
137 avpicture_fill(picture, buf, avctx->pix_fmt, avctx->width, avctx->height);
138 if(avctx->pix_fmt==PIX_FMT_PAL8 && buf_size < context->length){
139 frame->data[1]= context->buffer;
140 }
141 if (avctx->palctrl && avctx->palctrl->palette_changed) {
142 memcpy(frame->data[1], avctx->palctrl->palette, AVPALETTE_SIZE);
143 avctx->palctrl->palette_changed = 0;
144 }
145
146 flip(avctx, picture);
147
148 if (avctx->codec_tag == MKTAG('Y', 'V', '1', '2'))
149 {
150 // swap fields
151 unsigned char *tmp = picture->data[1];
152 picture->data[1] = picture->data[2];
153 picture->data[2] = tmp;
154 }
155
156 *data_size = sizeof(AVPicture);
157 return buf_size;
158 }
159
160 static int raw_close_decoder(AVCodecContext *avctx)
161 {
162 RawVideoContext *context = avctx->priv_data;
163
164 av_freep(&context->buffer);
165 return 0;
166 }
167
168 /* RAW Encoder Implementation */
169 #ifdef CONFIG_RAWVIDEO_ENCODER
170 static int raw_init_encoder(AVCodecContext *avctx)
171 {
172 avctx->coded_frame = (AVFrame *)avctx->priv_data;
173 avctx->coded_frame->pict_type = FF_I_TYPE;
174 avctx->coded_frame->key_frame = 1;
175 if(!avctx->codec_tag)
176 avctx->codec_tag = avcodec_pix_fmt_to_codec_tag(avctx->pix_fmt);
177 return 0;
178 }
179
180 static int raw_encode(AVCodecContext *avctx,
181 unsigned char *frame, int buf_size, void *data)
182 {
183 return avpicture_layout((AVPicture *)data, avctx->pix_fmt, avctx->width,
184 avctx->height, frame, buf_size);
185 }
186
187 AVCodec rawvideo_encoder = {
188 "rawvideo",
189 CODEC_TYPE_VIDEO,
190 CODEC_ID_RAWVIDEO,
191 sizeof(AVFrame),
192 raw_init_encoder,
193 raw_encode,
194 };
195 #endif // CONFIG_RAWVIDEO_ENCODER
196
197 AVCodec rawvideo_decoder = {
198 "rawvideo",
199 CODEC_TYPE_VIDEO,
200 CODEC_ID_RAWVIDEO,
201 sizeof(RawVideoContext),
202 raw_init_decoder,
203 NULL,
204 raw_close_decoder,
205 raw_decode,
206 };