diff options
author | Christophe Thommeret <hftom@free.fr> | 2009-02-15 03:42:29 +0000 |
---|---|---|
committer | Christophe Thommeret <hftom@free.fr> | 2009-02-15 03:42:29 +0000 |
commit | 91f2c78995297c5e6c8d1374fb766fc40285cdf2 (patch) | |
tree | 1c251493491eaf4b7975f05557e15ed6e4c29105 /src | |
parent | b48689cb87d8147753001325527bfc5b743ced32 (diff) | |
download | xine-lib-91f2c78995297c5e6c8d1374fb766fc40285cdf2.tar.gz xine-lib-91f2c78995297c5e6c8d1374fb766fc40285cdf2.tar.bz2 |
VC1 interlaced fixes.
Diffstat (limited to 'src')
-rw-r--r-- | src/libvdpau/vdpau_mpeg12.c | 4 | ||||
-rw-r--r-- | src/libvdpau/vdpau_vc1.c | 94 |
2 files changed, 76 insertions, 22 deletions
diff --git a/src/libvdpau/vdpau_mpeg12.c b/src/libvdpau/vdpau_mpeg12.c index d3c2436f9..c97c7cf9a 100644 --- a/src/libvdpau/vdpau_mpeg12.c +++ b/src/libvdpau/vdpau_mpeg12.c @@ -732,8 +732,8 @@ static void vdpau_mpeg12_decode_data (video_decoder_t *this_gen, buf_element_t * sequence_t *seq = (sequence_t*)&this->sequence; if (buf->decoder_flags & BUF_FLAG_FRAMERATE) { - seq->video_step = buf->decoder_info[0]; - _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, seq->video_step); + /*seq->video_step = buf->decoder_info[0]; + _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, seq->video_step);*/ } if ( !buf->size ) diff --git a/src/libvdpau/vdpau_vc1.c b/src/libvdpau/vdpau_vc1.c index 989e0c899..fca537d2d 100644 --- a/src/libvdpau/vdpau_vc1.c +++ b/src/libvdpau/vdpau_vc1.c @@ -562,6 +562,40 @@ static void parse_header( vdpau_vc1_decoder_t *this_gen, uint8_t *buf, int len ) +static void remove_emulation_prevention( uint8_t *src, uint8_t *dst, int src_len, int *dst_len ) +{ + int i; + int len = 0; + int removed = 0; + + for ( i=0; i<src_len; ++i ) + printf("%02X ", src[i]); + printf("\n"); + + for ( i=0; i<src_len-3; ++i ) { + if ( src[i]==0 && src[i+1]==0 && src[i+2]==3 ) { + lprintf("removed emulation prevention byte\n"); + dst[len++] = src[i]; + dst[len++] = src[i+1]; + i += 2; + ++removed; + } + else { + memcpy( dst+len, src+i, 4 ); + ++len; + } + } + for ( ; i<src_len; ++i ) + dst[len++] = src[i]; + *dst_len = src_len-removed; + + for ( i=0; i<*dst_len; ++i ) + printf("%02X ", dst[i]); + printf("\n"); +} + + + static int parse_code( vdpau_vc1_decoder_t *this_gen, uint8_t *buf, int len ) { sequence_t *sequence = (sequence_t*)&this_gen->sequence; @@ -569,17 +603,28 @@ static int parse_code( vdpau_vc1_decoder_t *this_gen, uint8_t *buf, int len ) if ( !sequence->have_header && buf[3]!=sequence_header_code ) return 0; - if ( sequence->code_start == frame_start_code ) + if ( sequence->code_start == frame_start_code ) { + if ( buf[3]==field_start_code || buf[3]==slice_start_code ) + return -1; return 1; /* frame complete, decode */ + } switch ( buf[3] ) { + int dst_len; + uint8_t *tmp; case sequence_header_code: lprintf("sequence_header_code\n"); - sequence_header( this_gen, buf+4, len-4 ); + tmp = malloc( len ); + remove_emulation_prevention( buf, tmp, len, &dst_len ); + sequence_header( this_gen, tmp+4, dst_len-4 ); + free( tmp ); break; case entry_point_code: lprintf("entry_point_code\n"); - entry_point( this_gen, buf+4, len-4 ); + tmp = malloc( len ); + remove_emulation_prevention( buf, tmp, len, &dst_len ); + entry_point( this_gen, tmp+4, dst_len-4 ); + free( tmp ); break; case sequence_end_code: lprintf("sequence_end_code\n"); @@ -733,20 +778,18 @@ static void decode_picture( vdpau_vc1_decoder_t *vd ) if ( len < 2 ) pic->skipped = 1; - - if ( pic->vdp_infos.interlace && pic->vdp_infos.frame_coding_mode == PICTURE_FIELD_INTERLACE ) { - if ( !(field = search_field( vd, buf, len )) ) - lprintf("error, no fields found!\n"); - else - pic->field = field; - } } else { seq->picture.vdp_infos.slice_count = 1; buf = seq->buf+seq->start+4; len = seq->bufseek-seq->start-4; - if ( seq->profile==VDP_DECODER_PROFILE_VC1_ADVANCED ) - picture_header_advanced( vd, buf, len ); + if ( seq->profile==VDP_DECODER_PROFILE_VC1_ADVANCED ) { + int tmplen = (len>50) ? 50 : len; + uint8_t *tmp = malloc( tmplen ); + remove_emulation_prevention( buf, tmp, tmplen, &tmplen ); + picture_header_advanced( vd, tmp, tmplen ); + free( tmp ); + } else picture_header( vd, buf, len ); @@ -754,6 +797,13 @@ static void decode_picture( vdpau_vc1_decoder_t *vd ) pic->skipped = 1; } + if ( pic->vdp_infos.interlace && pic->vdp_infos.frame_coding_mode == PICTURE_FIELD_INTERLACE ) { + if ( !(field = search_field( vd, buf, len )) ) + lprintf("error, no fields found!\n"); + else + pic->field = field; + } + VdpPictureInfoVC1 *info = &(seq->picture.vdp_infos); lprintf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n\n", info->slice_count, info->picture_type, info->frame_coding_mode, info->postprocflag, info->pulldown, info->interlace, info->tfcntrflag, info->finterpflag, info->psf, info->dquant, info->panscan_flag, info->refdist_flag, info->quantizer, info->extended_mv, info->extended_dmv, info->overlap, info->vstransform, info->loopfilter, info->fastuvmc, info->range_mapy_flag, info->range_mapy, info->range_mapuv_flag, info->range_mapuv, info->multires, info->syncmarker, info->rangered, info->maxbframes, info->deblockEnable, info->pquant ); @@ -922,6 +972,7 @@ static void vdpau_vc1_decode_data (video_decoder_t *this_gen, buf_element_t *buf } } else { + int res; while ( seq->bufseek <= seq->bufpos-4 ) { uint8_t *buffer = seq->buf+seq->bufseek; if ( buffer[0]==0 && buffer[1]==0 && buffer[2]==1 ) { @@ -932,17 +983,20 @@ static void vdpau_vc1_decode_data (video_decoder_t *this_gen, buf_element_t *buf seq->seq_pts = seq->cur_pts; } else { - if ( parse_code( this, seq->buf+seq->start, seq->bufseek-seq->start ) ) { + res = parse_code( this, seq->buf+seq->start, seq->bufseek-seq->start ); + if ( res==1 ) { decode_picture( this ); parse_code( this, seq->buf+seq->start, seq->bufseek-seq->start ); } - uint8_t *tmp = (uint8_t*)malloc(seq->bufsize); - xine_fast_memcpy( tmp, seq->buf+seq->bufseek, seq->bufpos-seq->bufseek ); - seq->bufpos -= seq->bufseek; - seq->start = -1; - seq->bufseek = -1; - free( seq->buf ); - seq->buf = tmp; + if ( res!=-1 ) { + uint8_t *tmp = (uint8_t*)malloc(seq->bufsize); + xine_fast_memcpy( tmp, seq->buf+seq->bufseek, seq->bufpos-seq->bufseek ); + seq->bufpos -= seq->bufseek; + seq->start = -1; + seq->bufseek = -1; + free( seq->buf ); + seq->buf = tmp; + } } } ++seq->bufseek; |