annotate v210dec.c @ 12530:63edd10ad4bc libavcodec tip

Try to fix crashes introduced by r25218 r25218 made assumptions about the existence of past reference frames that weren't necessarily true.
author darkshikari
date Tue, 28 Sep 2010 09:06:22 +0000
parents 8b28e74de2c0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
9628
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
1 /*
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
2 * V210 decoder
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
3 *
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
4 * Copyright (C) 2009 Michael Niedermayer <michaelni@gmx.at>
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
5 * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
6 *
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
7 * This file is part of FFmpeg.
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
8 *
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
9 * FFmpeg is free software; you can redistribute it and/or
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
10 * modify it under the terms of the GNU Lesser General Public
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
11 * License as published by the Free Software Foundation; either
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
12 * version 2.1 of the License, or (at your option) any later version.
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
13 *
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
14 * FFmpeg is distributed in the hope that it will be useful,
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
17 * Lesser General Public License for more details.
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
18 *
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
19 * You should have received a copy of the GNU Lesser General Public
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
20 * License along with FFmpeg; if not, write to the Free Software
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
22 */
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
23
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
24 #include "avcodec.h"
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
25 #include "libavutil/bswap.h"
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
26
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
27 static av_cold int decode_init(AVCodecContext *avctx)
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
28 {
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
29 if (avctx->width & 1) {
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
30 av_log(avctx, AV_LOG_ERROR, "v210 needs even width\n");
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
31 return -1;
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
32 }
10131
4f974b8d8851 prettyprinting cosmetics
diego
parents: 9630
diff changeset
33 avctx->pix_fmt = PIX_FMT_YUV422P16;
9628
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
34 avctx->bits_per_raw_sample = 10;
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
35
10131
4f974b8d8851 prettyprinting cosmetics
diego
parents: 9630
diff changeset
36 avctx->coded_frame = avcodec_alloc_frame();
9628
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
37
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
38 return 0;
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
39 }
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
40
10131
4f974b8d8851 prettyprinting cosmetics
diego
parents: 9630
diff changeset
41 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
4f974b8d8851 prettyprinting cosmetics
diego
parents: 9630
diff changeset
42 AVPacket *avpkt)
9628
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
43 {
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
44 int h, w;
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
45 AVFrame *pic = avctx->coded_frame;
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
46 const uint8_t *psrc = avpkt->data;
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
47 uint16_t *y, *u, *v;
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
48 int aligned_width = ((avctx->width + 47) / 48) * 48;
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
49 int stride = aligned_width * 8 / 3;
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
50
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
51 if (pic->data[0])
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
52 avctx->release_buffer(avctx, pic);
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
53
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
54 if (avpkt->size < stride * avctx->height) {
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
55 av_log(avctx, AV_LOG_ERROR, "packet too small\n");
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
56 return -1;
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
57 }
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
58
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
59 pic->reference = 0;
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
60 if (avctx->get_buffer(avctx, pic) < 0)
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
61 return -1;
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
62
9630
ef0cf18b192d add casts to silence gcc warnings
bcoudurier
parents: 9628
diff changeset
63 y = (uint16_t*)pic->data[0];
ef0cf18b192d add casts to silence gcc warnings
bcoudurier
parents: 9628
diff changeset
64 u = (uint16_t*)pic->data[1];
ef0cf18b192d add casts to silence gcc warnings
bcoudurier
parents: 9628
diff changeset
65 v = (uint16_t*)pic->data[2];
9628
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
66 pic->pict_type = FF_I_TYPE;
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
67 pic->key_frame = 1;
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
68
10131
4f974b8d8851 prettyprinting cosmetics
diego
parents: 9630
diff changeset
69 #define READ_PIXELS(a, b, c) \
4f974b8d8851 prettyprinting cosmetics
diego
parents: 9630
diff changeset
70 do { \
12129
8b28e74de2c0 Add av_ prefix to bswap macros
mru
parents: 12128
diff changeset
71 val = av_le2ne32(*src++); \
9628
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
72 *a++ = val << 6; \
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
73 *b++ = (val >> 4) & 0xFFC0; \
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
74 *c++ = (val >> 14) & 0xFFC0; \
10169
a48c43551737 Remove ; after while(0) in macros.
ramiro
parents: 10131
diff changeset
75 } while (0)
9628
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
76
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
77 for (h = 0; h < avctx->height; h++) {
9630
ef0cf18b192d add casts to silence gcc warnings
bcoudurier
parents: 9628
diff changeset
78 const uint32_t *src = (const uint32_t*)psrc;
9628
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
79 uint32_t val;
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
80 for (w = 0; w < avctx->width - 5; w += 6) {
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
81 READ_PIXELS(u, y, v);
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
82 READ_PIXELS(y, u, y);
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
83 READ_PIXELS(v, y, u);
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
84 READ_PIXELS(y, v, y);
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
85 }
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
86 if (w < avctx->width - 1) {
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
87 READ_PIXELS(u, y, v);
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
88
12129
8b28e74de2c0 Add av_ prefix to bswap macros
mru
parents: 12128
diff changeset
89 val = av_le2ne32(*src++);
9628
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
90 *y++ = val << 6;
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
91 }
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
92 if (w < avctx->width - 3) {
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
93 *u++ = (val >> 4) & 0xFFC0;
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
94 *y++ = (val >> 14) & 0xFFC0;
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
95
12129
8b28e74de2c0 Add av_ prefix to bswap macros
mru
parents: 12128
diff changeset
96 val = av_le2ne32(*src++);
9628
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
97 *v++ = val << 6;
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
98 *y++ = (val >> 4) & 0xFFC0;
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
99 }
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
100
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
101 psrc += stride;
10131
4f974b8d8851 prettyprinting cosmetics
diego
parents: 9630
diff changeset
102 y += pic->linesize[0] / 2 - avctx->width;
4f974b8d8851 prettyprinting cosmetics
diego
parents: 9630
diff changeset
103 u += pic->linesize[1] / 2 - avctx->width / 2;
4f974b8d8851 prettyprinting cosmetics
diego
parents: 9630
diff changeset
104 v += pic->linesize[2] / 2 - avctx->width / 2;
9628
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
105 }
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
106
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
107 *data_size = sizeof(AVFrame);
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
108 *(AVFrame*)data = *avctx->coded_frame;
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
109
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
110 return avpkt->size;
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
111 }
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
112
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
113 static av_cold int decode_close(AVCodecContext *avctx)
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
114 {
10396
2bb3882075b6 Call release_buffer on close for v210dec and v210x
reimar
parents: 10169
diff changeset
115 AVFrame *pic = avctx->coded_frame;
2bb3882075b6 Call release_buffer on close for v210dec and v210x
reimar
parents: 10169
diff changeset
116 if (pic->data[0])
2bb3882075b6 Call release_buffer on close for v210dec and v210x
reimar
parents: 10169
diff changeset
117 avctx->release_buffer(avctx, pic);
9628
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
118 av_freep(&avctx->coded_frame);
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
119
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
120 return 0;
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
121 }
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
122
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
123 AVCodec v210_decoder = {
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
124 "v210",
11560
8a4984c5cacc Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 10397
diff changeset
125 AVMEDIA_TYPE_VIDEO,
9628
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
126 CODEC_ID_V210,
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
127 0,
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
128 decode_init,
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
129 NULL,
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
130 decode_close,
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
131 decode_frame,
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
132 CODEC_CAP_DR1,
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
133 .long_name = NULL_IF_CONFIG_SMALL("Uncompressed 4:2:2 10-bit"),
4b6766057548 V210 Uncompressed 4:2:2 10-bit encoder and decoder
bcoudurier
parents:
diff changeset
134 };