comparison nuv.c @ 7799:c4f105f7c886 libavcodec

Fix nuv decoder to use reget_buffer for non-keyframes and correctly identify non-keyframe RTJPEG frames.
author reimar
date Fri, 05 Sep 2008 16:31:26 +0000
parents e943e1409077
children 967c0a1a60a0
comparison
equal deleted inserted replaced
7798:e7ec66d55d9e 7799:c4f105f7c886
130 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, 130 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
131 const uint8_t *buf, int buf_size) { 131 const uint8_t *buf, int buf_size) {
132 NuvContext *c = avctx->priv_data; 132 NuvContext *c = avctx->priv_data;
133 AVFrame *picture = data; 133 AVFrame *picture = data;
134 int orig_size = buf_size; 134 int orig_size = buf_size;
135 int keyframe;
136 int result;
135 enum {NUV_UNCOMPRESSED = '0', NUV_RTJPEG = '1', 137 enum {NUV_UNCOMPRESSED = '0', NUV_RTJPEG = '1',
136 NUV_RTJPEG_IN_LZO = '2', NUV_LZO = '3', 138 NUV_RTJPEG_IN_LZO = '2', NUV_LZO = '3',
137 NUV_BLACK = 'N', NUV_COPY_LAST = 'L'} comptype; 139 NUV_BLACK = 'N', NUV_COPY_LAST = 'L'} comptype;
138 140
139 if (buf_size < 12) { 141 if (buf_size < 12) {
157 if (buf[0] != 'V' || buf_size < 12) { 159 if (buf[0] != 'V' || buf_size < 12) {
158 av_log(avctx, AV_LOG_ERROR, "not a nuv video frame\n"); 160 av_log(avctx, AV_LOG_ERROR, "not a nuv video frame\n");
159 return -1; 161 return -1;
160 } 162 }
161 comptype = buf[1]; 163 comptype = buf[1];
164 switch (comptype) {
165 case NUV_RTJPEG_IN_LZO:
166 case NUV_RTJPEG:
167 keyframe = !buf[2]; break;
168 case NUV_COPY_LAST:
169 keyframe = 0; break;
170 default:
171 keyframe = 1; break;
172 }
162 // skip rest of the frameheader. 173 // skip rest of the frameheader.
163 buf = &buf[12]; 174 buf = &buf[12];
164 buf_size -= 12; 175 buf_size -= 12;
165 if (comptype == NUV_RTJPEG_IN_LZO || comptype == NUV_LZO) { 176 if (comptype == NUV_RTJPEG_IN_LZO || comptype == NUV_LZO) {
166 int outlen = c->decomp_size, inlen = buf_size; 177 int outlen = c->decomp_size, inlen = buf_size;
182 return -1; 193 return -1;
183 buf = &buf[12]; 194 buf = &buf[12];
184 buf_size -= 12; 195 buf_size -= 12;
185 } 196 }
186 197
187 if (c->pic.data[0]) 198 if (keyframe && c->pic.data[0])
188 avctx->release_buffer(avctx, &c->pic); 199 avctx->release_buffer(avctx, &c->pic);
189 c->pic.reference = 1; 200 c->pic.reference = 1;
190 c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_READABLE | 201 c->pic.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_READABLE |
191 FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; 202 FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
192 if (avctx->get_buffer(avctx, &c->pic) < 0) { 203 result = keyframe ? avctx->get_buffer(avctx, &c->pic) : avctx->reget_buffer(avctx, &c->pic);
204 if (result < 0) {
193 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); 205 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
194 return -1; 206 return -1;
195 } 207 }
196 208
197 c->pic.pict_type = FF_I_TYPE; 209 c->pic.pict_type = keyframe ? FF_I_TYPE : FF_P_TYPE;
198 c->pic.key_frame = 1; 210 c->pic.key_frame = keyframe;
199 // decompress/copy/whatever data 211 // decompress/copy/whatever data
200 switch (comptype) { 212 switch (comptype) {
201 case NUV_LZO: 213 case NUV_LZO:
202 case NUV_UNCOMPRESSED: { 214 case NUV_UNCOMPRESSED: {
203 int height = c->height; 215 int height = c->height;
218 memset(c->pic.data[1], 128, c->width * c->height / 4); 230 memset(c->pic.data[1], 128, c->width * c->height / 4);
219 memset(c->pic.data[2], 128, c->width * c->height / 4); 231 memset(c->pic.data[2], 128, c->width * c->height / 4);
220 break; 232 break;
221 } 233 }
222 case NUV_COPY_LAST: { 234 case NUV_COPY_LAST: {
223 c->pic.pict_type = FF_P_TYPE;
224 c->pic.key_frame = 0;
225 /* nothing more to do here */ 235 /* nothing more to do here */
226 break; 236 break;
227 } 237 }
228 default: 238 default:
229 av_log(avctx, AV_LOG_ERROR, "unknown compression\n"); 239 av_log(avctx, AV_LOG_ERROR, "unknown compression\n");