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