FFmpeg
1.2.4
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavcodec
loco.c
Go to the documentation of this file.
1
/*
2
* LOCO codec
3
* Copyright (c) 2005 Konstantin Shishkov
4
*
5
* This file is part of FFmpeg.
6
*
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.
11
*
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.
16
*
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
20
*/
21
27
#include "
avcodec.h
"
28
#include "
get_bits.h
"
29
#include "
golomb.h
"
30
#include "
internal.h
"
31
#include "
mathops.h
"
32
33
enum
LOCO_MODE
{
34
LOCO_UNKN
= 0,
35
LOCO_CYUY2
= -1,
36
LOCO_CRGB
= -2,
37
LOCO_CRGBA
= -3,
38
LOCO_CYV12
= -4,
39
LOCO_YUY2
= 1,
40
LOCO_UYVY
= 2,
41
LOCO_RGB
= 3,
42
LOCO_RGBA
= 4,
43
LOCO_YV12
= 5,
44
};
45
46
typedef
struct
LOCOContext
{
47
AVCodecContext
*
avctx
;
48
AVFrame
pic
;
49
int
lossy
;
50
int
mode
;
51
}
LOCOContext
;
52
53
typedef
struct
RICEContext
{
54
GetBitContext
gb
;
55
int
save
,
run
,
run2
;
/* internal rice decoder state */
56
int
sum
,
count
;
/* sum and count for getting rice parameter */
57
int
lossy
;
58
}
RICEContext
;
59
60
static
int
loco_get_rice_param
(
RICEContext
*
r
)
61
{
62
int
cnt = 0;
63
int
val = r->
count
;
64
65
while
(r->
sum
> val && cnt < 9) {
66
val <<= 1;
67
cnt++;
68
}
69
70
return
cnt;
71
}
72
73
static
inline
void
loco_update_rice_param
(
RICEContext
*
r
,
int
val)
74
{
75
r->
sum
+= val;
76
r->
count
++;
77
78
if
(r->
count
== 16) {
79
r->
sum
>>= 1;
80
r->
count
>>= 1;
81
}
82
}
83
84
static
inline
int
loco_get_rice
(
RICEContext
*
r
)
85
{
86
int
v
;
87
if
(r->
run
> 0) {
/* we have zero run */
88
r->
run
--;
89
loco_update_rice_param
(r, 0);
90
return
0;
91
}
92
v =
get_ur_golomb_jpegls
(&r->
gb
,
loco_get_rice_param
(r), INT_MAX, 0);
93
loco_update_rice_param
(r, (v + 1) >> 1);
94
if
(!v) {
95
if
(r->
save
>= 0) {
96
r->
run
=
get_ur_golomb_jpegls
(&r->
gb
, 2, INT_MAX, 0);
97
if
(r->
run
> 1)
98
r->
save
+= r->
run
+ 1;
99
else
100
r->
save
-= 3;
101
}
else
102
r->
run2
++;
103
}
else
{
104
v = ((v >> 1) + r->
lossy
) ^ -(v & 1);
105
if
(r->
run2
> 0) {
106
if
(r->
run2
> 2)
107
r->
save
+= r->
run2
;
108
else
109
r->
save
-= 3;
110
r->
run2
= 0;
111
}
112
}
113
114
return
v
;
115
}
116
117
/* LOCO main predictor - LOCO-I/JPEG-LS predictor */
118
static
inline
int
loco_predict
(
uint8_t
*
data
,
int
stride
,
int
step)
119
{
120
int
a
,
b
,
c
;
121
122
a = data[-
stride
];
123
b = data[-step];
124
c = data[-stride - step];
125
126
return
mid_pred
(a, a + b - c, b);
127
}
128
129
static
int
loco_decode_plane
(
LOCOContext
*l,
uint8_t
*
data
,
int
width
,
int
height
,
130
int
stride
,
const
uint8_t
*buf,
int
buf_size,
int
step)
131
{
132
RICEContext
rc;
133
int
val;
134
int
i, j;
135
136
if
(buf_size<=0)
137
return
-1;
138
139
init_get_bits
(&rc.
gb
, buf, buf_size*8);
140
rc.
save
= 0;
141
rc.
run
= 0;
142
rc.
run2
= 0;
143
rc.
lossy
= l->
lossy
;
144
145
rc.
sum
= 8;
146
rc.
count
= 1;
147
148
/* restore top left pixel */
149
val =
loco_get_rice
(&rc);
150
data[0] = 128 + val;
151
/* restore top line */
152
for
(i = 1; i <
width
; i++) {
153
val =
loco_get_rice
(&rc);
154
data[i * step] = data[i * step - step] + val;
155
}
156
data +=
stride
;
157
for
(j = 1; j <
height
; j++) {
158
/* restore left column */
159
val =
loco_get_rice
(&rc);
160
data[0] = data[-
stride
] + val;
161
/* restore all other pixels */
162
for
(i = 1; i <
width
; i++) {
163
val =
loco_get_rice
(&rc);
164
data[i * step] =
loco_predict
(&data[i * step], stride, step) + val;
165
}
166
data +=
stride
;
167
}
168
169
return
(
get_bits_count
(&rc.
gb
) + 7) >> 3;
170
}
171
172
static
int
decode_frame
(
AVCodecContext
*avctx,
173
void
*
data
,
int
*got_frame,
174
AVPacket
*avpkt)
175
{
176
LOCOContext
*
const
l = avctx->
priv_data
;
177
const
uint8_t
*buf = avpkt->
data
;
178
int
buf_size = avpkt->
size
;
179
AVFrame
*
const
p = &l->
pic
;
180
int
decoded, ret;
181
182
if
(p->
data
[0])
183
avctx->
release_buffer
(avctx, p);
184
185
p->
reference
= 0;
186
if
((ret =
ff_get_buffer
(avctx, p)) < 0) {
187
av_log
(avctx,
AV_LOG_ERROR
,
"get_buffer() failed\n"
);
188
return
ret;
189
}
190
p->
key_frame
= 1;
191
192
#define ADVANCE_BY_DECODED do { \
193
if (decoded < 0 || decoded >= buf_size) goto buf_too_small; \
194
buf += decoded; buf_size -= decoded; \
195
} while(0)
196
switch
(l->
mode
) {
197
case
LOCO_CYUY2
:
case
LOCO_YUY2
:
case
LOCO_UYVY
:
198
decoded =
loco_decode_plane
(l, p->
data
[0], avctx->
width
, avctx->
height
,
199
p->
linesize
[0], buf, buf_size, 1);
200
ADVANCE_BY_DECODED
;
201
decoded =
loco_decode_plane
(l, p->
data
[1], avctx->
width
/ 2, avctx->
height
,
202
p->
linesize
[1], buf, buf_size, 1);
203
ADVANCE_BY_DECODED
;
204
decoded =
loco_decode_plane
(l, p->
data
[2], avctx->
width
/ 2, avctx->
height
,
205
p->
linesize
[2], buf, buf_size, 1);
206
break
;
207
case
LOCO_CYV12
:
case
LOCO_YV12
:
208
decoded =
loco_decode_plane
(l, p->
data
[0], avctx->
width
, avctx->
height
,
209
p->
linesize
[0], buf, buf_size, 1);
210
ADVANCE_BY_DECODED
;
211
decoded =
loco_decode_plane
(l, p->
data
[2], avctx->
width
/ 2, avctx->
height
/ 2,
212
p->
linesize
[2], buf, buf_size, 1);
213
ADVANCE_BY_DECODED
;
214
decoded =
loco_decode_plane
(l, p->
data
[1], avctx->
width
/ 2, avctx->
height
/ 2,
215
p->
linesize
[1], buf, buf_size, 1);
216
break
;
217
case
LOCO_CRGB
:
case
LOCO_RGB
:
218
decoded =
loco_decode_plane
(l, p->
data
[0] + p->
linesize
[0]*(avctx->
height
-1), avctx->
width
, avctx->
height
,
219
-p->
linesize
[0], buf, buf_size, 3);
220
ADVANCE_BY_DECODED
;
221
decoded =
loco_decode_plane
(l, p->
data
[0] + p->
linesize
[0]*(avctx->
height
-1) + 1, avctx->
width
, avctx->
height
,
222
-p->
linesize
[0], buf, buf_size, 3);
223
ADVANCE_BY_DECODED
;
224
decoded =
loco_decode_plane
(l, p->
data
[0] + p->
linesize
[0]*(avctx->
height
-1) + 2, avctx->
width
, avctx->
height
,
225
-p->
linesize
[0], buf, buf_size, 3);
226
break
;
227
case
LOCO_CRGBA
:
228
case
LOCO_RGBA
:
229
decoded =
loco_decode_plane
(l, p->
data
[0] + p->
linesize
[0]*(avctx->
height
-1), avctx->
width
, avctx->
height
,
230
-p->
linesize
[0], buf, buf_size, 4);
231
ADVANCE_BY_DECODED
;
232
decoded =
loco_decode_plane
(l, p->
data
[0] + p->
linesize
[0]*(avctx->
height
-1) + 1, avctx->
width
, avctx->
height
,
233
-p->
linesize
[0], buf, buf_size, 4);
234
ADVANCE_BY_DECODED
;
235
decoded =
loco_decode_plane
(l, p->
data
[0] + p->
linesize
[0]*(avctx->
height
-1) + 2, avctx->
width
, avctx->
height
,
236
-p->
linesize
[0], buf, buf_size, 4);
237
ADVANCE_BY_DECODED
;
238
decoded =
loco_decode_plane
(l, p->
data
[0] + p->
linesize
[0]*(avctx->
height
-1) + 3, avctx->
width
, avctx->
height
,
239
-p->
linesize
[0], buf, buf_size, 4);
240
break
;
241
default
:
242
av_assert0
(0);
243
}
244
245
if
(decoded < 0 || decoded > buf_size)
246
goto
buf_too_small;
247
buf_size -= decoded;
248
249
*got_frame = 1;
250
*(
AVFrame
*)data = l->
pic
;
251
252
return
avpkt->
size
- buf_size;
253
buf_too_small:
254
av_log
(avctx,
AV_LOG_ERROR
,
"Input data too small.\n"
);
255
return
AVERROR
(EINVAL);
256
}
257
258
static
av_cold
int
decode_init
(
AVCodecContext
*avctx)
259
{
260
LOCOContext
*
const
l = avctx->
priv_data
;
261
int
version
;
262
263
l->
avctx
= avctx;
264
if
(avctx->
extradata_size
< 12) {
265
av_log
(avctx,
AV_LOG_ERROR
,
"Extradata size must be >= 12 instead of %i\n"
,
266
avctx->
extradata_size
);
267
return
AVERROR_INVALIDDATA
;
268
}
269
version =
AV_RL32
(avctx->
extradata
);
270
switch
(version) {
271
case
1:
272
l->
lossy
= 0;
273
break
;
274
case
2:
275
l->
lossy
=
AV_RL32
(avctx->
extradata
+ 8);
276
break
;
277
default
:
278
l->
lossy
=
AV_RL32
(avctx->
extradata
+ 8);
279
av_log_ask_for_sample
(avctx,
"This is LOCO codec version %i.\n"
, version);
280
}
281
282
l->
mode
=
AV_RL32
(avctx->
extradata
+ 4);
283
switch
(l->
mode
) {
284
case
LOCO_CYUY2
:
285
case
LOCO_YUY2
:
286
case
LOCO_UYVY
:
287
avctx->
pix_fmt
=
AV_PIX_FMT_YUV422P
;
288
break
;
289
case
LOCO_CRGB
:
290
case
LOCO_RGB
:
291
avctx->
pix_fmt
=
AV_PIX_FMT_BGR24
;
292
break
;
293
case
LOCO_CYV12
:
294
case
LOCO_YV12
:
295
avctx->
pix_fmt
=
AV_PIX_FMT_YUV420P
;
296
break
;
297
case
LOCO_CRGBA
:
298
case
LOCO_RGBA
:
299
avctx->
pix_fmt
=
AV_PIX_FMT_BGRA
;
300
break
;
301
default
:
302
av_log
(avctx,
AV_LOG_INFO
,
"Unknown colorspace, index = %i\n"
, l->
mode
);
303
return
AVERROR_INVALIDDATA
;
304
}
305
if
(avctx->
debug
&
FF_DEBUG_PICT_INFO
)
306
av_log
(avctx,
AV_LOG_INFO
,
"lossy:%i, version:%i, mode: %i\n"
, l->
lossy
, version, l->
mode
);
307
308
avcodec_get_frame_defaults
(&l->
pic
);
309
310
return
0;
311
}
312
313
static
av_cold
int
decode_end
(
AVCodecContext
*avctx)
314
{
315
LOCOContext
*
const
l = avctx->
priv_data
;
316
AVFrame
*pic = &l->
pic
;
317
318
if
(pic->
data
[0])
319
avctx->
release_buffer
(avctx, pic);
320
321
return
0;
322
}
323
324
AVCodec
ff_loco_decoder
= {
325
.
name
=
"loco"
,
326
.type =
AVMEDIA_TYPE_VIDEO
,
327
.id =
AV_CODEC_ID_LOCO
,
328
.priv_data_size =
sizeof
(
LOCOContext
),
329
.
init
=
decode_init
,
330
.
close
=
decode_end
,
331
.
decode
=
decode_frame
,
332
.capabilities =
CODEC_CAP_DR1
,
333
.long_name =
NULL_IF_CONFIG_SMALL
(
"LOCO"
),
334
};
Generated on Fri Nov 29 2013 19:15:03 for FFmpeg by
1.8.1.2