aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2011-10-27 17:53:29 +0200
committerMichael Niedermayer <michaelni@gmx.at>2011-10-27 17:53:29 +0200
commit4ffed61b4938d9a3371ca9d4af0be578546a4ae0 (patch)
tree16bf6d545fed647ae74251c7d75e9d6b66abc143
parent23040e2e3dafbe99a37e70c854073a102b8a7f46 (diff)
downloadffmpeg-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.h4
-rw-r--r--libavcodec/h264_parser.c27
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);
}
/**