Mercurial > libavcodec.hg
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"); |