ffmpeg / libavcodec / rtjpeg.c @ 9106a698
History | View | Annotate | Download (5.58 KB)
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 "dsputil.h" |
24 |
#include "rtjpeg.h" |
25 |
|
26 |
#define PUT_COEFF(c) \
|
27 |
i = scan[coeff--]; \ |
28 |
block[i] = (c) * quant[i]; |
29 |
|
30 |
//! aligns the bitstream to the give power of two
|
31 |
#define ALIGN(a) \
|
32 |
n = (-get_bits_count(gb)) & (a - 1); \
|
33 |
if (n) {skip_bits(gb, n);}
|
34 |
|
35 |
/**
|
36 |
* \brief read one block from stream
|
37 |
* \param gb contains stream data
|
38 |
* \param block where data is written to
|
39 |
* \param scan array containing the mapping stream address -> block position
|
40 |
* \param quant quantization factors
|
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, DCTELEM *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 |
// normally we would only need to clear the (63 - coeff) last values,
|
59 |
// but since we do not know where they are we just clear the whole block
|
60 |
memset(block, 0, 64 * sizeof(DCTELEM)); |
61 |
|
62 |
// 2 bits per coefficient
|
63 |
while (coeff) {
|
64 |
ac = get_sbits(gb, 2);
|
65 |
if (ac == -2) |
66 |
break; // continue with more bits |
67 |
PUT_COEFF(ac); |
68 |
} |
69 |
|
70 |
// 4 bits per coefficient
|
71 |
ALIGN(4);
|
72 |
while (coeff) {
|
73 |
ac = get_sbits(gb, 4);
|
74 |
if (ac == -8) |
75 |
break; // continue with more bits |
76 |
PUT_COEFF(ac); |
77 |
} |
78 |
|
79 |
// 8 bits per coefficient
|
80 |
ALIGN(8);
|
81 |
while (coeff) {
|
82 |
ac = get_sbits(gb, 8);
|
83 |
PUT_COEFF(ac); |
84 |
} |
85 |
|
86 |
PUT_COEFF(dc); |
87 |
return 1; |
88 |
} |
89 |
|
90 |
/**
|
91 |
* \brief decode one rtjpeg YUV420 frame
|
92 |
* \param c context, must be initialized via rtjpeg_decode_init
|
93 |
* \param f AVFrame to place decoded frame into. If parts of the frame
|
94 |
* are not coded they are left unchanged, so consider initializing it
|
95 |
* \param buf buffer containing input data
|
96 |
* \param buf_size length of input data in bytes
|
97 |
* \return number of bytes consumed from the input buffer
|
98 |
*/
|
99 |
int rtjpeg_decode_frame_yuv420(RTJpegContext *c, AVFrame *f,
|
100 |
const uint8_t *buf, int buf_size) { |
101 |
DECLARE_ALIGNED_16(DCTELEM, block[64]);
|
102 |
GetBitContext gb; |
103 |
int w = c->w / 16, h = c->h / 16; |
104 |
int x, y;
|
105 |
uint8_t *y1 = f->data[0], *y2 = f->data[0] + 8 * f->linesize[0]; |
106 |
uint8_t *u = f->data[1], *v = f->data[2]; |
107 |
init_get_bits(&gb, buf, buf_size * 8);
|
108 |
for (y = 0; y < h; y++) { |
109 |
for (x = 0; x < w; x++) { |
110 |
if (get_block(&gb, block, c->scan, c->lquant))
|
111 |
c->dsp->idct_put(y1, f->linesize[0], block);
|
112 |
y1 += 8;
|
113 |
if (get_block(&gb, block, c->scan, c->lquant))
|
114 |
c->dsp->idct_put(y1, f->linesize[0], block);
|
115 |
y1 += 8;
|
116 |
if (get_block(&gb, block, c->scan, c->lquant))
|
117 |
c->dsp->idct_put(y2, f->linesize[0], block);
|
118 |
y2 += 8;
|
119 |
if (get_block(&gb, block, c->scan, c->lquant))
|
120 |
c->dsp->idct_put(y2, f->linesize[0], block);
|
121 |
y2 += 8;
|
122 |
if (get_block(&gb, block, c->scan, c->cquant))
|
123 |
c->dsp->idct_put(u, f->linesize[1], block);
|
124 |
u += 8;
|
125 |
if (get_block(&gb, block, c->scan, c->cquant))
|
126 |
c->dsp->idct_put(v, f->linesize[2], block);
|
127 |
v += 8;
|
128 |
} |
129 |
y1 += 2 * 8 * (f->linesize[0] - w); |
130 |
y2 += 2 * 8 * (f->linesize[0] - w); |
131 |
u += 8 * (f->linesize[1] - w); |
132 |
v += 8 * (f->linesize[2] - w); |
133 |
} |
134 |
return get_bits_count(&gb) / 8; |
135 |
} |
136 |
|
137 |
/**
|
138 |
* \brief initialize an RTJpegContext, may be called multiple times
|
139 |
* \param c context to initialize
|
140 |
* \param dsp specifies the idct to use for decoding
|
141 |
* \param width width of image, will be rounded down to the nearest multiple
|
142 |
* of 16 for decoding
|
143 |
* \param height height of image, will be rounded down to the nearest multiple
|
144 |
* of 16 for decoding
|
145 |
* \param lquant luma quantization table to use
|
146 |
* \param cquant chroma quantization table to use
|
147 |
*/
|
148 |
void rtjpeg_decode_init(RTJpegContext *c, DSPContext *dsp,
|
149 |
int width, int height, |
150 |
const uint32_t *lquant, const uint32_t *cquant) { |
151 |
int i;
|
152 |
c->dsp = dsp; |
153 |
for (i = 0; i < 64; i++) { |
154 |
int z = ff_zigzag_direct[i];
|
155 |
int p = c->dsp->idct_permutation[i];
|
156 |
z = ((z << 3) | (z >> 3)) & 63; // rtjpeg uses a transposed variant |
157 |
|
158 |
// permute the scan and quantization tables for the chosen idct
|
159 |
c->scan[i] = c->dsp->idct_permutation[z]; |
160 |
c->lquant[p] = lquant[i]; |
161 |
c->cquant[p] = cquant[i]; |
162 |
} |
163 |
c->w = width; |
164 |
c->h = height; |
165 |
} |