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