]> git.sesse.net Git - ffmpeg/blob - libavcodec/rawdec.c
get_buffer(): do not initialize the data.
[ffmpeg] / libavcodec / rawdec.c
1 /*
2  * Raw Video Decoder
3  * Copyright (c) 2001 Fabrice Bellard
4  *
5  * This file is part of Libav.
6  *
7  * Libav 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  * Libav 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 Libav; 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
24  * Raw Video Decoder
25  */
26
27 #include "avcodec.h"
28 #include "raw.h"
29 #include "libavutil/common.h"
30 #include "libavutil/intreadwrite.h"
31 #include "libavutil/imgutils.h"
32
33 typedef struct RawVideoContext {
34     uint32_t palette[AVPALETTE_COUNT];
35     unsigned char *buffer;  /* block of memory for holding one frame */
36     int            length;  /* number of bytes in buffer */
37     int flip;
38     AVFrame pic;             ///< AVCodecContext.coded_frame
39 } RawVideoContext;
40
41 static const PixelFormatTag pix_fmt_bps_avi[] = {
42     { AV_PIX_FMT_PAL8,    4 },
43     { AV_PIX_FMT_PAL8,    8 },
44     { AV_PIX_FMT_RGB444, 12 },
45     { AV_PIX_FMT_RGB555, 15 },
46     { AV_PIX_FMT_RGB555, 16 },
47     { AV_PIX_FMT_BGR24,  24 },
48     { AV_PIX_FMT_RGB32,  32 },
49     { AV_PIX_FMT_NONE,    0 },
50 };
51
52 static const PixelFormatTag pix_fmt_bps_mov[] = {
53     { AV_PIX_FMT_MONOWHITE, 1 },
54     { AV_PIX_FMT_PAL8,      2 },
55     { AV_PIX_FMT_PAL8,      4 },
56     { AV_PIX_FMT_PAL8,      8 },
57     // FIXME swscale does not support 16 bit in .mov, sample 16bit.mov
58     // http://developer.apple.com/documentation/QuickTime/QTFF/QTFFChap3/qtff3.html
59     { AV_PIX_FMT_RGB555BE, 16 },
60     { AV_PIX_FMT_RGB24,    24 },
61     { AV_PIX_FMT_ARGB,     32 },
62     { AV_PIX_FMT_MONOWHITE,33 },
63     { AV_PIX_FMT_NONE,      0 },
64 };
65
66 static enum AVPixelFormat find_pix_fmt(const PixelFormatTag *tags,
67                                        unsigned int fourcc)
68 {
69     while (tags->pix_fmt >= 0) {
70         if (tags->fourcc == fourcc)
71             return tags->pix_fmt;
72         tags++;
73     }
74     return AV_PIX_FMT_YUV420P;
75 }
76
77 static av_cold int raw_init_decoder(AVCodecContext *avctx)
78 {
79     RawVideoContext *context = avctx->priv_data;
80
81     if (avctx->codec_tag == MKTAG('r', 'a', 'w', ' '))
82         avctx->pix_fmt = find_pix_fmt(pix_fmt_bps_mov,
83                                       avctx->bits_per_coded_sample);
84     else if (avctx->codec_tag == MKTAG('W', 'R', 'A', 'W'))
85         avctx->pix_fmt = find_pix_fmt(pix_fmt_bps_avi,
86                                       avctx->bits_per_coded_sample);
87     else if (avctx->codec_tag)
88         avctx->pix_fmt = find_pix_fmt(ff_raw_pix_fmt_tags, avctx->codec_tag);
89     else if (avctx->pix_fmt == AV_PIX_FMT_NONE && avctx->bits_per_coded_sample)
90         avctx->pix_fmt = find_pix_fmt(pix_fmt_bps_avi,
91                                       avctx->bits_per_coded_sample);
92
93     avpriv_set_systematic_pal2(context->palette, avctx->pix_fmt);
94     context->length = avpicture_get_size(avctx->pix_fmt, avctx->width,
95                                          avctx->height);
96     if ((avctx->bits_per_coded_sample == 4 || avctx->bits_per_coded_sample == 2) &&
97         avctx->pix_fmt == AV_PIX_FMT_PAL8 &&
98        (!avctx->codec_tag || avctx->codec_tag == MKTAG('r','a','w',' '))) {
99         context->buffer = av_malloc(context->length);
100         if (!context->buffer)
101             return -1;
102     }
103     context->pic.pict_type = AV_PICTURE_TYPE_I;
104     context->pic.key_frame = 1;
105
106     avctx->coded_frame = &context->pic;
107
108     if ((avctx->extradata_size >= 9 &&
109          !memcmp(avctx->extradata + avctx->extradata_size - 9, "BottomUp", 9)) ||
110         avctx->codec_tag == MKTAG(3, 0, 0, 0) ||
111         avctx->codec_tag == MKTAG('W','R','A','W'))
112         context->flip = 1;
113
114     return 0;
115 }
116
117 static void flip(AVCodecContext *avctx, AVPicture *picture)
118 {
119     picture->data[0]     += picture->linesize[0] * (avctx->height - 1);
120     picture->linesize[0] *= -1;
121 }
122
123 static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame,
124                       AVPacket *avpkt)
125 {
126     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
127     RawVideoContext *context       = avctx->priv_data;
128     const uint8_t *buf             = avpkt->data;
129     int buf_size                   = avpkt->size;
130     int res;
131
132     AVFrame   *frame   = data;
133     AVPicture *picture = data;
134
135     frame->pict_type        = avctx->coded_frame->pict_type;
136     frame->interlaced_frame = avctx->coded_frame->interlaced_frame;
137     frame->top_field_first  = avctx->coded_frame->top_field_first;
138     frame->reordered_opaque = avctx->reordered_opaque;
139     frame->pkt_pts          = avctx->pkt->pts;
140
141     if (buf_size < context->length - (avctx->pix_fmt == AV_PIX_FMT_PAL8 ?
142                                       AVPALETTE_SIZE : 0))
143         return -1;
144
145     //2bpp and 4bpp raw in avi and mov (yes this is ugly ...)
146     if (context->buffer) {
147         int i;
148         uint8_t *dst = context->buffer;
149         buf_size = context->length - AVPALETTE_SIZE;
150         if (avctx->bits_per_coded_sample == 4) {
151             for (i = 0; 2 * i + 1 < buf_size; i++) {
152                 dst[2 * i + 0] = buf[i] >> 4;
153                 dst[2 * i + 1] = buf[i] & 15;
154             }
155         } else {
156             for (i = 0; 4 * i + 3 < buf_size; i++) {
157                 dst[4 * i + 0] = buf[i] >> 6;
158                 dst[4 * i + 1] = buf[i] >> 4 & 3;
159                 dst[4 * i + 2] = buf[i] >> 2 & 3;
160                 dst[4 * i + 3] = buf[i]      & 3;
161             }
162         }
163         buf = dst;
164     }
165
166     if (avctx->codec_tag == MKTAG('A', 'V', '1', 'x') ||
167         avctx->codec_tag == MKTAG('A', 'V', 'u', 'p'))
168         buf += buf_size - context->length;
169
170     if ((res = avpicture_fill(picture, buf, avctx->pix_fmt,
171                               avctx->width, avctx->height)) < 0)
172         return res;
173     if ((avctx->pix_fmt == AV_PIX_FMT_PAL8 && buf_size < context->length) ||
174         (desc->flags & PIX_FMT_PSEUDOPAL)) {
175         frame->data[1] = context->palette;
176     }
177     if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
178         const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE,
179                                                      NULL);
180
181         if (pal) {
182             memcpy(frame->data[1], pal, AVPALETTE_SIZE);
183             frame->palette_has_changed = 1;
184         }
185     }
186     if (avctx->pix_fmt == AV_PIX_FMT_BGR24 &&
187         ((frame->linesize[0] + 3) & ~3) * avctx->height <= buf_size)
188         frame->linesize[0] = (frame->linesize[0] + 3) & ~3;
189
190     if (context->flip)
191         flip(avctx, picture);
192
193     if (avctx->codec_tag == MKTAG('Y', 'V', '1', '2') ||
194         avctx->codec_tag == MKTAG('Y', 'V', '1', '6') ||
195         avctx->codec_tag == MKTAG('Y', 'V', '2', '4') ||
196         avctx->codec_tag == MKTAG('Y', 'V', 'U', '9'))
197         FFSWAP(uint8_t *, picture->data[1], picture->data[2]);
198
199     if (avctx->codec_tag == AV_RL32("yuv2") &&
200         avctx->pix_fmt   == AV_PIX_FMT_YUYV422) {
201         int x, y;
202         uint8_t *line = picture->data[0];
203         for (y = 0; y < avctx->height; y++) {
204             for (x = 0; x < avctx->width; x++)
205                 line[2 * x + 1] ^= 0x80;
206             line += picture->linesize[0];
207         }
208     }
209
210     *got_frame = 1;
211     return buf_size;
212 }
213
214 static av_cold int raw_close_decoder(AVCodecContext *avctx)
215 {
216     RawVideoContext *context = avctx->priv_data;
217
218     av_freep(&context->buffer);
219     return 0;
220 }
221
222 AVCodec ff_rawvideo_decoder = {
223     .name           = "rawvideo",
224     .type           = AVMEDIA_TYPE_VIDEO,
225     .id             = AV_CODEC_ID_RAWVIDEO,
226     .priv_data_size = sizeof(RawVideoContext),
227     .init           = raw_init_decoder,
228     .close          = raw_close_decoder,
229     .decode         = raw_decode,
230     .long_name      = NULL_IF_CONFIG_SMALL("raw video"),
231 };