FFmpeg
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
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
22
/**
23
* @file
24
* LOCO codec.
25
*/
26
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 Sat May 25 2013 04:01:06 for FFmpeg by
1.8.2