[FFmpeg-devel] [PATCH] PB-frames support for i263

Michael Niedermayer michaelni
Tue Feb 17 14:28:00 CET 2009


On Tue, Feb 17, 2009 at 09:30:43AM +0200, Kostya wrote:
> $subj
> 
> For now it decodes only P part of PB frames and skips B blocks part
> (excellent idea to store data for two frames in one).

yes, PB frames where one of the most idiotic things in h263
the commitee apparently has never bother to ask the question how hard
some of these things may be to support in non academic implementations
(the complete lack of unambigous timestamps in mpeg-ps/ts and especially
h264 in them is another example, a single integer per packet would have
avoided hundreads of hours of work and lines of code)


> 
> Samples are at http://samples.mplayerhq.hu/A-codecs/IMC/

> Index: libavcodec/h263.c
> ===================================================================
> --- libavcodec/h263.c	(revision 16921)
> +++ libavcodec/h263.c	(working copy)
> @@ -3892,6 +3892,8 @@
>      int cbpc, cbpy, i, cbp, pred_x, pred_y, mx, my, dquant;
>      int16_t *mot_val;
>      const int xy= s->mb_x + s->mb_y * s->mb_stride;
> +    int cbpb = 0, mvdb = 0;
> +    DECLARE_ALIGNED(16, DCTELEM, dblock[64]);
>  
>      assert(!s->h263_pred);
>  
> @@ -3924,6 +3926,23 @@
>          s->mb_intra = ((cbpc & 4) != 0);
>          if (s->mb_intra) goto intra;
>  
> +        if(s->pb_frame){

> +            if(s->impr_pb_frame){
> +                if(get_bits1(&s->gb)){
> +                    cbpb = get_bits1(&s->gb);
> +                    if(cbpb)
> +                        mvdb = !get_bits1(&s->gb);
> +                    else
> +                        mvdb = 1;
> +                }
> +            }else{
> +                mvdb = get_bits1(&s->gb);
> +                if(mvdb)
> +                    cbpb = get_bits1(&s->gb);
> +            }

if(get_bits1(&s->gb)){
    cbpb = get_bits1(&s->gb);
    if(cbpb && s->pb_frame == 2) mvdb = !get_bits1(&s->gb);
    else                         mvdb = 1;
}


> +            if(cbpb)
> +                cbpb = get_bits(&s->gb, 6);
> +        }
>          cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1);
>  
>          if(s->alt_inter_vlc==0 || (cbpc & 3)!=3)
> @@ -3987,12 +4006,25 @@
>              }
>          }
>  
> +        if(mvdb){
> +            h263_decode_motion(s, 0, 1);
> +            h263_decode_motion(s, 0, 1);
> +        }
> +
>          /* decode each block */
>          for (i = 0; i < 6; i++) {
>              if (h263_decode_block(s, block[i], i, cbp&32) < 0)
>                  return -1;
>              cbp+=cbp;
>          }
> +        if(s->pb_frame){
> +            cbp = cbpb;
> +            for (i = 0; i < 6; i++) {
> +                if (h263_decode_block(s, dblock, i, cbp&32) < 0)
> +                    return -1;
> +                cbp+=cbp;
> +            }        
> +        }
>  
>          if(s->obmc){
>              if(s->pict_type == FF_P_TYPE && s->mb_x+1<s->mb_width && s->mb_num_left != 1)

> @@ -4118,6 +4150,23 @@
>          }else
>              s->ac_pred = 0;
>  
> +        if(s->pb_frame){
> +            if(s->impr_pb_frame){
> +                if(get_bits1(&s->gb)){
> +                    cbpb = get_bits1(&s->gb);
> +                    if(cbpb)
> +                        mvdb = !get_bits1(&s->gb);
> +                    else
> +                        mvdb = 1;
> +                }
> +            }else{
> +                mvdb = get_bits1(&s->gb);
> +                if(mvdb)
> +                    cbpb = get_bits1(&s->gb);
> +            }
> +            if(cbpb)
> +                cbpb = get_bits(&s->gb, 6);
> +        }
>          cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1);
>          if(cbpy<0){
>              av_log(s->avctx, AV_LOG_ERROR, "I cbpy damaged at %d %d\n", s->mb_x, s->mb_y);

duplicate



> @@ -4128,12 +4177,31 @@
>              h263_decode_dquant(s);
>          }
>  

> +        if(s->pb_frame){
> +            h263_decode_motion(s, 0, 1);
> +            h263_decode_motion(s, 0, 1);
> +        }
> +        if(mvdb){
> +            h263_decode_motion(s, 0, 1);
> +            h263_decode_motion(s, 0, 1);
> +        }

mvdb += !!s->pb_frame;
while(mvdb--){
    h263_decode_motion(s, 0, 1);
    h263_decode_motion(s, 0, 1);
}

also rename mvdb to pb_mv_count


> +
>          /* decode each block */
>          for (i = 0; i < 6; i++) {
>              if (h263_decode_block(s, block[i], i, cbp&32) < 0)
>                  return -1;
>              cbp+=cbp;
>          }

> +        if(s->pb_frame){
> +            cbp = cbpb;
> +            s->mb_intra = 0;
> +            for (i = 0; i < 6; i++) {
> +                if (h263_decode_block(s, dblock, i, cbp&32) < 0)
> +                    return -1;
> +                cbp+=cbp;
> +            }
> +            s->mb_intra = 1;
> +        }
>      }
>  end:
>  

> @@ -6149,6 +6217,8 @@
>  {
>      int format;
>  
> +    if(s->gb.buffer_end - s->gb.buffer == 8)
> +        return -1;
>      /* picture header */
>      if (get_bits_long(&s->gb, 22) != 0x20) {
>          av_log(s->avctx, AV_LOG_ERROR, "Bad picture start code\n");

explain ...


> @@ -6185,17 +6255,34 @@
>          return -1;      /* SAC: off */
>      }
>      s->obmc= get_bits1(&s->gb);
> -    if (get_bits1(&s->gb) != 0) {
> -        av_log(s->avctx, AV_LOG_ERROR, "PB frame mode no supported\n");
> -        return -1;      /* PB frame mode */
> +    s->pb_frame = get_bits1(&s->gb);
> +    s->impr_pb_frame = 0;
> +
> +    if(format == 7){
> +        format = get_bits(&s->gb, 3);
> +        if(format == 0 || format == 7){
> +            av_log(s->avctx, AV_LOG_ERROR, "Wrong Intel H263 format\n");
> +            return -1;        
> +        }
> +        skip_bits(&s->gb, 2);
> +        s->loop_filter = get_bits1(&s->gb);
> +        skip_bits(&s->gb, 1);
> +        s->impr_pb_frame = get_bits1(&s->gb);
> +        skip_bits(&s->gb, 10);
> +    }else{
> +        s->loop_filter = 0;

do you have a file that falls in this else category?
it at least has to be a seperate patch as its not related to pb
frames rather an extension of the fixed skip_bits 41


>      }
> +    if(format == 6)
> +        skip_bits(&s->gb, 23);
>  
> -    /* skip unknown header garbage */
> -    skip_bits(&s->gb, 41);
> -
>      s->chroma_qscale= s->qscale = get_bits(&s->gb, 5);
>      skip_bits1(&s->gb); /* Continuous Presence Multipoint mode: off */
>  
> +    if(s->pb_frame){
> +        skip_bits(&s->gb, 3); //temporal reference for B-frame
> +        skip_bits(&s->gb, 2); //dbquant
> +    }
> +
>      /* PEI */
>      while (get_bits1(&s->gb) != 0) {
>          skip_bits(&s->gb, 8);
> Index: libavcodec/mpegvideo.h
> ===================================================================
> --- libavcodec/mpegvideo.h	(revision 16921)
> +++ libavcodec/mpegvideo.h	(working copy)
> @@ -201,6 +201,8 @@
>      int bit_rate;     ///< wanted bit rate
>      enum OutputFormat out_format; ///< output format
>      int h263_pred;    ///< use mpeg4/h263 ac/dc predictions

> +    int pb_frame;     ///< PB frame mode
> +    int impr_pb_frame;///< improved PB frame mode

impr_pb_frame can be merged in pb_frame==2

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

In a rich man's house there is no place to spit but his face.
-- Diogenes of Sinope
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090217/a40df99c/attachment.pgp>



More information about the ffmpeg-devel mailing list