Fixes Ticket4011
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 69a9a90d2ef795162074be24e3ad2182a8676af2)
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
... | ... |
@@ -202,10 +202,10 @@ static int scan_mmco_reset(AVCodecParserContext *s) |
202 | 202 |
*/ |
203 | 203 |
static inline int parse_nal_units(AVCodecParserContext *s, |
204 | 204 |
AVCodecContext *avctx, |
205 |
- const uint8_t *buf, int buf_size) |
|
205 |
+ const uint8_t * const buf, int buf_size) |
|
206 | 206 |
{ |
207 | 207 |
H264Context *h = s->priv_data; |
208 |
- const uint8_t *buf_end = buf + buf_size; |
|
208 |
+ int buf_index, next_avc; |
|
209 | 209 |
unsigned int pps_id; |
210 | 210 |
unsigned int slice_type; |
211 | 211 |
int state = -1, got_reset = 0; |
... | ... |
@@ -225,26 +225,26 @@ static inline int parse_nal_units(AVCodecParserContext *s, |
225 | 225 |
if (!buf_size) |
226 | 226 |
return 0; |
227 | 227 |
|
228 |
+ buf_index = 0; |
|
229 |
+ next_avc = h->is_avc ? 0 : buf_size; |
|
228 | 230 |
for (;;) { |
229 | 231 |
int src_length, dst_length, consumed, nalsize = 0; |
230 |
- if (h->is_avc) { |
|
231 |
- int i; |
|
232 |
- if (h->nal_length_size >= buf_end - buf) break; |
|
233 |
- nalsize = 0; |
|
234 |
- for (i = 0; i < h->nal_length_size; i++) |
|
235 |
- nalsize = (nalsize << 8) | *buf++; |
|
236 |
- if (nalsize <= 0 || nalsize > buf_end - buf) { |
|
237 |
- av_log(h->avctx, AV_LOG_ERROR, "AVC: nal size %d\n", nalsize); |
|
232 |
+ |
|
233 |
+ if (buf_index >= next_avc) { |
|
234 |
+ nalsize = get_avc_nalsize(h, buf, buf_size, &buf_index); |
|
235 |
+ if (nalsize < 0) |
|
238 | 236 |
break; |
239 |
- } |
|
240 |
- src_length = nalsize; |
|
237 |
+ next_avc = buf_index + nalsize; |
|
241 | 238 |
} else { |
242 |
- buf = avpriv_find_start_code(buf, buf_end, &state); |
|
243 |
- if (buf >= buf_end) |
|
244 |
- break; |
|
245 |
- --buf; |
|
246 |
- src_length = buf_end - buf; |
|
239 |
+ buf_index = find_start_code(buf, buf_size, buf_index, next_avc); |
|
240 |
+ if (buf_index >= buf_size) |
|
241 |
+ break; |
|
242 |
+ if (buf_index >= next_avc) |
|
243 |
+ continue; |
|
247 | 244 |
} |
245 |
+ src_length = next_avc - buf_index; |
|
246 |
+ |
|
247 |
+ state = buf[buf_index]; |
|
248 | 248 |
switch (state & 0x1f) { |
249 | 249 |
case NAL_SLICE: |
250 | 250 |
case NAL_IDR_SLICE: |
... | ... |
@@ -261,10 +261,13 @@ static inline int parse_nal_units(AVCodecParserContext *s, |
261 | 261 |
} |
262 | 262 |
break; |
263 | 263 |
} |
264 |
- ptr = ff_h264_decode_nal(h, buf, &dst_length, &consumed, src_length); |
|
264 |
+ ptr = ff_h264_decode_nal(h, buf + buf_index, &dst_length, |
|
265 |
+ &consumed, src_length); |
|
265 | 266 |
if (!ptr || dst_length < 0) |
266 | 267 |
break; |
267 | 268 |
|
269 |
+ buf_index += consumed; |
|
270 |
+ |
|
268 | 271 |
init_get_bits(&h->gb, ptr, 8 * dst_length); |
269 | 272 |
switch (h->nal_unit_type) { |
270 | 273 |
case NAL_SPS: |
... | ... |
@@ -439,7 +442,6 @@ static inline int parse_nal_units(AVCodecParserContext *s, |
439 | 439 |
|
440 | 440 |
return 0; /* no need to evaluate the rest */ |
441 | 441 |
} |
442 |
- buf += h->is_avc ? nalsize : consumed; |
|
443 | 442 |
} |
444 | 443 |
if (q264) |
445 | 444 |
return 0; |