faster find_startcode()

Originally committed as revision 4939 to svn://svn.ffmpeg.org/ffmpeg/trunk
pull/126/head
Michael Niedermayer 19 years ago
parent 8f0df75438
commit 82fcbc145d
  1. 41
      libavcodec/mpeg12.c
  2. 28
      libavcodec/mpegvideo.c
  3. 1
      libavcodec/mpegvideo.h
  4. 25
      libavcodec/parser.c

@ -2171,33 +2171,6 @@ static int mpeg_decode_postinit(AVCodecContext *avctx){
return 0; return 0;
} }
/* return the 8 bit start code value and update the search
state. Return -1 if no start code found */
static int find_start_code(const uint8_t **pbuf_ptr, const uint8_t *buf_end)
{
const uint8_t *buf_ptr= *pbuf_ptr;
buf_ptr++; //gurantees that -1 is within the array
buf_end -= 3; // gurantees that +3 is within the array
while (buf_ptr < buf_end) {
if(*buf_ptr==0){
while(buf_ptr < buf_end && buf_ptr[1]==0)
buf_ptr++;
if(buf_ptr[-1] == 0 && buf_ptr[1] == 1){
*pbuf_ptr = buf_ptr+3;
return buf_ptr[2] + 0x100;
}
}
buf_ptr += 2;
}
buf_end += 3; //undo the hack above
*pbuf_ptr = buf_end;
return -1;
}
static int mpeg1_decode_picture(AVCodecContext *avctx, static int mpeg1_decode_picture(AVCodecContext *avctx,
const uint8_t *buf, int buf_size) const uint8_t *buf, int buf_size)
{ {
@ -2715,7 +2688,8 @@ static int slice_decode_thread(AVCodecContext *c, void *arg){
if(s->mb_y == s->end_mb_y) if(s->mb_y == s->end_mb_y)
return 0; return 0;
start_code = find_start_code(&buf, s->gb.buffer_end); start_code= -1;
buf = ff_find_start_code(buf, s->gb.buffer_end, &start_code);
mb_y= start_code - SLICE_MIN_START_CODE; mb_y= start_code - SLICE_MIN_START_CODE;
if(mb_y < 0 || mb_y >= s->end_mb_y) if(mb_y < 0 || mb_y >= s->end_mb_y)
return -1; return -1;
@ -2995,14 +2969,12 @@ static void mpeg_decode_gop(AVCodecContext *avctx,
int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size) int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size)
{ {
int i; int i;
uint32_t state; uint32_t state= pc->state;
state= pc->state;
i=0; i=0;
if(!pc->frame_start_found){ if(!pc->frame_start_found){
for(i=0; i<buf_size; i++){ for(i=0; i<buf_size; i++){
state= (state<<8) | buf[i]; i= ff_find_start_code(buf+i, buf+buf_size, &state) - buf - 1;
if(state >= SLICE_MIN_START_CODE && state <= SLICE_MAX_START_CODE){ if(state >= SLICE_MIN_START_CODE && state <= SLICE_MAX_START_CODE){
i++; i++;
pc->frame_start_found=1; pc->frame_start_found=1;
@ -3016,7 +2988,7 @@ int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size)
if (buf_size == 0) if (buf_size == 0)
return 0; return 0;
for(; i<buf_size; i++){ for(; i<buf_size; i++){
state= (state<<8) | buf[i]; i= ff_find_start_code(buf+i, buf+buf_size, &state) - buf - 1;
if((state&0xFFFFFF00) == 0x100){ if((state&0xFFFFFF00) == 0x100){
if(state < SLICE_MIN_START_CODE || state > SLICE_MAX_START_CODE){ if(state < SLICE_MIN_START_CODE || state > SLICE_MAX_START_CODE){
pc->frame_start_found=0; pc->frame_start_found=0;
@ -3083,7 +3055,8 @@ static int mpeg_decode_frame(AVCodecContext *avctx,
for(;;) { for(;;) {
/* find start next code */ /* find start next code */
start_code = find_start_code(&buf_ptr, buf_end); start_code = -1;
buf_ptr = ff_find_start_code(buf_ptr,buf_end, &start_code);
if (start_code < 0){ if (start_code < 0){
if(s2->pict_type != B_TYPE || avctx->skip_frame <= AVDISCARD_DEFAULT){ if(s2->pict_type != B_TYPE || avctx->skip_frame <= AVDISCARD_DEFAULT){
if(avctx->thread_count > 1){ if(avctx->thread_count > 1){

@ -228,6 +228,34 @@ void ff_write_quant_matrix(PutBitContext *pb, int16_t *matrix){
} }
#endif //CONFIG_ENCODERS #endif //CONFIG_ENCODERS
const uint8_t *ff_find_start_code(const uint8_t * restrict p, const uint8_t *end, uint32_t * restrict state){
int i;
for(i=0; i<3; i++){
uint32_t tmp= *state << 8;
*state= tmp + *(p++);
if(tmp == 0x100 || p==end)
return p;
}
p--; // need to recheck or might miss one
end--; // we need the byte after 00 00 01 too
while(p<end){
if (p[ 0] > 1) p+= 3;
else if(p[-1] ) p+= 2;
else if(p[-2]|(p[0]-1)) p++;
else{
p++;
break;
}
}
p= FFMIN(p, end)-3;
*state= be2me_32(unaligned32(p));
return p+4;
}
/* init common dct for both encoder and decoder */ /* init common dct for both encoder and decoder */
int DCT_common_init(MpegEncContext *s) int DCT_common_init(MpegEncContext *s)
{ {

@ -773,6 +773,7 @@ void ff_write_quant_matrix(PutBitContext *pb, int16_t *matrix);
int ff_find_unused_picture(MpegEncContext *s, int shared); int ff_find_unused_picture(MpegEncContext *s, int shared);
void ff_denoise_dct(MpegEncContext *s, DCTELEM *block); void ff_denoise_dct(MpegEncContext *s, DCTELEM *block);
void ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src); void ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src);
const uint8_t *ff_find_start_code(const uint8_t *p, const uint8_t *end, uint32_t *state);
void ff_er_frame_start(MpegEncContext *s); void ff_er_frame_start(MpegEncContext *s);
void ff_er_frame_end(MpegEncContext *s); void ff_er_frame_end(MpegEncContext *s);

@ -272,28 +272,6 @@ int ff_combine_frame(ParseContext *pc, int next, uint8_t **buf, int *buf_size)
return 0; return 0;
} }
static int find_start_code(const uint8_t **pbuf_ptr, const uint8_t *buf_end)
{
const uint8_t *buf_ptr;
unsigned int state=0xFFFFFFFF, v;
int val;
buf_ptr = *pbuf_ptr;
while (buf_ptr < buf_end) {
v = *buf_ptr++;
if (state == 0x000001) {
state = ((state << 8) | v) & 0xffffff;
val = state;
goto found;
}
state = ((state << 8) | v) & 0xffffff;
}
val = -1;
found:
*pbuf_ptr = buf_ptr;
return val;
}
/* XXX: merge with libavcodec ? */ /* XXX: merge with libavcodec ? */
#define MPEG1_FRAME_RATE_BASE 1001 #define MPEG1_FRAME_RATE_BASE 1001
@ -335,7 +313,8 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s,
s->repeat_pict = 0; s->repeat_pict = 0;
buf_end = buf + buf_size; buf_end = buf + buf_size;
while (buf < buf_end) { while (buf < buf_end) {
start_code = find_start_code(&buf, buf_end); start_code= -1;
buf= ff_find_start_code(buf, buf_end, &start_code);
bytes_left = buf_end - buf; bytes_left = buf_end - buf;
switch(start_code) { switch(start_code) {
case PICTURE_START_CODE: case PICTURE_START_CODE:

Loading…
Cancel
Save