annotate roqvideodec.c @ 6018:9d1654835629 libavcodec

Ensure that our total reference frame count does not exceed the SPS max frame count, which is limited to less than the size of the reference buffers, thereby preventing overflow. Part of fix for issue 281.
author heydowns
date Fri, 14 Dec 2007 06:25:23 +0000
parents f47bc5359101
children dfdff1ca78a7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5080
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
1 /*
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
2 * Copyright (C) 2003 the ffmpeg project
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
3 *
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
4 * This file is part of FFmpeg.
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
5 *
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
6 * FFmpeg is free software; you can redistribute it and/or
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
7 * modify it under the terms of the GNU Lesser General Public
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
8 * License as published by the Free Software Foundation; either
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
9 * version 2.1 of the License, or (at your option) any later version.
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
10 *
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
11 * FFmpeg is distributed in the hope that it will be useful,
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
14 * Lesser General Public License for more details.
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
15 *
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
16 * You should have received a copy of the GNU Lesser General Public
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
17 * License along with FFmpeg; if not, write to the Free Software
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
19 */
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
20
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
21 /**
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
22 * @file roqvideodec.c
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
23 * Id RoQ Video Decoder by Dr. Tim Ferguson
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
24 * For more information about the Id RoQ format, visit:
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
25 * http://www.csse.monash.edu.au/~timf/
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
26 */
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
27
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
28 #include <stdio.h>
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
29 #include <stdlib.h>
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
30 #include <string.h>
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
31 #include <unistd.h>
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
32
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
33 #include "avcodec.h"
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
34 #include "bytestream.h"
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
35 #include "dsputil.h"
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
36 #include "roqvideo.h"
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
37
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
38 static void roqvideo_decode_frame(RoqContext *ri)
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
39 {
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
40 unsigned int chunk_id = 0, chunk_arg = 0;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
41 unsigned long chunk_size = 0;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
42 int i, j, k, nv1, nv2, vqflg = 0, vqflg_pos = -1;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
43 int vqid, bpos, xpos, ypos, xp, yp, x, y, mx, my;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
44 int frame_stats[2][4] = {{0},{0}};
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
45 roq_qcell *qcell;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
46 unsigned char *buf = ri->buf;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
47 unsigned char *buf_end = ri->buf + ri->size;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
48
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
49 while (buf < buf_end) {
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
50 chunk_id = bytestream_get_le16(&buf);
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
51 chunk_size = bytestream_get_le32(&buf);
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
52 chunk_arg = bytestream_get_le16(&buf);
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
53
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
54 if(chunk_id == RoQ_QUAD_VQ)
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
55 break;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
56 if(chunk_id == RoQ_QUAD_CODEBOOK) {
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
57 if((nv1 = chunk_arg >> 8) == 0)
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
58 nv1 = 256;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
59 if((nv2 = chunk_arg & 0xff) == 0 && nv1 * 6 < chunk_size)
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
60 nv2 = 256;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
61 for(i = 0; i < nv1; i++) {
5104
b8e8aa53f613 Rename cb field
benoit
parents: 5099
diff changeset
62 ri->cb2x2[i].y[0] = *buf++;
b8e8aa53f613 Rename cb field
benoit
parents: 5099
diff changeset
63 ri->cb2x2[i].y[1] = *buf++;
b8e8aa53f613 Rename cb field
benoit
parents: 5099
diff changeset
64 ri->cb2x2[i].y[2] = *buf++;
b8e8aa53f613 Rename cb field
benoit
parents: 5099
diff changeset
65 ri->cb2x2[i].y[3] = *buf++;
b8e8aa53f613 Rename cb field
benoit
parents: 5099
diff changeset
66 ri->cb2x2[i].u = *buf++;
b8e8aa53f613 Rename cb field
benoit
parents: 5099
diff changeset
67 ri->cb2x2[i].v = *buf++;
5080
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
68 }
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
69 for(i = 0; i < nv2; i++)
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
70 for(j = 0; j < 4; j++)
5104
b8e8aa53f613 Rename cb field
benoit
parents: 5099
diff changeset
71 ri->cb4x4[i].idx[j] = *buf++;
5080
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
72 }
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
73 }
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
74
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
75 bpos = xpos = ypos = 0;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
76 while(bpos < chunk_size) {
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
77 for (yp = ypos; yp < ypos + 16; yp += 8)
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
78 for (xp = xpos; xp < xpos + 16; xp += 8) {
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
79 if (vqflg_pos < 0) {
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
80 vqflg = buf[bpos++]; vqflg |= (buf[bpos++] << 8);
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
81 vqflg_pos = 7;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
82 }
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
83 vqid = (vqflg >> (vqflg_pos * 2)) & 0x3;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
84 frame_stats[0][vqid]++;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
85 vqflg_pos--;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
86
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
87 switch(vqid) {
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
88 case RoQ_ID_MOT:
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
89 break;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
90 case RoQ_ID_FCC:
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
91 mx = 8 - (buf[bpos] >> 4) - ((signed char) (chunk_arg >> 8));
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
92 my = 8 - (buf[bpos++] & 0xf) - ((signed char) chunk_arg);
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
93 ff_apply_motion_8x8(ri, xp, yp, mx, my);
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
94 break;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
95 case RoQ_ID_SLD:
5104
b8e8aa53f613 Rename cb field
benoit
parents: 5099
diff changeset
96 qcell = ri->cb4x4 + buf[bpos++];
b8e8aa53f613 Rename cb field
benoit
parents: 5099
diff changeset
97 ff_apply_vector_4x4(ri, xp, yp, ri->cb2x2 + qcell->idx[0]);
b8e8aa53f613 Rename cb field
benoit
parents: 5099
diff changeset
98 ff_apply_vector_4x4(ri, xp+4, yp, ri->cb2x2 + qcell->idx[1]);
b8e8aa53f613 Rename cb field
benoit
parents: 5099
diff changeset
99 ff_apply_vector_4x4(ri, xp, yp+4, ri->cb2x2 + qcell->idx[2]);
b8e8aa53f613 Rename cb field
benoit
parents: 5099
diff changeset
100 ff_apply_vector_4x4(ri, xp+4, yp+4, ri->cb2x2 + qcell->idx[3]);
5080
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
101 break;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
102 case RoQ_ID_CCC:
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
103 for (k = 0; k < 4; k++) {
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
104 x = xp; y = yp;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
105 if(k & 0x01) x += 4;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
106 if(k & 0x02) y += 4;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
107
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
108 if (vqflg_pos < 0) {
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
109 vqflg = buf[bpos++];
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
110 vqflg |= (buf[bpos++] << 8);
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
111 vqflg_pos = 7;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
112 }
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
113 vqid = (vqflg >> (vqflg_pos * 2)) & 0x3;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
114 frame_stats[1][vqid]++;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
115 vqflg_pos--;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
116 switch(vqid) {
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
117 case RoQ_ID_MOT:
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
118 break;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
119 case RoQ_ID_FCC:
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
120 mx = 8 - (buf[bpos] >> 4) - ((signed char) (chunk_arg >> 8));
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
121 my = 8 - (buf[bpos++] & 0xf) - ((signed char) chunk_arg);
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
122 ff_apply_motion_4x4(ri, x, y, mx, my);
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
123 break;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
124 case RoQ_ID_SLD:
5104
b8e8aa53f613 Rename cb field
benoit
parents: 5099
diff changeset
125 qcell = ri->cb4x4 + buf[bpos++];
b8e8aa53f613 Rename cb field
benoit
parents: 5099
diff changeset
126 ff_apply_vector_2x2(ri, x, y, ri->cb2x2 + qcell->idx[0]);
b8e8aa53f613 Rename cb field
benoit
parents: 5099
diff changeset
127 ff_apply_vector_2x2(ri, x+2, y, ri->cb2x2 + qcell->idx[1]);
b8e8aa53f613 Rename cb field
benoit
parents: 5099
diff changeset
128 ff_apply_vector_2x2(ri, x, y+2, ri->cb2x2 + qcell->idx[2]);
b8e8aa53f613 Rename cb field
benoit
parents: 5099
diff changeset
129 ff_apply_vector_2x2(ri, x+2, y+2, ri->cb2x2 + qcell->idx[3]);
5080
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
130 break;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
131 case RoQ_ID_CCC:
5104
b8e8aa53f613 Rename cb field
benoit
parents: 5099
diff changeset
132 ff_apply_vector_2x2(ri, x, y, ri->cb2x2 + buf[bpos]);
b8e8aa53f613 Rename cb field
benoit
parents: 5099
diff changeset
133 ff_apply_vector_2x2(ri, x+2, y, ri->cb2x2 + buf[bpos+1]);
b8e8aa53f613 Rename cb field
benoit
parents: 5099
diff changeset
134 ff_apply_vector_2x2(ri, x, y+2, ri->cb2x2 + buf[bpos+2]);
b8e8aa53f613 Rename cb field
benoit
parents: 5099
diff changeset
135 ff_apply_vector_2x2(ri, x+2, y+2, ri->cb2x2 + buf[bpos+3]);
5080
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
136 bpos += 4;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
137 break;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
138 }
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
139 }
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
140 break;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
141 default:
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
142 av_log(ri->avctx, AV_LOG_ERROR, "Unknown vq code: %d\n", vqid);
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
143 }
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
144 }
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
145
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
146 xpos += 16;
5188
c2a475157299 add width and height in context and use them
benoit
parents: 5104
diff changeset
147 if (xpos >= ri->width) {
c2a475157299 add width and height in context and use them
benoit
parents: 5104
diff changeset
148 xpos -= ri->width;
5080
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
149 ypos += 16;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
150 }
5188
c2a475157299 add width and height in context and use them
benoit
parents: 5104
diff changeset
151 if(ypos >= ri->height)
5080
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
152 break;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
153 }
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
154 }
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
155
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
156
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
157 static int roq_decode_init(AVCodecContext *avctx)
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
158 {
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
159 RoqContext *s = avctx->priv_data;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
160
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
161 s->avctx = avctx;
5188
c2a475157299 add width and height in context and use them
benoit
parents: 5104
diff changeset
162 s->width = avctx->width;
c2a475157299 add width and height in context and use them
benoit
parents: 5104
diff changeset
163 s->height = avctx->height;
5080
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
164 s->last_frame = &s->frames[0];
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
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
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
167 dsputil_init(&s->dsp, avctx);
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
168
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
169 return 0;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
170 }
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
171
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
172 static int roq_decode_frame(AVCodecContext *avctx,
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
173 void *data, int *data_size,
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
174 uint8_t *buf, int buf_size)
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
175 {
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
176 RoqContext *s = avctx->priv_data;
5524
f47bc5359101 fix decoding of samples.mplayerhq.hu/game-formats/idroq/demoEnd.roq
michael
parents: 5215
diff changeset
177 int copy= !s->current_frame->data[0];
5080
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
178
5088
8e206208db1f fix skipped blocks
michael
parents: 5080
diff changeset
179 if (avctx->reget_buffer(avctx, s->current_frame)) {
5080
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
180 av_log(avctx, AV_LOG_ERROR, " RoQ: get_buffer() failed\n");
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
181 return -1;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
182 }
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
183
5524
f47bc5359101 fix decoding of samples.mplayerhq.hu/game-formats/idroq/demoEnd.roq
michael
parents: 5215
diff changeset
184 if(copy)
f47bc5359101 fix decoding of samples.mplayerhq.hu/game-formats/idroq/demoEnd.roq
michael
parents: 5215
diff changeset
185 av_picture_copy((AVPicture*)s->current_frame, (AVPicture*)s->last_frame,
f47bc5359101 fix decoding of samples.mplayerhq.hu/game-formats/idroq/demoEnd.roq
michael
parents: 5215
diff changeset
186 avctx->pix_fmt, avctx->width, avctx->height);
f47bc5359101 fix decoding of samples.mplayerhq.hu/game-formats/idroq/demoEnd.roq
michael
parents: 5215
diff changeset
187
5080
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
188 s->buf = buf;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
189 s->size = buf_size;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
190 roqvideo_decode_frame(s);
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
191
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
192 *data_size = sizeof(AVFrame);
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
193 *(AVFrame*)data = *s->current_frame;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
194
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
195 /* shuffle frames */
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
196 FFSWAP(AVFrame *, s->current_frame, s->last_frame);
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
197
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
198 return buf_size;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
199 }
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
200
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
201 static int roq_decode_end(AVCodecContext *avctx)
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
202 {
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
203 RoqContext *s = avctx->priv_data;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
204
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
205 /* release the last frame */
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
206 if (s->last_frame->data[0])
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
207 avctx->release_buffer(avctx, s->last_frame);
5088
8e206208db1f fix skipped blocks
michael
parents: 5080
diff changeset
208 if (s->current_frame->data[0])
8e206208db1f fix skipped blocks
michael
parents: 5080
diff changeset
209 avctx->release_buffer(avctx, s->current_frame);
5080
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
210
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
211 return 0;
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
212 }
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
213
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
214 AVCodec roq_decoder = {
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
215 "roqvideo",
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
216 CODEC_TYPE_VIDEO,
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
217 CODEC_ID_ROQ,
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
218 sizeof(RoqContext),
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
219 roq_decode_init,
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
220 NULL,
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
221 roq_decode_end,
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
222 roq_decode_frame,
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
223 CODEC_CAP_DR1,
e72265f4e518 Split RoQ decoder to accommodate future encoder patch
benoit
parents:
diff changeset
224 };