Mercurial > libavcodec.hg
annotate eatqi.c @ 9930:32e856bd5ded libavcodec
Check for CONFIG_LIBFOO_DECODER/CONFIG_LIBFOO_ENCODER instead of just
CONFIG_LIBFOO in the external libraries section.
This is more consistent with the rest of the Makefiles, it makes clearer what
is actually implemented and should be advantageous if we implement an external
library encoder where we previously just had the decoder and vice versa.
author | diego |
---|---|
date | Tue, 07 Jul 2009 09:33:08 +0000 |
parents | 3dcbde0de577 |
children | 34a65026fa06 |
rev | line source |
---|---|
8745 | 1 /* |
2 * Electronic Arts TQI Video Decoder | |
3 * Copyright (c) 2007-2009 Peter Ross <pross@xvid.org> | |
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 St, Fifth Floor, Boston, MA 02110-1301 USA | |
20 */ | |
21 | |
22 /** | |
23 * @file eatqi.c | |
24 * Electronic Arts TQI Video Decoder | |
25 * by Peter Ross <pross@xvid.org> | |
26 * | |
27 * Technical details here: | |
28 * http://wiki.multimedia.cx/index.php?title=Electronic_Arts_TQI | |
29 */ | |
30 | |
31 #include "avcodec.h" | |
9428 | 32 #include "get_bits.h" |
8745 | 33 #include "dsputil.h" |
34 #include "aandcttab.h" | |
35 #include "mpeg12.h" | |
36 #include "mpegvideo.h" | |
37 | |
38 typedef struct TqiContext { | |
39 MpegEncContext s; | |
40 AVFrame frame; | |
9414
5a738e8f9524
Use void * instead of uint8_t * for the destination buffer for dsp.bswap_buf
reimar
parents:
9413
diff
changeset
|
41 void *bitstream_buf; |
8745 | 42 unsigned int bitstream_buf_size; |
9702
3dcbde0de577
eatqi: move "block" variable into context to ensure sufficient alignment for
reimar
parents:
9428
diff
changeset
|
43 DECLARE_ALIGNED_16(DCTELEM, block[6][64]); |
8745 | 44 } TqiContext; |
45 | |
46 static av_cold int tqi_decode_init(AVCodecContext *avctx) | |
47 { | |
48 TqiContext *t = avctx->priv_data; | |
49 MpegEncContext *s = &t->s; | |
50 s->avctx = avctx; | |
51 if(avctx->idct_algo==FF_IDCT_AUTO) | |
52 avctx->idct_algo=FF_IDCT_EA; | |
53 dsputil_init(&s->dsp, avctx); | |
54 ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct); | |
55 s->qscale = 1; | |
56 avctx->time_base = (AVRational){1, 15}; | |
57 avctx->pix_fmt = PIX_FMT_YUV420P; | |
58 ff_mpeg12_init_vlcs(); | |
59 return 0; | |
60 } | |
61 | |
62 static void tqi_decode_mb(MpegEncContext *s, DCTELEM (*block)[64]) | |
63 { | |
64 int n; | |
8755 | 65 s->dsp.clear_blocks(block[0]); |
8745 | 66 for (n=0; n<6; n++) |
67 ff_mpeg1_decode_block_intra(s, block[n], n); | |
68 } | |
69 | |
70 static inline void tqi_idct_put(TqiContext *t, DCTELEM (*block)[64]) | |
71 { | |
72 MpegEncContext *s = &t->s; | |
73 int linesize= t->frame.linesize[0]; | |
74 uint8_t *dest_y = t->frame.data[0] + (s->mb_y * 16* linesize ) + s->mb_x * 16; | |
75 uint8_t *dest_cb = t->frame.data[1] + (s->mb_y * 8 * t->frame.linesize[1]) + s->mb_x * 8; | |
76 uint8_t *dest_cr = t->frame.data[2] + (s->mb_y * 8 * t->frame.linesize[2]) + s->mb_x * 8; | |
77 | |
78 s->dsp.idct_put(dest_y , linesize, block[0]); | |
79 s->dsp.idct_put(dest_y + 8, linesize, block[1]); | |
80 s->dsp.idct_put(dest_y + 8*linesize , linesize, block[2]); | |
81 s->dsp.idct_put(dest_y + 8*linesize + 8, linesize, block[3]); | |
82 if(!(s->avctx->flags&CODEC_FLAG_GRAY)) { | |
83 s->dsp.idct_put(dest_cb, t->frame.linesize[1], block[4]); | |
84 s->dsp.idct_put(dest_cr, t->frame.linesize[2], block[5]); | |
85 } | |
86 } | |
87 | |
88 static void tqi_calculate_qtable(MpegEncContext *s, int quant) | |
89 { | |
90 const int qscale = (215 - 2*quant)*5; | |
91 int i; | |
92 if (s->avctx->idct_algo==FF_IDCT_EA) { | |
93 s->intra_matrix[0] = (ff_inv_aanscales[0]*ff_mpeg1_default_intra_matrix[0])>>11; | |
94 for(i=1; i<64; i++) | |
95 s->intra_matrix[i] = (ff_inv_aanscales[i]*ff_mpeg1_default_intra_matrix[i]*qscale + 32)>>14; | |
96 }else{ | |
97 s->intra_matrix[0] = ff_mpeg1_default_intra_matrix[0]; | |
98 for(i=1; i<64; i++) | |
99 s->intra_matrix[i] = (ff_mpeg1_default_intra_matrix[i]*qscale + 32)>>3; | |
100 } | |
101 } | |
102 | |
103 static int tqi_decode_frame(AVCodecContext *avctx, | |
104 void *data, int *data_size, | |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8755
diff
changeset
|
105 AVPacket *avpkt) |
8745 | 106 { |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8755
diff
changeset
|
107 const uint8_t *buf = avpkt->data; |
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8755
diff
changeset
|
108 int buf_size = avpkt->size; |
8745 | 109 const uint8_t *buf_end = buf+buf_size; |
110 TqiContext *t = avctx->priv_data; | |
111 MpegEncContext *s = &t->s; | |
112 | |
113 s->width = AV_RL16(&buf[0]); | |
114 s->height = AV_RL16(&buf[2]); | |
115 tqi_calculate_qtable(s, buf[4]); | |
116 buf += 8; | |
117 | |
118 if (t->frame.data[0]) | |
119 avctx->release_buffer(avctx, &t->frame); | |
120 | |
121 if (s->avctx->width!=s->width || s->avctx->height!=s->height) | |
122 avcodec_set_dimensions(s->avctx, s->width, s->height); | |
123 | |
124 if(avctx->get_buffer(avctx, &t->frame) < 0) { | |
125 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
126 return -1; | |
127 } | |
128 | |
9415
141badec76fc
Add a av_fast_malloc function and replace several uses of av_fast_realloc,
reimar
parents:
9414
diff
changeset
|
129 av_fast_malloc(&t->bitstream_buf, &t->bitstream_buf_size, (buf_end-buf) + FF_INPUT_BUFFER_PADDING_SIZE); |
8745 | 130 if (!t->bitstream_buf) |
9413
1eafaea58613
Use AVERROR(ENOMEM) instead of AVERROR_NOMEM / -1 in eatqi and mimic decoders
reimar
parents:
9355
diff
changeset
|
131 return AVERROR(ENOMEM); |
9414
5a738e8f9524
Use void * instead of uint8_t * for the destination buffer for dsp.bswap_buf
reimar
parents:
9413
diff
changeset
|
132 s->dsp.bswap_buf(t->bitstream_buf, (const uint32_t*)buf, (buf_end-buf)/4); |
8745 | 133 init_get_bits(&s->gb, t->bitstream_buf, 8*(buf_end-buf)); |
134 | |
135 s->last_dc[0] = s->last_dc[1] = s->last_dc[2] = 0; | |
136 for (s->mb_y=0; s->mb_y<(avctx->height+15)/16; s->mb_y++) | |
137 for (s->mb_x=0; s->mb_x<(avctx->width+15)/16; s->mb_x++) | |
138 { | |
9702
3dcbde0de577
eatqi: move "block" variable into context to ensure sufficient alignment for
reimar
parents:
9428
diff
changeset
|
139 tqi_decode_mb(s, t->block); |
3dcbde0de577
eatqi: move "block" variable into context to ensure sufficient alignment for
reimar
parents:
9428
diff
changeset
|
140 tqi_idct_put(t, t->block); |
8745 | 141 } |
142 | |
143 *data_size = sizeof(AVFrame); | |
144 *(AVFrame*)data = t->frame; | |
145 return buf_size; | |
146 } | |
147 | |
148 static av_cold int tqi_decode_end(AVCodecContext *avctx) | |
149 { | |
150 TqiContext *t = avctx->priv_data; | |
151 if(t->frame.data[0]) | |
152 avctx->release_buffer(avctx, &t->frame); | |
153 av_free(t->bitstream_buf); | |
154 return 0; | |
155 } | |
156 | |
157 AVCodec eatqi_decoder = { | |
158 "eatqi", | |
159 CODEC_TYPE_VIDEO, | |
160 CODEC_ID_TQI, | |
161 sizeof(TqiContext), | |
162 tqi_decode_init, | |
163 NULL, | |
164 tqi_decode_end, | |
165 tqi_decode_frame, | |
166 CODEC_CAP_DR1, | |
167 .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TQI Video"), | |
168 }; |