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