annotate motionpixels.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 8a4984c5cacc
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
7231
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
1 /*
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
2 * Motion Pixels Video Decoder
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
3 * Copyright (c) 2008 Gregory Montoir (cyx@users.sourceforge.net)
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
4 *
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
5 * This file is part of FFmpeg.
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
6 *
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
11 *
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
15 * Lesser General Public License for more details.
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
16 *
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
20 */
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
21
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
22 #include "avcodec.h"
9428
0dce4fe6e6f3 Rename bitstream.h to get_bits.h.
stefano
parents: 9415
diff changeset
23 #include "get_bits.h"
7231
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
24 #include "dsputil.h"
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
25
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
26 #define MAX_HUFF_CODES 16
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
27
10581
2980d9efc542 Add support for hardcoding the motionpixels rgb to yuv table.
reimar
parents: 10580
diff changeset
28 #include "motionpixels_tablegen.h"
7231
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
29
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
30 typedef struct HuffCode {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
31 int code;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
32 uint8_t size;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
33 uint8_t delta;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
34 } HuffCode;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
35
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
36 typedef struct MotionPixelsContext {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
37 AVCodecContext *avctx;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
38 AVFrame frame;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
39 DSPContext dsp;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
40 uint8_t *changes_map;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
41 int offset_bits_len;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
42 int codes_count, current_codes_count;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
43 int max_codes_bits;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
44 HuffCode codes[MAX_HUFF_CODES];
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
45 VLC vlc;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
46 YuvPixel *vpt, *hpt;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
47 uint8_t gradient_scale[3];
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
48 uint8_t *bswapbuf;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
49 int bswapbuf_size;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
50 } MotionPixelsContext;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
51
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
52 static av_cold int mp_decode_init(AVCodecContext *avctx)
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
53 {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
54 MotionPixelsContext *mp = avctx->priv_data;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
55
10581
2980d9efc542 Add support for hardcoding the motionpixels rgb to yuv table.
reimar
parents: 10580
diff changeset
56 motionpixels_tableinit();
7231
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
57 mp->avctx = avctx;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
58 dsputil_init(&mp->dsp, avctx);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
59 mp->changes_map = av_mallocz(avctx->width * avctx->height);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
60 mp->offset_bits_len = av_log2(avctx->width * avctx->height) + 1;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
61 mp->vpt = av_mallocz(avctx->height * sizeof(YuvPixel));
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
62 mp->hpt = av_mallocz(avctx->height * avctx->width / 16 * sizeof(YuvPixel));
10580
2e01212efb32 10l, pix_fmt should be set by the motionpixels decoder, not by the demuxer.
reimar
parents: 9583
diff changeset
63 avctx->pix_fmt = PIX_FMT_RGB555;
7231
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
64 return 0;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
65 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
66
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
67 static void mp_read_changes_map(MotionPixelsContext *mp, GetBitContext *gb, int count, int bits_len, int read_color)
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
68 {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
69 uint16_t *pixels;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
70 int offset, w, h, color = 0, x, y, i;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
71
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
72 while (count--) {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
73 offset = get_bits_long(gb, mp->offset_bits_len);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
74 w = get_bits(gb, bits_len) + 1;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
75 h = get_bits(gb, bits_len) + 1;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
76 if (read_color)
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
77 color = get_bits(gb, 15);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
78 x = offset % mp->avctx->width;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
79 y = offset / mp->avctx->width;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
80 if (y >= mp->avctx->height)
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
81 continue;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
82 w = FFMIN(w, mp->avctx->width - x);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
83 h = FFMIN(h, mp->avctx->height - y);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
84 pixels = (uint16_t *)&mp->frame.data[0][y * mp->frame.linesize[0] + x * 2];
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
85 while (h--) {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
86 mp->changes_map[offset] = w;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
87 if (read_color)
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
88 for (i = 0; i < w; ++i)
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
89 pixels[i] = color;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
90 offset += mp->avctx->width;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
91 pixels += mp->frame.linesize[0] / 2;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
92 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
93 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
94 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
95
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
96 static void mp_get_code(MotionPixelsContext *mp, GetBitContext *gb, int size, int code)
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
97 {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
98 while (get_bits1(gb)) {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
99 ++size;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
100 if (size > mp->max_codes_bits) {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
101 av_log(mp->avctx, AV_LOG_ERROR, "invalid code size %d/%d\n", size, mp->max_codes_bits);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
102 return;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
103 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
104 code <<= 1;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
105 mp_get_code(mp, gb, size, code + 1);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
106 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
107 if (mp->current_codes_count >= MAX_HUFF_CODES) {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
108 av_log(mp->avctx, AV_LOG_ERROR, "too many codes\n");
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
109 return;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
110 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
111 mp->codes[mp->current_codes_count ].code = code;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
112 mp->codes[mp->current_codes_count++].size = size;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
113 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
114
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
115 static void mp_read_codes_table(MotionPixelsContext *mp, GetBitContext *gb)
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
116 {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
117 if (mp->codes_count == 1) {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
118 mp->codes[0].delta = get_bits(gb, 4);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
119 } else {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
120 int i;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
121
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
122 mp->max_codes_bits = get_bits(gb, 4);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
123 for (i = 0; i < mp->codes_count; ++i)
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
124 mp->codes[i].delta = get_bits(gb, 4);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
125 mp->current_codes_count = 0;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
126 mp_get_code(mp, gb, 0, 0);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
127 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
128 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
129
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
130 static int mp_gradient(MotionPixelsContext *mp, int component, int v)
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
131 {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
132 int delta;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
133
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
134 delta = (v - 7) * mp->gradient_scale[component];
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
135 mp->gradient_scale[component] = (v == 0 || v == 14) ? 2 : 1;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
136 return delta;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
137 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
138
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
139 static YuvPixel mp_get_yuv_from_rgb(MotionPixelsContext *mp, int x, int y)
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
140 {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
141 int color;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
142
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
143 color = *(uint16_t *)&mp->frame.data[0][y * mp->frame.linesize[0] + x * 2];
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
144 return mp_rgb_yuv_table[color];
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
145 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
146
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
147 static void mp_set_rgb_from_yuv(MotionPixelsContext *mp, int x, int y, const YuvPixel *p)
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
148 {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
149 int color;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
150
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
151 color = mp_yuv_to_rgb(p->y, p->v, p->u, 1);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
152 *(uint16_t *)&mp->frame.data[0][y * mp->frame.linesize[0] + x * 2] = color;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
153 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
154
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
155 static int mp_get_vlc(MotionPixelsContext *mp, GetBitContext *gb)
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
156 {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
157 int i;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
158
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
159 i = (mp->codes_count == 1) ? 0 : get_vlc2(gb, mp->vlc.table, mp->max_codes_bits, 1);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
160 return mp->codes[i].delta;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
161 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
162
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
163 static void mp_decode_line(MotionPixelsContext *mp, GetBitContext *gb, int y)
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
164 {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
165 YuvPixel p;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
166 const int y0 = y * mp->avctx->width;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
167 int w, i, x = 0;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
168
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
169 p = mp->vpt[y];
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
170 if (mp->changes_map[y0 + x] == 0) {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
171 memset(mp->gradient_scale, 1, sizeof(mp->gradient_scale));
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
172 ++x;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
173 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
174 while (x < mp->avctx->width) {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
175 w = mp->changes_map[y0 + x];
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
176 if (w != 0) {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
177 if ((y & 3) == 0) {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
178 if (mp->changes_map[y0 + x + mp->avctx->width] < w ||
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
179 mp->changes_map[y0 + x + mp->avctx->width * 2] < w ||
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
180 mp->changes_map[y0 + x + mp->avctx->width * 3] < w) {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
181 for (i = (x + 3) & ~3; i < x + w; i += 4) {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
182 mp->hpt[((y / 4) * mp->avctx->width + i) / 4] = mp_get_yuv_from_rgb(mp, i, y);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
183 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
184 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
185 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
186 x += w;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
187 memset(mp->gradient_scale, 1, sizeof(mp->gradient_scale));
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
188 p = mp_get_yuv_from_rgb(mp, x - 1, y);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
189 } else {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
190 p.y += mp_gradient(mp, 0, mp_get_vlc(mp, gb));
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
191 if ((x & 3) == 0) {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
192 if ((y & 3) == 0) {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
193 p.v += mp_gradient(mp, 1, mp_get_vlc(mp, gb));
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
194 p.u += mp_gradient(mp, 2, mp_get_vlc(mp, gb));
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
195 mp->hpt[((y / 4) * mp->avctx->width + x) / 4] = p;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
196 } else {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
197 p.v = mp->hpt[((y / 4) * mp->avctx->width + x) / 4].v;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
198 p.u = mp->hpt[((y / 4) * mp->avctx->width + x) / 4].u;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
199 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
200 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
201 mp_set_rgb_from_yuv(mp, x, y, &p);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
202 ++x;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
203 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
204 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
205 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
206
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
207 static void mp_decode_frame_helper(MotionPixelsContext *mp, GetBitContext *gb)
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
208 {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
209 YuvPixel p;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
210 int y, y0;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
211
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
212 for (y = 0; y < mp->avctx->height; ++y) {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
213 if (mp->changes_map[y * mp->avctx->width] != 0) {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
214 memset(mp->gradient_scale, 1, sizeof(mp->gradient_scale));
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
215 p = mp_get_yuv_from_rgb(mp, 0, y);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
216 } else {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
217 p.y += mp_gradient(mp, 0, mp_get_vlc(mp, gb));
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
218 if ((y & 3) == 0) {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
219 p.v += mp_gradient(mp, 1, mp_get_vlc(mp, gb));
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
220 p.u += mp_gradient(mp, 2, mp_get_vlc(mp, gb));
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
221 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
222 mp->vpt[y] = p;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
223 mp_set_rgb_from_yuv(mp, 0, y, &p);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
224 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
225 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
226 for (y0 = 0; y0 < 2; ++y0)
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
227 for (y = y0; y < mp->avctx->height; y += 2)
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
228 mp_decode_line(mp, gb, y);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
229 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
230
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
231 static int mp_decode_frame(AVCodecContext *avctx,
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
232 void *data, int *data_size,
9355
54bc8a2727b0 Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents: 9083
diff changeset
233 AVPacket *avpkt)
7231
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
234 {
9355
54bc8a2727b0 Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents: 9083
diff changeset
235 const uint8_t *buf = avpkt->data;
54bc8a2727b0 Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents: 9083
diff changeset
236 int buf_size = avpkt->size;
7231
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
237 MotionPixelsContext *mp = avctx->priv_data;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
238 GetBitContext gb;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
239 int i, count1, count2, sz;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
240
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
241 mp->frame.reference = 1;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
242 mp->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
243 if (avctx->reget_buffer(avctx, &mp->frame)) {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
244 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
245 return -1;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
246 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
247
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
248 /* le32 bitstream msb first */
9415
141badec76fc Add a av_fast_malloc function and replace several uses of av_fast_realloc,
reimar
parents: 9355
diff changeset
249 av_fast_malloc(&mp->bswapbuf, &mp->bswapbuf_size, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
141badec76fc Add a av_fast_malloc function and replace several uses of av_fast_realloc,
reimar
parents: 9355
diff changeset
250 if (!mp->bswapbuf)
9583
26ccdc910898 Add missing return statement to out-of-memory condition. Fixes the warning:
diego
parents: 9428
diff changeset
251 return AVERROR(ENOMEM);
7231
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
252 mp->dsp.bswap_buf((uint32_t *)mp->bswapbuf, (const uint32_t *)buf, buf_size / 4);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
253 if (buf_size & 3)
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
254 memcpy(mp->bswapbuf + (buf_size & ~3), buf + (buf_size & ~3), buf_size & 3);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
255 init_get_bits(&gb, mp->bswapbuf, buf_size * 8);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
256
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
257 memset(mp->changes_map, 0, avctx->width * avctx->height);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
258 for (i = !(avctx->extradata[1] & 2); i < 2; ++i) {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
259 count1 = get_bits(&gb, 12);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
260 count2 = get_bits(&gb, 12);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
261 mp_read_changes_map(mp, &gb, count1, 8, i);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
262 mp_read_changes_map(mp, &gb, count2, 4, i);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
263 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
264
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
265 mp->codes_count = get_bits(&gb, 4);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
266 if (mp->codes_count == 0)
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
267 goto end;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
268
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
269 if (mp->changes_map[0] == 0) {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
270 *(uint16_t *)mp->frame.data[0] = get_bits(&gb, 15);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
271 mp->changes_map[0] = 1;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
272 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
273 mp_read_codes_table(mp, &gb);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
274
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
275 sz = get_bits(&gb, 18);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
276 if (avctx->extradata[0] != 5)
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
277 sz += get_bits(&gb, 18);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
278 if (sz == 0)
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
279 goto end;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
280
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
281 init_vlc(&mp->vlc, mp->max_codes_bits, mp->codes_count, &mp->codes[0].size, sizeof(HuffCode), 1, &mp->codes[0].code, sizeof(HuffCode), 4, 0);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
282 mp_decode_frame_helper(mp, &gb);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
283 free_vlc(&mp->vlc);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
284
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
285 end:
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
286 *data_size = sizeof(AVFrame);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
287 *(AVFrame *)data = mp->frame;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
288 return buf_size;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
289 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
290
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
291 static av_cold int mp_decode_end(AVCodecContext *avctx)
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
292 {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
293 MotionPixelsContext *mp = avctx->priv_data;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
294
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
295 av_freep(&mp->changes_map);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
296 av_freep(&mp->vpt);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
297 av_freep(&mp->hpt);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
298 av_freep(&mp->bswapbuf);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
299 if (mp->frame.data[0])
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
300 avctx->release_buffer(avctx, &mp->frame);
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
301
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
302 return 0;
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
303 }
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
304
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
305 AVCodec motionpixels_decoder = {
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
306 "motionpixels",
11560
8a4984c5cacc Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 10581
diff changeset
307 AVMEDIA_TYPE_VIDEO,
7231
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
308 CODEC_ID_MOTIONPIXELS,
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
309 sizeof(MotionPixelsContext),
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
310 mp_decode_init,
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
311 NULL,
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
312 mp_decode_end,
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
313 mp_decode_frame,
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
314 CODEC_CAP_DR1,
9083
bf274494b66e Change a bunch of codec long_names to be more consistent and descriptive.
diego
parents: 7231
diff changeset
315 .long_name = NULL_IF_CONFIG_SMALL("Motion Pixels video"),
7231
21f5d934ccbd Motion Pixels Video Decoder.
ramiro
parents:
diff changeset
316 };