Mercurial > libavcodec.hg
annotate roqvideodec.c @ 5319:40af705cef7e libavcodec
AC-3 decoder, soc revision 69, Aug 31 07:12:56 2006 UTC by cloud9
Fix the bugs:
1. The quality of output because of incorrect windowing coefficients.
New code for window generation.
2. Dynrng values were reset where dynrng value is present in the first block,
but not in the subsequent block.
author | jbr |
---|---|
date | Sat, 14 Jul 2007 16:03:14 +0000 |
parents | 2b72f9bc4f06 |
children | f47bc5359101 |
rev | line source |
---|---|
5080 | 1 /* |
2 * Copyright (C) 2003 the ffmpeg project | |
3 * | |
4 * This file is part of FFmpeg. | |
5 * | |
6 * FFmpeg is free software; you can redistribute it and/or | |
7 * modify it under the terms of the GNU Lesser General Public | |
8 * License as published by the Free Software Foundation; either | |
9 * version 2.1 of the License, or (at your option) any later version. | |
10 * | |
11 * FFmpeg is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 * Lesser General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU Lesser General Public | |
17 * License along with FFmpeg; if not, write to the Free Software | |
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
19 */ | |
20 | |
21 /** | |
22 * @file roqvideodec.c | |
23 * Id RoQ Video Decoder by Dr. Tim Ferguson | |
24 * For more information about the Id RoQ format, visit: | |
25 * http://www.csse.monash.edu.au/~timf/ | |
26 */ | |
27 | |
28 #include <stdio.h> | |
29 #include <stdlib.h> | |
30 #include <string.h> | |
31 #include <unistd.h> | |
32 | |
33 #include "avcodec.h" | |
34 #include "bytestream.h" | |
35 #include "dsputil.h" | |
36 #include "roqvideo.h" | |
37 | |
38 static void roqvideo_decode_frame(RoqContext *ri) | |
39 { | |
40 unsigned int chunk_id = 0, chunk_arg = 0; | |
41 unsigned long chunk_size = 0; | |
42 int i, j, k, nv1, nv2, vqflg = 0, vqflg_pos = -1; | |
43 int vqid, bpos, xpos, ypos, xp, yp, x, y, mx, my; | |
44 int frame_stats[2][4] = {{0},{0}}; | |
45 roq_qcell *qcell; | |
46 unsigned char *buf = ri->buf; | |
47 unsigned char *buf_end = ri->buf + ri->size; | |
48 | |
49 while (buf < buf_end) { | |
50 chunk_id = bytestream_get_le16(&buf); | |
51 chunk_size = bytestream_get_le32(&buf); | |
52 chunk_arg = bytestream_get_le16(&buf); | |
53 | |
54 if(chunk_id == RoQ_QUAD_VQ) | |
55 break; | |
56 if(chunk_id == RoQ_QUAD_CODEBOOK) { | |
57 if((nv1 = chunk_arg >> 8) == 0) | |
58 nv1 = 256; | |
59 if((nv2 = chunk_arg & 0xff) == 0 && nv1 * 6 < chunk_size) | |
60 nv2 = 256; | |
61 for(i = 0; i < nv1; i++) { | |
5104 | 62 ri->cb2x2[i].y[0] = *buf++; |
63 ri->cb2x2[i].y[1] = *buf++; | |
64 ri->cb2x2[i].y[2] = *buf++; | |
65 ri->cb2x2[i].y[3] = *buf++; | |
66 ri->cb2x2[i].u = *buf++; | |
67 ri->cb2x2[i].v = *buf++; | |
5080 | 68 } |
69 for(i = 0; i < nv2; i++) | |
70 for(j = 0; j < 4; j++) | |
5104 | 71 ri->cb4x4[i].idx[j] = *buf++; |
5080 | 72 } |
73 } | |
74 | |
75 bpos = xpos = ypos = 0; | |
76 while(bpos < chunk_size) { | |
77 for (yp = ypos; yp < ypos + 16; yp += 8) | |
78 for (xp = xpos; xp < xpos + 16; xp += 8) { | |
79 if (vqflg_pos < 0) { | |
80 vqflg = buf[bpos++]; vqflg |= (buf[bpos++] << 8); | |
81 vqflg_pos = 7; | |
82 } | |
83 vqid = (vqflg >> (vqflg_pos * 2)) & 0x3; | |
84 frame_stats[0][vqid]++; | |
85 vqflg_pos--; | |
86 | |
87 switch(vqid) { | |
88 case RoQ_ID_MOT: | |
89 break; | |
90 case RoQ_ID_FCC: | |
91 mx = 8 - (buf[bpos] >> 4) - ((signed char) (chunk_arg >> 8)); | |
92 my = 8 - (buf[bpos++] & 0xf) - ((signed char) chunk_arg); | |
93 ff_apply_motion_8x8(ri, xp, yp, mx, my); | |
94 break; | |
95 case RoQ_ID_SLD: | |
5104 | 96 qcell = ri->cb4x4 + buf[bpos++]; |
97 ff_apply_vector_4x4(ri, xp, yp, ri->cb2x2 + qcell->idx[0]); | |
98 ff_apply_vector_4x4(ri, xp+4, yp, ri->cb2x2 + qcell->idx[1]); | |
99 ff_apply_vector_4x4(ri, xp, yp+4, ri->cb2x2 + qcell->idx[2]); | |
100 ff_apply_vector_4x4(ri, xp+4, yp+4, ri->cb2x2 + qcell->idx[3]); | |
5080 | 101 break; |
102 case RoQ_ID_CCC: | |
103 for (k = 0; k < 4; k++) { | |
104 x = xp; y = yp; | |
105 if(k & 0x01) x += 4; | |
106 if(k & 0x02) y += 4; | |
107 | |
108 if (vqflg_pos < 0) { | |
109 vqflg = buf[bpos++]; | |
110 vqflg |= (buf[bpos++] << 8); | |
111 vqflg_pos = 7; | |
112 } | |
113 vqid = (vqflg >> (vqflg_pos * 2)) & 0x3; | |
114 frame_stats[1][vqid]++; | |
115 vqflg_pos--; | |
116 switch(vqid) { | |
117 case RoQ_ID_MOT: | |
118 break; | |
119 case RoQ_ID_FCC: | |
120 mx = 8 - (buf[bpos] >> 4) - ((signed char) (chunk_arg >> 8)); | |
121 my = 8 - (buf[bpos++] & 0xf) - ((signed char) chunk_arg); | |
122 ff_apply_motion_4x4(ri, x, y, mx, my); | |
123 break; | |
124 case RoQ_ID_SLD: | |
5104 | 125 qcell = ri->cb4x4 + buf[bpos++]; |
126 ff_apply_vector_2x2(ri, x, y, ri->cb2x2 + qcell->idx[0]); | |
127 ff_apply_vector_2x2(ri, x+2, y, ri->cb2x2 + qcell->idx[1]); | |
128 ff_apply_vector_2x2(ri, x, y+2, ri->cb2x2 + qcell->idx[2]); | |
129 ff_apply_vector_2x2(ri, x+2, y+2, ri->cb2x2 + qcell->idx[3]); | |
5080 | 130 break; |
131 case RoQ_ID_CCC: | |
5104 | 132 ff_apply_vector_2x2(ri, x, y, ri->cb2x2 + buf[bpos]); |
133 ff_apply_vector_2x2(ri, x+2, y, ri->cb2x2 + buf[bpos+1]); | |
134 ff_apply_vector_2x2(ri, x, y+2, ri->cb2x2 + buf[bpos+2]); | |
135 ff_apply_vector_2x2(ri, x+2, y+2, ri->cb2x2 + buf[bpos+3]); | |
5080 | 136 bpos += 4; |
137 break; | |
138 } | |
139 } | |
140 break; | |
141 default: | |
142 av_log(ri->avctx, AV_LOG_ERROR, "Unknown vq code: %d\n", vqid); | |
143 } | |
144 } | |
145 | |
146 xpos += 16; | |
5188 | 147 if (xpos >= ri->width) { |
148 xpos -= ri->width; | |
5080 | 149 ypos += 16; |
150 } | |
5188 | 151 if(ypos >= ri->height) |
5080 | 152 break; |
153 } | |
154 } | |
155 | |
156 | |
157 static int roq_decode_init(AVCodecContext *avctx) | |
158 { | |
159 RoqContext *s = avctx->priv_data; | |
160 | |
161 s->avctx = avctx; | |
5188 | 162 s->width = avctx->width; |
163 s->height = avctx->height; | |
5080 | 164 s->last_frame = &s->frames[0]; |
165 s->current_frame = &s->frames[1]; | |
5099
133329117637
Convert RoQ decoder to use YUV 4:4:4 unpacked macroblocks
benoit
parents:
5090
diff
changeset
|
166 avctx->pix_fmt = PIX_FMT_YUV444P; |
5080 | 167 dsputil_init(&s->dsp, avctx); |
168 | |
169 return 0; | |
170 } | |
171 | |
172 static int roq_decode_frame(AVCodecContext *avctx, | |
173 void *data, int *data_size, | |
174 uint8_t *buf, int buf_size) | |
175 { | |
176 RoqContext *s = avctx->priv_data; | |
177 | |
5088 | 178 if (avctx->reget_buffer(avctx, s->current_frame)) { |
5080 | 179 av_log(avctx, AV_LOG_ERROR, " RoQ: get_buffer() failed\n"); |
180 return -1; | |
181 } | |
182 | |
183 s->buf = buf; | |
184 s->size = buf_size; | |
185 roqvideo_decode_frame(s); | |
186 | |
187 *data_size = sizeof(AVFrame); | |
188 *(AVFrame*)data = *s->current_frame; | |
189 | |
190 /* shuffle frames */ | |
191 FFSWAP(AVFrame *, s->current_frame, s->last_frame); | |
192 | |
193 return buf_size; | |
194 } | |
195 | |
196 static int roq_decode_end(AVCodecContext *avctx) | |
197 { | |
198 RoqContext *s = avctx->priv_data; | |
199 | |
200 /* release the last frame */ | |
201 if (s->last_frame->data[0]) | |
202 avctx->release_buffer(avctx, s->last_frame); | |
5088 | 203 if (s->current_frame->data[0]) |
204 avctx->release_buffer(avctx, s->current_frame); | |
5080 | 205 |
206 return 0; | |
207 } | |
208 | |
209 AVCodec roq_decoder = { | |
210 "roqvideo", | |
211 CODEC_TYPE_VIDEO, | |
212 CODEC_ID_ROQ, | |
213 sizeof(RoqContext), | |
214 roq_decode_init, | |
215 NULL, | |
216 roq_decode_end, | |
217 roq_decode_frame, | |
218 CODEC_CAP_DR1, | |
219 }; |