Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavcodec
eatqi.c
Go to the documentation of this file.
1
/*
2
* Electronic Arts TQI Video Decoder
3
* Copyright (c) 2007-2009 Peter Ross <pross@xvid.org>
4
*
5
* This file is part of Libav.
6
*
7
* Libav 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
* Libav 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 Libav; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
*/
21
29
#include "
avcodec.h
"
30
#include "
get_bits.h
"
31
#include "
dsputil.h
"
32
#include "
aandcttab.h
"
33
#include "
mpeg12.h
"
34
#include "
mpegvideo.h
"
35
36
typedef
struct
TqiContext
{
37
MpegEncContext
s
;
38
AVFrame
frame
;
39
void
*
bitstream_buf
;
40
unsigned
int
bitstream_buf_size
;
41
DECLARE_ALIGNED
(16,
DCTELEM
,
block
)[6][64];
42
}
TqiContext
;
43
44
static
av_cold
int
tqi_decode_init
(
AVCodecContext
*avctx)
45
{
46
TqiContext
*
t
= avctx->
priv_data
;
47
MpegEncContext
*s = &t->
s
;
48
s->
avctx
= avctx;
49
if
(avctx->
idct_algo
==
FF_IDCT_AUTO
)
50
avctx->
idct_algo
=
FF_IDCT_EA
;
51
dsputil_init
(&s->
dsp
, avctx);
52
ff_init_scantable
(s->
dsp
.
idct_permutation
, &s->
intra_scantable
,
ff_zigzag_direct
);
53
s->
qscale
= 1;
54
avctx->
time_base
= (
AVRational
){1, 15};
55
avctx->
pix_fmt
=
PIX_FMT_YUV420P
;
56
ff_mpeg12_init_vlcs
();
57
return
0;
58
}
59
60
static
int
tqi_decode_mb
(
MpegEncContext
*s,
DCTELEM
(*
block
)[64])
61
{
62
int
n;
63
s->
dsp
.
clear_blocks
(
block
[0]);
64
for
(n=0; n<6; n++)
65
if
(
ff_mpeg1_decode_block_intra
(s,
block
[n], n) < 0)
66
return
-1;
67
68
return
0;
69
}
70
71
static
inline
void
tqi_idct_put
(
TqiContext
*
t
,
DCTELEM
(*
block
)[64])
72
{
73
MpegEncContext
*s = &t->
s
;
74
int
linesize= t->
frame
.
linesize
[0];
75
uint8_t *dest_y = t->
frame
.
data
[0] + (s->
mb_y
* 16* linesize ) + s->
mb_x
* 16;
76
uint8_t *dest_cb = t->
frame
.
data
[1] + (s->
mb_y
* 8 * t->
frame
.
linesize
[1]) + s->
mb_x
* 8;
77
uint8_t *dest_cr = t->
frame
.
data
[2] + (s->
mb_y
* 8 * t->
frame
.
linesize
[2]) + s->
mb_x
* 8;
78
79
s->
dsp
.
idct_put
(dest_y , linesize,
block
[0]);
80
s->
dsp
.
idct_put
(dest_y + 8, linesize,
block
[1]);
81
s->
dsp
.
idct_put
(dest_y + 8*linesize , linesize,
block
[2]);
82
s->
dsp
.
idct_put
(dest_y + 8*linesize + 8, linesize,
block
[3]);
83
if
(!(s->
avctx
->
flags
&
CODEC_FLAG_GRAY
)) {
84
s->
dsp
.
idct_put
(dest_cb, t->
frame
.
linesize
[1],
block
[4]);
85
s->
dsp
.
idct_put
(dest_cr, t->
frame
.
linesize
[2],
block
[5]);
86
}
87
}
88
89
static
void
tqi_calculate_qtable
(
MpegEncContext
*s,
int
quant
)
90
{
91
const
int
qscale = (215 - 2*
quant
)*5;
92
int
i;
93
if
(s->
avctx
->
idct_algo
==
FF_IDCT_EA
) {
94
s->
intra_matrix
[0] = (
ff_inv_aanscales
[0]*
ff_mpeg1_default_intra_matrix
[0])>>11;
95
for
(i=1; i<64; i++)
96
s->
intra_matrix
[i] = (
ff_inv_aanscales
[i]*
ff_mpeg1_default_intra_matrix
[i]*qscale + 32)>>14;
97
}
else
{
98
s->
intra_matrix
[0] =
ff_mpeg1_default_intra_matrix
[0];
99
for
(i=1; i<64; i++)
100
s->
intra_matrix
[i] = (
ff_mpeg1_default_intra_matrix
[i]*qscale + 32)>>3;
101
}
102
}
103
104
static
int
tqi_decode_frame
(
AVCodecContext
*avctx,
105
void
*
data
,
int
*data_size,
106
AVPacket
*avpkt)
107
{
108
const
uint8_t *buf = avpkt->
data
;
109
int
buf_size = avpkt->
size
;
110
const
uint8_t *buf_end = buf+buf_size;
111
TqiContext
*t = avctx->
priv_data
;
112
MpegEncContext
*s = &t->
s
;
113
114
s->
width
=
AV_RL16
(&buf[0]);
115
s->
height
=
AV_RL16
(&buf[2]);
116
tqi_calculate_qtable
(s, buf[4]);
117
buf += 8;
118
119
if
(t->
frame
.
data
[0])
120
avctx->
release_buffer
(avctx, &t->
frame
);
121
122
if
(s->
avctx
->
width
!=s->
width
|| s->
avctx
->
height
!=s->
height
)
123
avcodec_set_dimensions
(s->
avctx
, s->
width
, s->
height
);
124
125
if
(avctx->
get_buffer
(avctx, &t->
frame
) < 0) {
126
av_log
(avctx,
AV_LOG_ERROR
,
"get_buffer() failed\n"
);
127
return
-1;
128
}
129
130
av_fast_malloc
(&t->
bitstream_buf
, &t->
bitstream_buf_size
, (buf_end-buf) +
FF_INPUT_BUFFER_PADDING_SIZE
);
131
if
(!t->
bitstream_buf
)
132
return
AVERROR
(ENOMEM);
133
s->
dsp
.
bswap_buf
(t->
bitstream_buf
, (
const
uint32_t*)buf, (buf_end-buf)/4);
134
init_get_bits
(&s->
gb
, t->
bitstream_buf
, 8*(buf_end-buf));
135
136
s->
last_dc
[0] = s->
last_dc
[1] = s->
last_dc
[2] = 0;
137
for
(s->
mb_y
=0; s->
mb_y
<(avctx->
height
+15)/16; s->
mb_y
++)
138
for
(s->
mb_x
=0; s->
mb_x
<(avctx->
width
+15)/16; s->
mb_x
++)
139
{
140
if
(
tqi_decode_mb
(s, t->
block
) < 0)
141
break
;
142
tqi_idct_put
(t, t->
block
);
143
}
144
145
*data_size =
sizeof
(
AVFrame
);
146
*(
AVFrame
*)data = t->
frame
;
147
return
buf_size;
148
}
149
150
static
av_cold
int
tqi_decode_end
(
AVCodecContext
*avctx)
151
{
152
TqiContext
*t = avctx->
priv_data
;
153
if
(t->
frame
.
data
[0])
154
avctx->
release_buffer
(avctx, &t->
frame
);
155
av_free
(t->
bitstream_buf
);
156
return
0;
157
}
158
159
AVCodec
ff_eatqi_decoder
= {
160
.
name
=
"eatqi"
,
161
.type =
AVMEDIA_TYPE_VIDEO
,
162
.id =
CODEC_ID_TQI
,
163
.priv_data_size =
sizeof
(
TqiContext
),
164
.
init
=
tqi_decode_init
,
165
.
close
=
tqi_decode_end
,
166
.
decode
=
tqi_decode_frame
,
167
.capabilities =
CODEC_CAP_DR1
,
168
.long_name =
NULL_IF_CONFIG_SMALL
(
"Electronic Arts TQI Video"
),
169
};