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