annotate eatqi.c @ 12530:63edd10ad4bc libavcodec tip

Try to fix crashes introduced by r25218 r25218 made assumptions about the existence of past reference frames that weren't necessarily true.
author darkshikari
date Tue, 28 Sep 2010 09:06:22 +0000
parents 7dd2a45249a9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8745
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
1 /*
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
2 * Electronic Arts TQI Video Decoder
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
3 * Copyright (c) 2007-2009 Peter Ross <pross@xvid.org>
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
4 *
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
5 * This file is part of FFmpeg.
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
6 *
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
11 *
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
15 * Lesser General Public License for more details.
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
16 *
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
20 */
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
21
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
22 /**
11644
7dd2a45249a9 Remove explicit filename from Doxygen @file commands.
diego
parents: 11560
diff changeset
23 * @file
8745
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
24 * Electronic Arts TQI Video Decoder
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
25 * by Peter Ross <pross@xvid.org>
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
26 *
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
27 * Technical details here:
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
28 * http://wiki.multimedia.cx/index.php?title=Electronic_Arts_TQI
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
29 */
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
30
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
31 #include "avcodec.h"
9428
0dce4fe6e6f3 Rename bitstream.h to get_bits.h.
stefano
parents: 9415
diff changeset
32 #include "get_bits.h"
8745
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
33 #include "dsputil.h"
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
34 #include "aandcttab.h"
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
35 #include "mpeg12.h"
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
36 #include "mpegvideo.h"
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
37
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
38 typedef struct TqiContext {
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
39 MpegEncContext s;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
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
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
42 unsigned int bitstream_buf_size;
11369
98970e51365a Remove DECLARE_ALIGNED_{8,16} macros
mru
parents: 10961
diff changeset
43 DECLARE_ALIGNED(16, DCTELEM, block)[6][64];
8745
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
44 } TqiContext;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
45
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
46 static av_cold int tqi_decode_init(AVCodecContext *avctx)
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
47 {
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
48 TqiContext *t = avctx->priv_data;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
49 MpegEncContext *s = &t->s;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
50 s->avctx = avctx;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
51 if(avctx->idct_algo==FF_IDCT_AUTO)
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
52 avctx->idct_algo=FF_IDCT_EA;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
53 dsputil_init(&s->dsp, avctx);
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
54 ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct);
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
55 s->qscale = 1;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
56 avctx->time_base = (AVRational){1, 15};
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
57 avctx->pix_fmt = PIX_FMT_YUV420P;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
58 ff_mpeg12_init_vlcs();
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
59 return 0;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
60 }
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
61
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
62 static void tqi_decode_mb(MpegEncContext *s, DCTELEM (*block)[64])
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
63 {
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
64 int n;
8755
1a6581522f9a remove warning about incompatible pointer
bcoudurier
parents: 8745
diff changeset
65 s->dsp.clear_blocks(block[0]);
8745
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
66 for (n=0; n<6; n++)
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
67 ff_mpeg1_decode_block_intra(s, block[n], n);
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
68 }
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
69
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
70 static inline void tqi_idct_put(TqiContext *t, DCTELEM (*block)[64])
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
71 {
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
72 MpegEncContext *s = &t->s;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
73 int linesize= t->frame.linesize[0];
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
74 uint8_t *dest_y = t->frame.data[0] + (s->mb_y * 16* linesize ) + s->mb_x * 16;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
75 uint8_t *dest_cb = t->frame.data[1] + (s->mb_y * 8 * t->frame.linesize[1]) + s->mb_x * 8;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
76 uint8_t *dest_cr = t->frame.data[2] + (s->mb_y * 8 * t->frame.linesize[2]) + s->mb_x * 8;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
77
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
78 s->dsp.idct_put(dest_y , linesize, block[0]);
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
79 s->dsp.idct_put(dest_y + 8, linesize, block[1]);
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
80 s->dsp.idct_put(dest_y + 8*linesize , linesize, block[2]);
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
81 s->dsp.idct_put(dest_y + 8*linesize + 8, linesize, block[3]);
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
82 if(!(s->avctx->flags&CODEC_FLAG_GRAY)) {
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
83 s->dsp.idct_put(dest_cb, t->frame.linesize[1], block[4]);
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
84 s->dsp.idct_put(dest_cr, t->frame.linesize[2], block[5]);
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
85 }
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
86 }
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
87
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
88 static void tqi_calculate_qtable(MpegEncContext *s, int quant)
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
89 {
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
90 const int qscale = (215 - 2*quant)*5;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
91 int i;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
92 if (s->avctx->idct_algo==FF_IDCT_EA) {
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
93 s->intra_matrix[0] = (ff_inv_aanscales[0]*ff_mpeg1_default_intra_matrix[0])>>11;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
94 for(i=1; i<64; i++)
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
95 s->intra_matrix[i] = (ff_inv_aanscales[i]*ff_mpeg1_default_intra_matrix[i]*qscale + 32)>>14;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
96 }else{
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
97 s->intra_matrix[0] = ff_mpeg1_default_intra_matrix[0];
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
98 for(i=1; i<64; i++)
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
99 s->intra_matrix[i] = (ff_mpeg1_default_intra_matrix[i]*qscale + 32)>>3;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
100 }
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
101 }
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
102
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
103 static int tqi_decode_frame(AVCodecContext *avctx,
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
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
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
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
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
109 const uint8_t *buf_end = buf+buf_size;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
110 TqiContext *t = avctx->priv_data;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
111 MpegEncContext *s = &t->s;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
112
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
113 s->width = AV_RL16(&buf[0]);
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
114 s->height = AV_RL16(&buf[2]);
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
115 tqi_calculate_qtable(s, buf[4]);
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
116 buf += 8;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
117
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
118 if (t->frame.data[0])
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
119 avctx->release_buffer(avctx, &t->frame);
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
120
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
121 if (s->avctx->width!=s->width || s->avctx->height!=s->height)
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
122 avcodec_set_dimensions(s->avctx, s->width, s->height);
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
123
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
124 if(avctx->get_buffer(avctx, &t->frame) < 0) {
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
125 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
126 return -1;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
127 }
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
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
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
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
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
133 init_get_bits(&s->gb, t->bitstream_buf, 8*(buf_end-buf));
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
134
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
135 s->last_dc[0] = s->last_dc[1] = s->last_dc[2] = 0;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
136 for (s->mb_y=0; s->mb_y<(avctx->height+15)/16; s->mb_y++)
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
137 for (s->mb_x=0; s->mb_x<(avctx->width+15)/16; s->mb_x++)
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
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
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
141 }
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
142
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
143 *data_size = sizeof(AVFrame);
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
144 *(AVFrame*)data = t->frame;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
145 return buf_size;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
146 }
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
147
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
148 static av_cold int tqi_decode_end(AVCodecContext *avctx)
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
149 {
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
150 TqiContext *t = avctx->priv_data;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
151 if(t->frame.data[0])
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
152 avctx->release_buffer(avctx, &t->frame);
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
153 av_free(t->bitstream_buf);
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
154 return 0;
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
155 }
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
156
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
157 AVCodec eatqi_decoder = {
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
158 "eatqi",
11560
8a4984c5cacc Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents: 11369
diff changeset
159 AVMEDIA_TYPE_VIDEO,
8745
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
160 CODEC_ID_TQI,
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
161 sizeof(TqiContext),
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
162 tqi_decode_init,
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
163 NULL,
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
164 tqi_decode_end,
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
165 tqi_decode_frame,
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
166 CODEC_CAP_DR1,
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
167 .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TQI Video"),
9833a42260fc Electronic Arts TQI decoder
pross
parents:
diff changeset
168 };