summaryrefslogtreecommitdiff
path: root/libavcodec/h263.c
diff options
context:
space:
mode:
authorKostya Shishkov <kostya.shishkov@gmail.com>2009-03-03 05:17:22 +0000
committerKostya Shishkov <kostya.shishkov@gmail.com>2009-03-03 05:17:22 +0000
commit685502cf3dce8c48aa530001c58ed37bad59d74a (patch)
treeb4ad529c8973462f36844151bfa71e358d6f038c /libavcodec/h263.c
parent6053da0182c4368874f0823bb244010236036b02 (diff)
Add PB-frame decoding support for H.263/i263 (and enable it for i263)
Originally committed as revision 17745 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/h263.c')
-rw-r--r--libavcodec/h263.c56
1 files changed, 52 insertions, 4 deletions
diff --git a/libavcodec/h263.c b/libavcodec/h263.c
index f4b1360109..4a1f8496ec 100644
--- a/libavcodec/h263.c
+++ b/libavcodec/h263.c
@@ -40,6 +40,7 @@
#include "h263data.h"
#include "mpeg4data.h"
#include "mathops.h"
+#include "unary.h"
//#undef NDEBUG
//#include <assert.h>
@@ -3905,12 +3906,50 @@ static void h263_decode_dquant(MpegEncContext *s){
ff_set_qscale(s, s->qscale);
}
+static int h263_skip_b_part(MpegEncContext *s, int cbp)
+{
+ DECLARE_ALIGNED(16, DCTELEM, dblock[64]);
+ int i, mbi;
+
+ /* we have to set s->mb_intra to zero to decode B-part of PB-frame correctly
+ * but real value should be restored in order to be used later (in OBMC condition)
+ */
+ mbi = s->mb_intra;
+ 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 = mbi;
+ return 0;
+}
+
+static int h263_get_modb(GetBitContext *gb, int pb_frame, int *cbpb)
+{
+ int c, mv = 1;
+
+ if (pb_frame < 3) { // h.263 Annex G and i263 PB-frame
+ c = get_bits1(gb);
+ if (pb_frame == 2 && c)
+ mv = !get_bits1(gb);
+ } else { // h.263 Annex M improved PB-frame
+ mv = get_unary(gb, 0, 4) + 1;
+ c = mv & 1;
+ mv = !!(mv & 2);
+ }
+ if(c)
+ *cbpb = get_bits(gb, 6);
+ return mv;
+}
+
int ff_h263_decode_mb(MpegEncContext *s,
DCTELEM block[6][64])
{
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, pb_mv_count = 0;
assert(!s->h263_pred);
@@ -3943,6 +3982,8 @@ int ff_h263_decode_mb(MpegEncContext *s,
s->mb_intra = ((cbpc & 4) != 0);
if (s->mb_intra) goto intra;
+ if(s->pb_frame && get_bits1(&s->gb))
+ pb_mv_count = h263_get_modb(&s->gb, s->pb_frame, &cbpb);
cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1);
if(s->alt_inter_vlc==0 || (cbpc & 3)!=3)
@@ -4118,6 +4159,8 @@ intra:
}else
s->ac_pred = 0;
+ if(s->pb_frame && get_bits1(&s->gb))
+ pb_mv_count = h263_get_modb(&s->gb, s->pb_frame, &cbpb);
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);
@@ -4127,6 +4170,13 @@ intra:
if (dquant) {
h263_decode_dquant(s);
}
+
+ pb_mv_count += !!s->pb_frame;
+ }
+
+ while(pb_mv_count--){
+ h263_decode_motion(s, 0, 1);
+ h263_decode_motion(s, 0, 1);
}
/* decode each block */
@@ -4136,6 +4186,8 @@ intra:
cbp+=cbp;
}
+ if(s->pb_frame && h263_skip_b_part(s, cbpb) < 0)
+ return -1;
if(s->obmc && !s->mb_intra){
if(s->pict_type == FF_P_TYPE && s->mb_x+1<s->mb_width && s->mb_num_left != 1)
preview_obmc(s);
@@ -6241,10 +6293,6 @@ int intel_h263_decode_picture_header(MpegEncContext *s)
if(s->avctx->debug&FF_DEBUG_PICT_INFO)
show_pict_info(s);
- if(s->pb_frame){
- av_log(s->avctx, AV_LOG_ERROR, "PB frame mode no supported\n");
- return -1; /* PB frame mode */
- }
return 0;
}