2 * Motion Pixels Video Decoder
3 * Copyright (c) 2008 Gregory Montoir (cyx@users.sourceforge.net)
5 * This file is part of FFmpeg.
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.
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.
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
23 #include "bitstream.h"
26 #define MAX_HUFF_CODES 16
28 typedef struct YuvPixel
{
32 typedef struct HuffCode
{
38 typedef struct MotionPixelsContext
{
39 AVCodecContext
*avctx
;
44 int codes_count
, current_codes_count
;
46 HuffCode codes
[MAX_HUFF_CODES
];
49 uint8_t gradient_scale
[3];
52 } MotionPixelsContext
;
54 static YuvPixel mp_rgb_yuv_table
[1 << 15];
56 static int mp_yuv_to_rgb(int y
, int v
, int u
, int clip_rgb
) {
57 static const uint8_t *cm
= ff_cropTbl
+ MAX_NEG_CROP
;
60 r
= (1000 * y
+ 701 * v
) / 1000;
61 g
= (1000 * y
- 357 * v
- 172 * u
) / 1000;
62 b
= (1000 * y
+ 886 * u
) / 1000;
64 return ((cm
[r
* 8] & 0xF8) << 7) | ((cm
[g
* 8] & 0xF8) << 2) | (cm
[b
* 8] >> 3);
65 if ((unsigned)r
< 32 && (unsigned)g
< 32 && (unsigned)b
< 32)
66 return (r
<< 10) | (g
<< 5) | b
;
70 static void mp_set_zero_yuv(YuvPixel
*p
)
74 for (i
= 0; i
< 31; ++i
) {
75 for (j
= 31; j
> i
; --j
)
76 if (!(p
[j
].u
| p
[j
].v
| p
[j
].y
))
78 for (j
= 0; j
< 31 - i
; ++j
)
79 if (!(p
[j
].u
| p
[j
].v
| p
[j
].y
))
84 static void mp_build_rgb_yuv_table(YuvPixel
*p
)
88 for (y
= 0; y
<= 31; ++y
)
89 for (v
= -31; v
<= 31; ++v
)
90 for (u
= -31; u
<= 31; ++u
) {
91 i
= mp_yuv_to_rgb(y
, v
, u
, 0);
92 if (i
< (1 << 15) && !(p
[i
].u
| p
[i
].v
| p
[i
].y
)) {
98 for (i
= 0; i
< 1024; ++i
)
99 mp_set_zero_yuv(p
+ i
* 32);
102 static av_cold
int mp_decode_init(AVCodecContext
*avctx
)
104 MotionPixelsContext
*mp
= avctx
->priv_data
;
106 if (!mp_rgb_yuv_table
[0].u
) {
107 mp_build_rgb_yuv_table(mp_rgb_yuv_table
);
110 dsputil_init(&mp
->dsp
, avctx
);
111 mp
->changes_map
= av_mallocz(avctx
->width
* avctx
->height
);
112 mp
->offset_bits_len
= av_log2(avctx
->width
* avctx
->height
) + 1;
113 mp
->vpt
= av_mallocz(avctx
->height
* sizeof(YuvPixel
));
114 mp
->hpt
= av_mallocz(avctx
->height
* avctx
->width
/ 16 * sizeof(YuvPixel
));
118 static void mp_read_changes_map(MotionPixelsContext
*mp
, GetBitContext
*gb
, int count
, int bits_len
, int read_color
)
121 int offset
, w
, h
, color
= 0, x
, y
, i
;
124 offset
= get_bits_long(gb
, mp
->offset_bits_len
);
125 w
= get_bits(gb
, bits_len
) + 1;
126 h
= get_bits(gb
, bits_len
) + 1;
128 color
= get_bits(gb
, 15);
129 x
= offset
% mp
->avctx
->width
;
130 y
= offset
/ mp
->avctx
->width
;
131 if (y
>= mp
->avctx
->height
)
133 w
= FFMIN(w
, mp
->avctx
->width
- x
);
134 h
= FFMIN(h
, mp
->avctx
->height
- y
);
135 pixels
= (uint16_t *)&mp
->frame
.data
[0][y
* mp
->frame
.linesize
[0] + x
* 2];
137 mp
->changes_map
[offset
] = w
;
139 for (i
= 0; i
< w
; ++i
)
141 offset
+= mp
->avctx
->width
;
142 pixels
+= mp
->frame
.linesize
[0] / 2;
147 static void mp_get_code(MotionPixelsContext
*mp
, GetBitContext
*gb
, int size
, int code
)
149 while (get_bits1(gb
)) {
151 if (size
> mp
->max_codes_bits
) {
152 av_log(mp
->avctx
, AV_LOG_ERROR
, "invalid code size %d/%d\n", size
, mp
->max_codes_bits
);
156 mp_get_code(mp
, gb
, size
, code
+ 1);
158 if (mp
->current_codes_count
>= MAX_HUFF_CODES
) {
159 av_log(mp
->avctx
, AV_LOG_ERROR
, "too many codes\n");
162 mp
->codes
[mp
->current_codes_count
].code
= code
;
163 mp
->codes
[mp
->current_codes_count
++].size
= size
;
166 static void mp_read_codes_table(MotionPixelsContext
*mp
, GetBitContext
*gb
)
168 if (mp
->codes_count
== 1) {
169 mp
->codes
[0].delta
= get_bits(gb
, 4);
173 mp
->max_codes_bits
= get_bits(gb
, 4);
174 for (i
= 0; i
< mp
->codes_count
; ++i
)
175 mp
->codes
[i
].delta
= get_bits(gb
, 4);
176 mp
->current_codes_count
= 0;
177 mp_get_code(mp
, gb
, 0, 0);
181 static int mp_gradient(MotionPixelsContext
*mp
, int component
, int v
)
185 delta
= (v
- 7) * mp
->gradient_scale
[component
];
186 mp
->gradient_scale
[component
] = (v
== 0 || v
== 14) ? 2 : 1;
190 static YuvPixel
mp_get_yuv_from_rgb(MotionPixelsContext
*mp
, int x
, int y
)
194 color
= *(uint16_t *)&mp
->frame
.data
[0][y
* mp
->frame
.linesize
[0] + x
* 2];
195 return mp_rgb_yuv_table
[color
];
198 static void mp_set_rgb_from_yuv(MotionPixelsContext
*mp
, int x
, int y
, const YuvPixel
*p
)
202 color
= mp_yuv_to_rgb(p
->y
, p
->v
, p
->u
, 1);
203 *(uint16_t *)&mp
->frame
.data
[0][y
* mp
->frame
.linesize
[0] + x
* 2] = color
;
206 static int mp_get_vlc(MotionPixelsContext
*mp
, GetBitContext
*gb
)
210 i
= (mp
->codes_count
== 1) ? 0 : get_vlc2(gb
, mp
->vlc
.table
, mp
->max_codes_bits
, 1);
211 return mp
->codes
[i
].delta
;
214 static void mp_decode_line(MotionPixelsContext
*mp
, GetBitContext
*gb
, int y
)
217 const int y0
= y
* mp
->avctx
->width
;
221 if (mp
->changes_map
[y0
+ x
] == 0) {
222 memset(mp
->gradient_scale
, 1, sizeof(mp
->gradient_scale
));
225 while (x
< mp
->avctx
->width
) {
226 w
= mp
->changes_map
[y0
+ x
];
229 if (mp
->changes_map
[y0
+ x
+ mp
->avctx
->width
] < w
||
230 mp
->changes_map
[y0
+ x
+ mp
->avctx
->width
* 2] < w
||
231 mp
->changes_map
[y0
+ x
+ mp
->avctx
->width
* 3] < w
) {
232 for (i
= (x
+ 3) & ~3; i
< x
+ w
; i
+= 4) {
233 mp
->hpt
[((y
/ 4) * mp
->avctx
->width
+ i
) / 4] = mp_get_yuv_from_rgb(mp
, i
, y
);
238 memset(mp
->gradient_scale
, 1, sizeof(mp
->gradient_scale
));
239 p
= mp_get_yuv_from_rgb(mp
, x
- 1, y
);
241 p
.y
+= mp_gradient(mp
, 0, mp_get_vlc(mp
, gb
));
244 p
.v
+= mp_gradient(mp
, 1, mp_get_vlc(mp
, gb
));
245 p
.u
+= mp_gradient(mp
, 2, mp_get_vlc(mp
, gb
));
246 mp
->hpt
[((y
/ 4) * mp
->avctx
->width
+ x
) / 4] = p
;
248 p
.v
= mp
->hpt
[((y
/ 4) * mp
->avctx
->width
+ x
) / 4].v
;
249 p
.u
= mp
->hpt
[((y
/ 4) * mp
->avctx
->width
+ x
) / 4].u
;
252 mp_set_rgb_from_yuv(mp
, x
, y
, &p
);
258 static void mp_decode_frame_helper(MotionPixelsContext
*mp
, GetBitContext
*gb
)
263 for (y
= 0; y
< mp
->avctx
->height
; ++y
) {
264 if (mp
->changes_map
[y
* mp
->avctx
->width
] != 0) {
265 memset(mp
->gradient_scale
, 1, sizeof(mp
->gradient_scale
));
266 p
= mp_get_yuv_from_rgb(mp
, 0, y
);
268 p
.y
+= mp_gradient(mp
, 0, mp_get_vlc(mp
, gb
));
270 p
.v
+= mp_gradient(mp
, 1, mp_get_vlc(mp
, gb
));
271 p
.u
+= mp_gradient(mp
, 2, mp_get_vlc(mp
, gb
));
274 mp_set_rgb_from_yuv(mp
, 0, y
, &p
);
277 for (y0
= 0; y0
< 2; ++y0
)
278 for (y
= y0
; y
< mp
->avctx
->height
; y
+= 2)
279 mp_decode_line(mp
, gb
, y
);
282 static int mp_decode_frame(AVCodecContext
*avctx
,
283 void *data
, int *data_size
,
284 const uint8_t *buf
, int buf_size
)
286 MotionPixelsContext
*mp
= avctx
->priv_data
;
288 int i
, count1
, count2
, sz
;
290 mp
->frame
.reference
= 1;
291 mp
->frame
.buffer_hints
= FF_BUFFER_HINTS_VALID
| FF_BUFFER_HINTS_PRESERVE
| FF_BUFFER_HINTS_REUSABLE
;
292 if (avctx
->reget_buffer(avctx
, &mp
->frame
)) {
293 av_log(avctx
, AV_LOG_ERROR
, "reget_buffer() failed\n");
297 /* le32 bitstream msb first */
298 mp
->bswapbuf
= av_fast_realloc(mp
->bswapbuf
, &mp
->bswapbuf_size
, buf_size
+ FF_INPUT_BUFFER_PADDING_SIZE
);
299 mp
->dsp
.bswap_buf((uint32_t *)mp
->bswapbuf
, (const uint32_t *)buf
, buf_size
/ 4);
301 memcpy(mp
->bswapbuf
+ (buf_size
& ~3), buf
+ (buf_size
& ~3), buf_size
& 3);
302 init_get_bits(&gb
, mp
->bswapbuf
, buf_size
* 8);
304 memset(mp
->changes_map
, 0, avctx
->width
* avctx
->height
);
305 for (i
= !(avctx
->extradata
[1] & 2); i
< 2; ++i
) {
306 count1
= get_bits(&gb
, 12);
307 count2
= get_bits(&gb
, 12);
308 mp_read_changes_map(mp
, &gb
, count1
, 8, i
);
309 mp_read_changes_map(mp
, &gb
, count2
, 4, i
);
312 mp
->codes_count
= get_bits(&gb
, 4);
313 if (mp
->codes_count
== 0)
316 if (mp
->changes_map
[0] == 0) {
317 *(uint16_t *)mp
->frame
.data
[0] = get_bits(&gb
, 15);
318 mp
->changes_map
[0] = 1;
320 mp_read_codes_table(mp
, &gb
);
322 sz
= get_bits(&gb
, 18);
323 if (avctx
->extradata
[0] != 5)
324 sz
+= get_bits(&gb
, 18);
328 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);
329 mp_decode_frame_helper(mp
, &gb
);
333 *data_size
= sizeof(AVFrame
);
334 *(AVFrame
*)data
= mp
->frame
;
338 static av_cold
int mp_decode_end(AVCodecContext
*avctx
)
340 MotionPixelsContext
*mp
= avctx
->priv_data
;
342 av_freep(&mp
->changes_map
);
345 av_freep(&mp
->bswapbuf
);
346 if (mp
->frame
.data
[0])
347 avctx
->release_buffer(avctx
, &mp
->frame
);
352 AVCodec motionpixels_decoder
= {
355 CODEC_ID_MOTIONPIXELS
,
356 sizeof(MotionPixelsContext
),
362 .long_name
= NULL_IF_CONFIG_SMALL("Motion Pixels Video"),