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