diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2011-10-27 17:53:29 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2011-10-27 17:53:29 +0200 |
commit | 4ffed61b4938d9a3371ca9d4af0be578546a4ae0 (patch) | |
tree | 16bf6d545fed647ae74251c7d75e9d6b66abc143 | |
parent | 23040e2e3dafbe99a37e70c854073a102b8a7f46 (diff) | |
download | ffmpeg-4ffed61b4938d9a3371ca9d4af0be578546a4ae0.tar.gz |
h264_parser: fully parse first_mb_in_slice to more reliably detect AU boundaries.
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavcodec/h264.h | 4 | ||||
-rw-r--r-- | libavcodec/h264_parser.c | 27 |
2 files changed, 23 insertions, 8 deletions
diff --git a/libavcodec/h264.h b/libavcodec/h264.h index f4a463310e..63ed3573cb 100644 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@ -591,6 +591,10 @@ typedef struct H264Context{ int16_t slice_row[MAX_SLICES]; ///< to detect when MAX_SLICES is too low int sync; ///< did we had a keyframe or recovery point + + uint8_t parse_history[4]; + int parse_history_count; + int parse_last_mb; }H264Context; diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c index 778ef1efec..4945a6864c 100644 --- a/libavcodec/h264_parser.c +++ b/libavcodec/h264_parser.c @@ -93,17 +93,28 @@ static int ff_h264_find_frame_end(H264Context *h, const uint8_t *buf, int buf_si goto found; } }else if(v==1 || v==2 || v==5){ + state+=8; + continue; + } + state= 7; + }else{ + h->parse_history[h->parse_history_count++]= buf[i]; + if(h->parse_history_count>3){ + unsigned int mb, last_mb= h->parse_last_mb; + GetBitContext gb; + + init_get_bits(&gb, h->parse_history, 8*h->parse_history_count); + h->parse_history_count=0; + mb= get_ue_golomb_long(&gb); + last_mb= h->parse_last_mb; + h->parse_last_mb= mb; if(pc->frame_start_found){ - state+=8; - continue; + if(mb <= last_mb) + goto found; }else pc->frame_start_found = 1; + state= 7; } - state= 7; - }else{ - if(buf[i] & 0x80) - goto found; - state= 7; } } pc->state= state; @@ -116,7 +127,7 @@ found: pc->frame_start_found= 0; if(h->is_avc) return next_avc; - return i-(state&5); + return i-(state&5) - 3*(state>7); } /** |