aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2011-10-01 17:41:28 +0200
committerReinhard Tartler <siretart@tauware.de>2012-03-14 21:27:22 +0100
commita81a6d9c80448cfbba0d2bcdd681bf971c7055a4 (patch)
treee9e958f981590841592907edafecefbb52028572
parent48f0eeb2e519882da9fe156abaa95cc808b67a8b (diff)
downloadffmpeg-a81a6d9c80448cfbba0d2bcdd681bf971c7055a4.tar.gz
h264: improve parsing of broken AVC SPS
Parsing the entire NAL as SPS fixes decoding of some AVC bitstreams with broken escaping. Since the size of the NAL unit is known and checked against the buffer end we can parse it entirely without buffer overreads. Fixes playback of http://streams.videolan.org/streams/mp4/Mr_MrsSmith-h264_aac.mp4 Signed-off-by: Janne Grunau <janne-libav@jannau.net> (cherry picked from commit 3aa661ec561d7a20812b84b353b0d7855ac346c8) Signed-off-by: Reinhard Tartler <siretart@tauware.de>
-rw-r--r--libavcodec/h264.c9
-rw-r--r--libavcodec/h264_ps.c5
2 files changed, 12 insertions, 2 deletions
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index d09c4aca2e..95a672b962 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -3924,7 +3924,14 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){
break;
case NAL_SPS:
init_get_bits(&s->gb, ptr, bit_length);
- ff_h264_decode_seq_parameter_set(h);
+ if (ff_h264_decode_seq_parameter_set(h) < 0 &&
+ h->is_avc && (nalsize != consumed) && nalsize) {
+ av_log(h->s.avctx, AV_LOG_DEBUG, "SPS decoding failure, "
+ "try parsing the coomplete NAL\n");
+ init_get_bits(&s->gb, buf + buf_index + 1 - consumed,
+ 8 * (nalsize - 1));
+ ff_h264_decode_seq_parameter_set(h);
+ }
if (s->flags& CODEC_FLAG_LOW_DELAY ||
(h->sps.bitstream_restriction_flag && !h->sps.num_reorder_frames))
diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c
index 287702c7c4..276eb77d1d 100644
--- a/libavcodec/h264_ps.c
+++ b/libavcodec/h264_ps.c
@@ -228,7 +228,6 @@ static inline int decode_vui_parameters(H264Context *h, SPS *sps){
get_ue_golomb(&s->gb); /*max_dec_frame_buffering*/
if (get_bits_left(&s->gb) < 0) {
- av_log(h->s.avctx, AV_LOG_ERROR, "Overread VUI by %d bits\n", -get_bits_left(&s->gb));
sps->num_reorder_frames=0;
sps->bitstream_restriction_flag= 0;
}
@@ -238,6 +237,10 @@ static inline int decode_vui_parameters(H264Context *h, SPS *sps){
return -1;
}
}
+ if (get_bits_left(&s->gb) < 0) {
+ av_log(h->s.avctx, AV_LOG_ERROR, "Overread VUI by %d bits\n", -get_bits_left(&s->gb));
+ return AVERROR_INVALIDDATA;
+ }
return 0;
}