Mercurial > libavcodec.hg
annotate loco.c @ 10893:2aafcafbe1f0 libavcodec
Replace cabac checks in inline functions from h264.h with constants.
No benchmark because its just replacing variables with litteral constants
(so no risk for slowdown outside gcc silliness) and i need sleep.
author | michael |
---|---|
date | Sat, 16 Jan 2010 05:41:33 +0000 |
parents | 8a137661f31e |
children | 8a4984c5cacc |
rev | line source |
---|---|
2530 | 1 /* |
2 * LOCO codec | |
3 * Copyright (c) 2005 Konstantin Shishkov | |
4 * | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
5 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
6 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
2530 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
2530 | 11 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
2530 | 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 | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2967
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
2530 | 20 */ |
2967 | 21 |
2530 | 22 /** |
8718
e9d9d946f213
Use full internal pathname in doxygen @file directives.
diego
parents:
8627
diff
changeset
|
23 * @file libavcodec/loco.c |
2530 | 24 * LOCO codec. |
25 */ | |
2967 | 26 |
2530 | 27 #include "avcodec.h" |
9428 | 28 #include "get_bits.h" |
2530 | 29 #include "golomb.h" |
8627
d6bab465b82c
moves mid_pred() into mathops.h (with arch specific code split by directory)
aurel
parents:
7040
diff
changeset
|
30 #include "mathops.h" |
2530 | 31 |
2587 | 32 enum LOCO_MODE {LOCO_UNKN=0, LOCO_CYUY2=-1, LOCO_CRGB=-2, LOCO_CRGBA=-3, LOCO_CYV12=-4, |
2530 | 33 LOCO_YUY2=1, LOCO_UYVY=2, LOCO_RGB=3, LOCO_RGBA=4, LOCO_YV12=5}; |
34 | |
35 typedef struct LOCOContext{ | |
36 AVCodecContext *avctx; | |
37 AVFrame pic; | |
38 int lossy; | |
39 int mode; | |
40 } LOCOContext; | |
41 | |
42 typedef struct RICEContext{ | |
43 GetBitContext gb; | |
44 int save, run, run2; /* internal rice decoder state */ | |
45 int sum, count; /* sum and count for getting rice parameter */ | |
2558 | 46 int lossy; |
2530 | 47 }RICEContext; |
48 | |
49 static int loco_get_rice_param(RICEContext *r) | |
50 { | |
51 int cnt = 0; | |
52 int val = r->count; | |
2967 | 53 |
2530 | 54 while(r->sum > val && cnt < 9) { |
55 val <<= 1; | |
56 cnt++; | |
57 } | |
2967 | 58 |
2530 | 59 return cnt; |
60 } | |
61 | |
62 static inline void loco_update_rice_param(RICEContext *r, int val) | |
63 { | |
64 r->sum += val; | |
65 r->count++; | |
2967 | 66 |
2530 | 67 if(r->count == 16) { |
68 r->sum >>= 1; | |
69 r->count >>= 1; | |
70 } | |
71 } | |
72 | |
73 static inline int loco_get_rice(RICEContext *r) | |
74 { | |
75 int v; | |
76 if (r->run > 0) { /* we have zero run */ | |
77 r->run--; | |
2558 | 78 loco_update_rice_param(r, 0); |
2530 | 79 return 0; |
80 } | |
2558 | 81 v = get_ur_golomb_jpegls(&r->gb, loco_get_rice_param(r), INT_MAX, 0); |
82 loco_update_rice_param(r, (v+1)>>1); | |
2530 | 83 if (!v) { |
84 if (r->save >= 0) { | |
2558 | 85 r->run = get_ur_golomb_jpegls(&r->gb, 2, INT_MAX, 0); |
2530 | 86 if(r->run > 1) |
87 r->save += r->run + 1; | |
88 else | |
89 r->save -= 3; | |
90 } | |
91 else | |
92 r->run2++; | |
2558 | 93 } else { |
94 v = ((v>>1) + r->lossy) ^ -(v&1); | |
95 if (r->run2 > 0) { | |
96 if (r->run2 > 2) | |
97 r->save += r->run2; | |
98 else | |
99 r->save -= 3; | |
100 r->run2 = 0; | |
101 } | |
2530 | 102 } |
2967 | 103 |
2530 | 104 return v; |
105 } | |
106 | |
107 /* LOCO main predictor - LOCO-I/JPEG-LS predictor */ | |
108 static inline int loco_predict(uint8_t* data, int stride, int step) | |
109 { | |
110 int a, b, c; | |
2967 | 111 |
2530 | 112 a = data[-stride]; |
113 b = data[-step]; | |
114 c = data[-stride - step]; | |
2967 | 115 |
2558 | 116 return mid_pred(a, a + b - c, b); |
2530 | 117 } |
118 | |
119 static int loco_decode_plane(LOCOContext *l, uint8_t *data, int width, int height, | |
6218 | 120 int stride, const uint8_t *buf, int buf_size, int step) |
2530 | 121 { |
122 RICEContext rc; | |
123 int val; | |
124 int i, j; | |
2967 | 125 |
2530 | 126 init_get_bits(&rc.gb, buf, buf_size*8); |
127 rc.save = 0; | |
128 rc.run = 0; | |
129 rc.run2 = 0; | |
2967 | 130 rc.lossy = l->lossy; |
131 | |
2530 | 132 rc.sum = 8; |
133 rc.count = 1; | |
2967 | 134 |
2530 | 135 /* restore top left pixel */ |
136 val = loco_get_rice(&rc); | |
137 data[0] = 128 + val; | |
138 /* restore top line */ | |
139 for (i = 1; i < width; i++) { | |
140 val = loco_get_rice(&rc); | |
141 data[i * step] = data[i * step - step] + val; | |
142 } | |
143 data += stride; | |
144 for (j = 1; j < height; j++) { | |
145 /* restore left column */ | |
146 val = loco_get_rice(&rc); | |
147 data[0] = data[-stride] + val; | |
148 /* restore all other pixels */ | |
149 for (i = 1; i < width; i++) { | |
150 val = loco_get_rice(&rc); | |
151 data[i * step] = loco_predict(&data[i * step], stride, step) + val; | |
152 } | |
153 data += stride; | |
154 } | |
2967 | 155 |
6750 | 156 return (get_bits_count(&rc.gb) + 7) >> 3; |
2530 | 157 } |
158 | |
2967 | 159 static int decode_frame(AVCodecContext *avctx, |
2530 | 160 void *data, int *data_size, |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8718
diff
changeset
|
161 AVPacket *avpkt) |
2530 | 162 { |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8718
diff
changeset
|
163 const uint8_t *buf = avpkt->data; |
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8718
diff
changeset
|
164 int buf_size = avpkt->size; |
2530 | 165 LOCOContext * const l = avctx->priv_data; |
166 AVFrame * const p= (AVFrame*)&l->pic; | |
167 int decoded; | |
168 | |
169 if(p->data[0]) | |
170 avctx->release_buffer(avctx, p); | |
171 | |
172 p->reference = 0; | |
173 if(avctx->get_buffer(avctx, p) < 0){ | |
174 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
175 return -1; | |
176 } | |
177 p->key_frame = 1; | |
178 | |
179 switch(l->mode) { | |
180 case LOCO_CYUY2: case LOCO_YUY2: case LOCO_UYVY: | |
181 decoded = loco_decode_plane(l, p->data[0], avctx->width, avctx->height, | |
182 p->linesize[0], buf, buf_size, 1); | |
183 buf += decoded; buf_size -= decoded; | |
184 decoded = loco_decode_plane(l, p->data[1], avctx->width / 2, avctx->height, | |
185 p->linesize[1], buf, buf_size, 1); | |
186 buf += decoded; buf_size -= decoded; | |
187 decoded = loco_decode_plane(l, p->data[2], avctx->width / 2, avctx->height, | |
188 p->linesize[2], buf, buf_size, 1); | |
189 break; | |
190 case LOCO_CYV12: case LOCO_YV12: | |
191 decoded = loco_decode_plane(l, p->data[0], avctx->width, avctx->height, | |
192 p->linesize[0], buf, buf_size, 1); | |
193 buf += decoded; buf_size -= decoded; | |
2598
6eaebf1fbd74
Fix colors for YV12 case (u/v planes are swapped)
rtognimp
parents:
2587
diff
changeset
|
194 decoded = loco_decode_plane(l, p->data[2], avctx->width / 2, avctx->height / 2, |
6eaebf1fbd74
Fix colors for YV12 case (u/v planes are swapped)
rtognimp
parents:
2587
diff
changeset
|
195 p->linesize[2], buf, buf_size, 1); |
6eaebf1fbd74
Fix colors for YV12 case (u/v planes are swapped)
rtognimp
parents:
2587
diff
changeset
|
196 buf += decoded; buf_size -= decoded; |
2530 | 197 decoded = loco_decode_plane(l, p->data[1], avctx->width / 2, avctx->height / 2, |
198 p->linesize[1], buf, buf_size, 1); | |
199 break; | |
200 case LOCO_CRGB: case LOCO_RGB: | |
2599
3e36a706f5b7
Fix upside-down picture for BGR24 images (fixes pig-loco-rgb.avi)
rtognimp
parents:
2598
diff
changeset
|
201 decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1), avctx->width, avctx->height, |
3e36a706f5b7
Fix upside-down picture for BGR24 images (fixes pig-loco-rgb.avi)
rtognimp
parents:
2598
diff
changeset
|
202 -p->linesize[0], buf, buf_size, 3); |
2530 | 203 buf += decoded; buf_size -= decoded; |
2599
3e36a706f5b7
Fix upside-down picture for BGR24 images (fixes pig-loco-rgb.avi)
rtognimp
parents:
2598
diff
changeset
|
204 decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1) + 1, avctx->width, avctx->height, |
3e36a706f5b7
Fix upside-down picture for BGR24 images (fixes pig-loco-rgb.avi)
rtognimp
parents:
2598
diff
changeset
|
205 -p->linesize[0], buf, buf_size, 3); |
2530 | 206 buf += decoded; buf_size -= decoded; |
2599
3e36a706f5b7
Fix upside-down picture for BGR24 images (fixes pig-loco-rgb.avi)
rtognimp
parents:
2598
diff
changeset
|
207 decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1) + 2, avctx->width, avctx->height, |
3e36a706f5b7
Fix upside-down picture for BGR24 images (fixes pig-loco-rgb.avi)
rtognimp
parents:
2598
diff
changeset
|
208 -p->linesize[0], buf, buf_size, 3); |
2530 | 209 break; |
210 case LOCO_RGBA: | |
211 decoded = loco_decode_plane(l, p->data[0], avctx->width, avctx->height, | |
212 p->linesize[0], buf, buf_size, 4); | |
213 buf += decoded; buf_size -= decoded; | |
214 decoded = loco_decode_plane(l, p->data[0] + 1, avctx->width, avctx->height, | |
215 p->linesize[0], buf, buf_size, 4); | |
216 buf += decoded; buf_size -= decoded; | |
217 decoded = loco_decode_plane(l, p->data[0] + 2, avctx->width, avctx->height, | |
218 p->linesize[0], buf, buf_size, 4); | |
219 buf += decoded; buf_size -= decoded; | |
220 decoded = loco_decode_plane(l, p->data[0] + 3, avctx->width, avctx->height, | |
221 p->linesize[0], buf, buf_size, 4); | |
222 break; | |
223 } | |
224 | |
225 *data_size = sizeof(AVFrame); | |
226 *(AVFrame*)data = l->pic; | |
2967 | 227 |
2530 | 228 return buf_size; |
229 } | |
230 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6218
diff
changeset
|
231 static av_cold int decode_init(AVCodecContext *avctx){ |
2530 | 232 LOCOContext * const l = avctx->priv_data; |
233 int version; | |
234 | |
235 l->avctx = avctx; | |
236 if (avctx->extradata_size < 12) { | |
237 av_log(avctx, AV_LOG_ERROR, "Extradata size must be >= 12 instead of %i\n", | |
238 avctx->extradata_size); | |
239 return -1; | |
240 } | |
4364 | 241 version = AV_RL32(avctx->extradata); |
2530 | 242 switch(version) { |
243 case 1: | |
244 l->lossy = 0; | |
245 break; | |
246 case 2: | |
4364 | 247 l->lossy = AV_RL32(avctx->extradata + 8); |
2530 | 248 break; |
249 default: | |
4364 | 250 l->lossy = AV_RL32(avctx->extradata + 8); |
2530 | 251 av_log(avctx, AV_LOG_INFO, "This is LOCO codec version %i, please upload file for study\n", version); |
252 } | |
2967 | 253 |
4364 | 254 l->mode = AV_RL32(avctx->extradata + 4); |
2530 | 255 switch(l->mode) { |
256 case LOCO_CYUY2: case LOCO_YUY2: case LOCO_UYVY: | |
257 avctx->pix_fmt = PIX_FMT_YUV422P; | |
258 break; | |
259 case LOCO_CRGB: case LOCO_RGB: | |
260 avctx->pix_fmt = PIX_FMT_BGR24; | |
261 break; | |
262 case LOCO_CYV12: case LOCO_YV12: | |
263 avctx->pix_fmt = PIX_FMT_YUV420P; | |
264 break; | |
2587 | 265 case LOCO_CRGBA: case LOCO_RGBA: |
4494
ce643a22f049
Replace deprecated PIX_FMT names by the newer variants.
diego
parents:
4364
diff
changeset
|
266 avctx->pix_fmt = PIX_FMT_RGB32; |
2530 | 267 break; |
268 default: | |
269 av_log(avctx, AV_LOG_INFO, "Unknown colorspace, index = %i\n", l->mode); | |
270 return -1; | |
271 } | |
2558 | 272 if(avctx->debug & FF_DEBUG_PICT_INFO) |
273 av_log(avctx, AV_LOG_INFO, "lossy:%i, version:%i, mode: %i\n", l->lossy, version, l->mode); | |
2530 | 274 |
275 return 0; | |
276 } | |
277 | |
10399 | 278 static av_cold int decode_end(AVCodecContext *avctx){ |
279 LOCOContext * const l = avctx->priv_data; | |
280 AVFrame *pic = &l->pic; | |
281 | |
282 if (pic->data[0]) | |
283 avctx->release_buffer(avctx, pic); | |
284 | |
285 return 0; | |
286 } | |
287 | |
2530 | 288 AVCodec loco_decoder = { |
289 "loco", | |
290 CODEC_TYPE_VIDEO, | |
291 CODEC_ID_LOCO, | |
292 sizeof(LOCOContext), | |
293 decode_init, | |
294 NULL, | |
10399 | 295 decode_end, |
2530 | 296 decode_frame, |
297 CODEC_CAP_DR1, | |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6750
diff
changeset
|
298 .long_name = NULL_IF_CONFIG_SMALL("LOCO"), |
2530 | 299 }; |