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
rtjpeg.c
Go to the documentation of this file.
1
/*
2
* RTJpeg decoding functions
3
* Copyright (c) 2006 Reimar Doeffinger
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
#include "
libavutil/common.h
"
22
#include "
get_bits.h
"
23
#include "
rtjpeg.h
"
24
25
#define PUT_COEFF(c) \
26
i = scan[coeff--]; \
27
block[i] = (c) * quant[i];
28
29
/// aligns the bitstream to the given power of two
30
#define ALIGN(a) \
31
n = (-get_bits_count(gb)) & (a - 1); \
32
if (n) {skip_bits(gb, n);}
33
34
/**
35
* @brief read one block from stream
36
* @param gb contains stream data
37
* @param block where data is written to
38
* @param scan array containing the mapping stream address -> block position
39
* @param quant quantization factors
40
* @return 0 means the block is not coded, < 0 means an error occurred.
41
*
42
* Note: GetBitContext is used to make the code simpler, since all data is
43
* aligned this could be done faster in a different way, e.g. as it is done
44
* in MPlayer libmpcodecs/native/rtjpegn.c.
45
*/
46
static
inline
int
get_block
(
GetBitContext
*gb, int16_t *
block
,
const
uint8_t
*scan,
47
const
uint32_t *
quant
) {
48
int
coeff
, i,
n
;
49
int8_t ac;
50
uint8_t
dc
=
get_bits
(gb, 8);
51
52
// block not coded
53
if
(dc == 255)
54
return
0;
55
56
// number of non-zero coefficients
57
coeff =
get_bits
(gb, 6);
58
if
(
get_bits_left
(gb) < (coeff << 1))
59
return
AVERROR_INVALIDDATA
;
60
61
// normally we would only need to clear the (63 - coeff) last values,
62
// but since we do not know where they are we just clear the whole block
63
memset(block, 0, 64 *
sizeof
(int16_t));
64
65
// 2 bits per coefficient
66
while
(coeff) {
67
ac =
get_sbits
(gb, 2);
68
if
(ac == -2)
69
break
;
// continue with more bits
70
PUT_COEFF
(ac);
71
}
72
73
// 4 bits per coefficient
74
ALIGN
(4);
75
if
(
get_bits_left
(gb) < (coeff << 2))
76
return
AVERROR_INVALIDDATA
;
77
while
(coeff) {
78
ac =
get_sbits
(gb, 4);
79
if
(ac == -8)
80
break
;
// continue with more bits
81
PUT_COEFF
(ac);
82
}
83
84
// 8 bits per coefficient
85
ALIGN
(8);
86
if
(
get_bits_left
(gb) < (coeff << 3))
87
return
AVERROR_INVALIDDATA
;
88
while
(coeff) {
89
ac =
get_sbits
(gb, 8);
90
PUT_COEFF
(ac);
91
}
92
93
PUT_COEFF
(dc);
94
return
1;
95
}
96
97
/**
98
* @brief decode one rtjpeg YUV420 frame
99
* @param c context, must be initialized via ff_rtjpeg_decode_init
100
* @param f AVFrame to place decoded frame into. If parts of the frame
101
* are not coded they are left unchanged, so consider initializing it
102
* @param buf buffer containing input data
103
* @param buf_size length of input data in bytes
104
* @return number of bytes consumed from the input buffer
105
*/
106
int
ff_rtjpeg_decode_frame_yuv420
(
RTJpegContext
*
c
,
AVFrame
*f,
107
const
uint8_t
*
buf
,
int
buf_size) {
108
GetBitContext
gb;
109
int
w = c->
w
/ 16, h = c->
h
/ 16;
110
int
x,
y
,
ret
;
111
uint8_t
*y1 = f->
data
[0], *y2 = f->
data
[0] + 8 * f->
linesize
[0];
112
uint8_t
*
u
= f->
data
[1], *
v
= f->
data
[2];
113
114
if
((ret =
init_get_bits8
(&gb, buf, buf_size)) < 0)
115
return
ret
;
116
117
for
(y = 0; y < h; y++) {
118
for
(x = 0; x < w; x++) {
119
#define BLOCK(quant, dst, stride) do { \
120
int res = get_block(&gb, block, c->scan, quant); \
121
if (res < 0) \
122
return res; \
123
if (res > 0) \
124
c->idsp.idct_put(dst, stride, block); \
125
} while (0)
126
int16_t *
block
= c->
block
;
127
BLOCK
(c->
lquant
, y1, f->
linesize
[0]);
128
y1 += 8;
129
BLOCK
(c->
lquant
, y1, f->
linesize
[0]);
130
y1 += 8;
131
BLOCK
(c->
lquant
, y2, f->
linesize
[0]);
132
y2 += 8;
133
BLOCK
(c->
lquant
, y2, f->
linesize
[0]);
134
y2 += 8;
135
BLOCK
(c->
cquant
, u, f->
linesize
[1]);
136
u += 8;
137
BLOCK
(c->
cquant
,
v
, f->
linesize
[2]);
138
v
+= 8;
139
}
140
y1 += 2 * 8 * (f->
linesize
[0] - w);
141
y2 += 2 * 8 * (f->
linesize
[0] - w);
142
u += 8 * (f->
linesize
[1] - w);
143
v
+= 8 * (f->
linesize
[2] - w);
144
}
145
return
get_bits_count
(&gb) / 8;
146
}
147
148
/**
149
* @brief initialize an RTJpegContext, may be called multiple times
150
* @param c context to initialize
151
* @param width width of image, will be rounded down to the nearest multiple
152
* of 16 for decoding
153
* @param height height of image, will be rounded down to the nearest multiple
154
* of 16 for decoding
155
* @param lquant luma quantization table to use
156
* @param cquant chroma quantization table to use
157
*/
158
void
ff_rtjpeg_decode_init
(
RTJpegContext
*
c
,
int
width
,
int
height
,
159
const
uint32_t *lquant,
const
uint32_t *cquant) {
160
int
i;
161
for
(i = 0; i < 64; i++) {
162
int
p = c->
idsp
.
idct_permutation
[i];
163
c->
lquant
[p] = lquant[i];
164
c->
cquant
[p] = cquant[i];
165
}
166
c->
w
=
width
;
167
c->
h
=
height
;
168
}
169
170
void
ff_rtjpeg_init
(
RTJpegContext
*
c
,
AVCodecContext
*avctx)
171
{
172
int
i;
173
174
ff_idctdsp_init
(&c->
idsp
, avctx);
175
176
for
(i = 0; i < 64; i++) {
177
int
z =
ff_zigzag_direct
[i];
178
z = ((z << 3) | (z >> 3)) & 63;
// rtjpeg uses a transposed variant
179
180
// permute the scan and quantization tables for the chosen idct
181
c->
scan
[i] = c->
idsp
.
idct_permutation
[z];
182
}
183
}
Generated on Sun Sep 14 2014 18:56:03 for FFmpeg by
1.8.2