Mercurial > libavcodec.hg
annotate loco.c @ 2809:75400dfbe117 libavcodec
fixing colocated mv if colocated block is L1 predicted for the temporal direct case
untested (none of the conformance streams laying around on my disk seems affected by this change)
author | michael |
---|---|
date | Wed, 27 Jul 2005 00:15:55 +0000 |
parents | 3e36a706f5b7 |
children | ef2149182f1c |
rev | line source |
---|---|
2530 | 1 /* |
2 * LOCO codec | |
3 * Copyright (c) 2005 Konstantin Shishkov | |
4 * | |
5 * This library is free software; you can redistribute it and/or | |
6 * modify it under the terms of the GNU Lesser General Public | |
7 * License as published by the Free Software Foundation; either | |
8 * version 2 of the License, or (at your option) any later version. | |
9 * | |
10 * This library is distributed in the hope that it will be useful, | |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 * Lesser General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU Lesser General Public | |
16 * License along with this library; if not, write to the Free Software | |
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
18 * | |
19 */ | |
20 | |
21 /** | |
22 * @file loco.c | |
23 * LOCO codec. | |
24 */ | |
25 | |
26 #include "avcodec.h" | |
27 #include "common.h" | |
28 #include "bitstream.h" | |
29 #include "golomb.h" | |
30 | |
2587 | 31 enum LOCO_MODE {LOCO_UNKN=0, LOCO_CYUY2=-1, LOCO_CRGB=-2, LOCO_CRGBA=-3, LOCO_CYV12=-4, |
2530 | 32 LOCO_YUY2=1, LOCO_UYVY=2, LOCO_RGB=3, LOCO_RGBA=4, LOCO_YV12=5}; |
33 | |
34 typedef struct LOCOContext{ | |
35 AVCodecContext *avctx; | |
36 AVFrame pic; | |
37 int lossy; | |
38 int mode; | |
39 } LOCOContext; | |
40 | |
41 typedef struct RICEContext{ | |
42 GetBitContext gb; | |
43 int save, run, run2; /* internal rice decoder state */ | |
44 int sum, count; /* sum and count for getting rice parameter */ | |
2558 | 45 int lossy; |
2530 | 46 }RICEContext; |
47 | |
48 static int loco_get_rice_param(RICEContext *r) | |
49 { | |
50 int cnt = 0; | |
51 int val = r->count; | |
52 | |
53 while(r->sum > val && cnt < 9) { | |
54 val <<= 1; | |
55 cnt++; | |
56 } | |
57 | |
58 return cnt; | |
59 } | |
60 | |
61 static inline void loco_update_rice_param(RICEContext *r, int val) | |
62 { | |
63 r->sum += val; | |
64 r->count++; | |
65 | |
66 if(r->count == 16) { | |
67 r->sum >>= 1; | |
68 r->count >>= 1; | |
69 } | |
70 } | |
71 | |
72 static inline int loco_get_rice(RICEContext *r) | |
73 { | |
74 int v; | |
75 if (r->run > 0) { /* we have zero run */ | |
76 r->run--; | |
2558 | 77 loco_update_rice_param(r, 0); |
2530 | 78 return 0; |
79 } | |
2558 | 80 v = get_ur_golomb_jpegls(&r->gb, loco_get_rice_param(r), INT_MAX, 0); |
81 loco_update_rice_param(r, (v+1)>>1); | |
2530 | 82 if (!v) { |
83 if (r->save >= 0) { | |
2558 | 84 r->run = get_ur_golomb_jpegls(&r->gb, 2, INT_MAX, 0); |
2530 | 85 if(r->run > 1) |
86 r->save += r->run + 1; | |
87 else | |
88 r->save -= 3; | |
89 } | |
90 else | |
91 r->run2++; | |
2558 | 92 } else { |
93 v = ((v>>1) + r->lossy) ^ -(v&1); | |
94 if (r->run2 > 0) { | |
95 if (r->run2 > 2) | |
96 r->save += r->run2; | |
97 else | |
98 r->save -= 3; | |
99 r->run2 = 0; | |
100 } | |
2530 | 101 } |
102 | |
103 return v; | |
104 } | |
105 | |
106 /* LOCO main predictor - LOCO-I/JPEG-LS predictor */ | |
107 static inline int loco_predict(uint8_t* data, int stride, int step) | |
108 { | |
109 int a, b, c; | |
110 | |
111 a = data[-stride]; | |
112 b = data[-step]; | |
113 c = data[-stride - step]; | |
114 | |
2558 | 115 return mid_pred(a, a + b - c, b); |
2530 | 116 } |
117 | |
118 static int loco_decode_plane(LOCOContext *l, uint8_t *data, int width, int height, | |
119 int stride, uint8_t *buf, int buf_size, int step) | |
120 { | |
121 RICEContext rc; | |
122 int val; | |
123 int i, j; | |
124 | |
125 init_get_bits(&rc.gb, buf, buf_size*8); | |
126 rc.save = 0; | |
127 rc.run = 0; | |
128 rc.run2 = 0; | |
2558 | 129 rc.lossy = l->lossy; |
2530 | 130 |
131 rc.sum = 8; | |
132 rc.count = 1; | |
133 | |
134 /* restore top left pixel */ | |
135 val = loco_get_rice(&rc); | |
136 data[0] = 128 + val; | |
137 /* restore top line */ | |
138 for (i = 1; i < width; i++) { | |
139 val = loco_get_rice(&rc); | |
140 data[i * step] = data[i * step - step] + val; | |
141 } | |
142 data += stride; | |
143 for (j = 1; j < height; j++) { | |
144 /* restore left column */ | |
145 val = loco_get_rice(&rc); | |
146 data[0] = data[-stride] + val; | |
147 /* restore all other pixels */ | |
148 for (i = 1; i < width; i++) { | |
149 val = loco_get_rice(&rc); | |
150 data[i * step] = loco_predict(&data[i * step], stride, step) + val; | |
151 } | |
152 data += stride; | |
153 } | |
154 | |
155 return ((get_bits_count(&rc.gb) + 7) >> 3); | |
156 } | |
157 | |
158 static int decode_frame(AVCodecContext *avctx, | |
159 void *data, int *data_size, | |
160 uint8_t *buf, int buf_size) | |
161 { | |
162 LOCOContext * const l = avctx->priv_data; | |
163 AVFrame * const p= (AVFrame*)&l->pic; | |
164 int decoded; | |
165 | |
166 if(p->data[0]) | |
167 avctx->release_buffer(avctx, p); | |
168 | |
169 p->reference = 0; | |
170 if(avctx->get_buffer(avctx, p) < 0){ | |
171 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
172 return -1; | |
173 } | |
174 p->key_frame = 1; | |
175 | |
176 switch(l->mode) { | |
177 case LOCO_CYUY2: case LOCO_YUY2: case LOCO_UYVY: | |
178 decoded = loco_decode_plane(l, p->data[0], avctx->width, avctx->height, | |
179 p->linesize[0], buf, buf_size, 1); | |
180 buf += decoded; buf_size -= decoded; | |
181 decoded = loco_decode_plane(l, p->data[1], avctx->width / 2, avctx->height, | |
182 p->linesize[1], buf, buf_size, 1); | |
183 buf += decoded; buf_size -= decoded; | |
184 decoded = loco_decode_plane(l, p->data[2], avctx->width / 2, avctx->height, | |
185 p->linesize[2], buf, buf_size, 1); | |
186 break; | |
187 case LOCO_CYV12: case LOCO_YV12: | |
188 decoded = loco_decode_plane(l, p->data[0], avctx->width, avctx->height, | |
189 p->linesize[0], buf, buf_size, 1); | |
190 buf += decoded; buf_size -= decoded; | |
2598
6eaebf1fbd74
Fix colors for YV12 case (u/v planes are swapped)
rtognimp
parents:
2587
diff
changeset
|
191 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
|
192 p->linesize[2], buf, buf_size, 1); |
6eaebf1fbd74
Fix colors for YV12 case (u/v planes are swapped)
rtognimp
parents:
2587
diff
changeset
|
193 buf += decoded; buf_size -= decoded; |
2530 | 194 decoded = loco_decode_plane(l, p->data[1], avctx->width / 2, avctx->height / 2, |
195 p->linesize[1], buf, buf_size, 1); | |
196 break; | |
197 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
|
198 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
|
199 -p->linesize[0], buf, buf_size, 3); |
2530 | 200 buf += decoded; buf_size -= decoded; |
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) + 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) + 2, 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 break; |
207 case LOCO_RGBA: | |
208 decoded = loco_decode_plane(l, p->data[0], avctx->width, avctx->height, | |
209 p->linesize[0], buf, buf_size, 4); | |
210 buf += decoded; buf_size -= decoded; | |
211 decoded = loco_decode_plane(l, p->data[0] + 1, 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] + 2, 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] + 3, avctx->width, avctx->height, | |
218 p->linesize[0], buf, buf_size, 4); | |
219 break; | |
220 } | |
221 | |
222 *data_size = sizeof(AVFrame); | |
223 *(AVFrame*)data = l->pic; | |
224 | |
225 return buf_size; | |
226 } | |
227 | |
228 static int decode_init(AVCodecContext *avctx){ | |
229 LOCOContext * const l = avctx->priv_data; | |
230 int version; | |
231 | |
232 l->avctx = avctx; | |
233 if (avctx->extradata_size < 12) { | |
234 av_log(avctx, AV_LOG_ERROR, "Extradata size must be >= 12 instead of %i\n", | |
235 avctx->extradata_size); | |
236 return -1; | |
237 } | |
238 version = LE_32(avctx->extradata); | |
239 switch(version) { | |
240 case 1: | |
241 l->lossy = 0; | |
242 break; | |
243 case 2: | |
244 l->lossy = LE_32(avctx->extradata + 8); | |
245 break; | |
246 default: | |
247 l->lossy = LE_32(avctx->extradata + 8); | |
248 av_log(avctx, AV_LOG_INFO, "This is LOCO codec version %i, please upload file for study\n", version); | |
249 } | |
250 | |
251 l->mode = LE_32(avctx->extradata + 4); | |
252 switch(l->mode) { | |
253 case LOCO_CYUY2: case LOCO_YUY2: case LOCO_UYVY: | |
254 avctx->pix_fmt = PIX_FMT_YUV422P; | |
255 break; | |
256 case LOCO_CRGB: case LOCO_RGB: | |
257 avctx->pix_fmt = PIX_FMT_BGR24; | |
258 break; | |
259 case LOCO_CYV12: case LOCO_YV12: | |
260 avctx->pix_fmt = PIX_FMT_YUV420P; | |
261 break; | |
2587 | 262 case LOCO_CRGBA: case LOCO_RGBA: |
2530 | 263 avctx->pix_fmt = PIX_FMT_RGBA32; |
264 break; | |
265 default: | |
266 av_log(avctx, AV_LOG_INFO, "Unknown colorspace, index = %i\n", l->mode); | |
267 return -1; | |
268 } | |
2558 | 269 if(avctx->debug & FF_DEBUG_PICT_INFO) |
270 av_log(avctx, AV_LOG_INFO, "lossy:%i, version:%i, mode: %i\n", l->lossy, version, l->mode); | |
2530 | 271 |
272 return 0; | |
273 } | |
274 | |
275 AVCodec loco_decoder = { | |
276 "loco", | |
277 CODEC_TYPE_VIDEO, | |
278 CODEC_ID_LOCO, | |
279 sizeof(LOCOContext), | |
280 decode_init, | |
281 NULL, | |
282 NULL, | |
283 decode_frame, | |
284 CODEC_CAP_DR1, | |
285 }; |