# HG changeset patch # User pulento # Date 1006135994 0 # Node ID de80712db90b320441bac48fd0a6a6a736f9bcae # Parent 7ce36cf13055dfc4fcaed894bb03e81a5b27d293 - Preliminary RTP friendly mode for H.263. - GOB headers for H.263 coding on RTP mode. - Improved GOB header detection for H.263 decoder. diff -r 7ce36cf13055 -r de80712db90b avcodec.h --- a/avcodec.h Sat Nov 17 21:14:54 2001 +0000 +++ b/avcodec.h Mon Nov 19 02:13:14 2001 +0000 @@ -103,6 +103,19 @@ struct AVCodec *codec; void *priv_data; + /* The following data is for RTP friendly coding */ + /* By now only H.263/H.263+ coder honours this */ + int rtp_mode; /* 1 for activate RTP friendly-mode */ + /* highers numbers represent more error-prone */ + /* enviroments, by now just "1" exist */ + + int rtp_payload_size; /* The size of the RTP payload, the coder will */ + /* do it's best to deliver a chunk with size */ + /* below rtp_payload_size, the chunk will start */ + /* with a start code on some codecs like H.263 */ + /* This doesn't take account of any particular */ + /* headers inside the transmited RTP payload */ + /* the following fields are ignored */ void *opaque; /* can be used to carry app specific stuff */ char codec_name[32]; @@ -239,8 +252,8 @@ #ifdef FF_POSTPROCESS #ifndef MBC -#define MBC 120 -#define MBR 72 +#define MBC 48 +#define MBR 36 #endif extern int quant_store[MBR+1][MBC+1]; // [Review] #endif diff -r 7ce36cf13055 -r de80712db90b h263.c --- a/h263.c Sat Nov 17 21:14:54 2001 +0000 +++ b/h263.c Mon Nov 19 02:13:14 2001 +0000 @@ -140,12 +140,45 @@ put_bits(&s->pb, 1, 0); /* no PEI */ } +int h263_encode_gob_header(MpegEncContext * s, int mb_line) +{ + int pdif=0; + + /* Check to see if we need to put a new GBSC */ + /* for RTP packetization */ + if (s->rtp_mode) { + pdif = s->pb.buf_ptr - s->ptr_lastgob; + if (pdif >= s->rtp_payload_size) { + /* Bad luck, packet must be cut before */ + align_put_bits(&s->pb); + s->ptr_lastgob = s->pb.buf_ptr; + put_bits(&s->pb, 17, 1); /* GBSC */ + s->gob_number = mb_line; + put_bits(&s->pb, 5, s->gob_number); /* GN */ + put_bits(&s->pb, 2, 1); /* GFID */ + put_bits(&s->pb, 5, s->qscale); /* GQUANT */ + return pdif; + } else if (pdif + s->mb_line_avgsize >= s->rtp_payload_size) { + /* Cut the packet before we can't */ + align_put_bits(&s->pb); + s->ptr_lastgob = s->pb.buf_ptr; + put_bits(&s->pb, 17, 1); /* GBSC */ + s->gob_number = mb_line; + put_bits(&s->pb, 5, s->gob_number); /* GN */ + put_bits(&s->pb, 2, 1); /* GFID */ + put_bits(&s->pb, 5, s->qscale); /* GQUANT */ + return pdif; + } + } + return 0; +} + void h263_encode_mb(MpegEncContext * s, DCTELEM block[6][64], int motion_x, int motion_y) { int cbpc, cbpy, i, cbp, pred_x, pred_y; - + // printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y); if (!s->mb_intra) { /* compute cbp */ @@ -772,42 +805,38 @@ } } +int h263_decode_gob_header(MpegEncContext *s) +{ + unsigned int val, gfid; + + /* Check for GOB Start Code */ + val = show_bits(&s->gb, 16); + if (val == 0) { + /* We have a GBSC probably with GSTUFF */ + skip_bits(&s->gb, 16); /* Drop the zeros */ + while (get_bits1(&s->gb) == 0); /* Seek the '1' bit */ +#ifdef DEBUG + fprintf(stderr,"\nGOB Start Code at MB %d\n", (s->mb_y * s->mb_width) + s->mb_x); +#endif + s->gob_number = get_bits(&s->gb, 5); /* GN */ + gfid = get_bits(&s->gb, 2); /* GFID */ + s->qscale = get_bits(&s->gb, 5); /* GQUANT */ +#ifdef DEBUG + fprintf(stderr, "\nGN: %u GFID: %u Quant: %u\n", gn, gfid, s->qscale); +#endif + return 1; + } + return 0; + +} + int h263_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) { int cbpc, cbpy, i, cbp, pred_x, pred_y, mx, my, dquant; - unsigned int val; INT16 *mot_val; static INT8 quant_tab[4] = { -1, -2, 1, 2 }; - unsigned int gfid; - /* Check for GOB Start Code */ - if (s->mb_x == 0) { - val = show_bits(&s->gb, 16); - if (val == 0) { - /* We have a GBSC probably with GSTUFF */ - skip_bits(&s->gb, 16); /* Drop the zeros */ - while (get_bits1(&s->gb) == 0); /* Seek the '1' bit */ -#ifdef DEBUG - fprintf(stderr,"\nGOB Start Code at MB %d\n", - (s->mb_y * s->mb_width) + s->mb_x); -#endif - s->gob_number = get_bits(&s->gb, 5); /* GN */ - gfid = get_bits(&s->gb, 2); /* GFID */ - s->qscale = get_bits(&s->gb, 5); /* GQUANT */ -#ifdef DEBUG - fprintf(stderr, "\nGN: %u GFID: %u Quant: %u\n", gn, gfid, s->qscale); -#endif - } - } - /* FIXME: In the future H.263+ will have intra prediction */ - /* and we are gonna need another way to detect MPEG4 */ - if (!s->h263_pred) { - if (s->mb_y == s->gob_number) - s->first_gob_line = 1; - else - s->first_gob_line = 0; - } if (s->pict_type == P_TYPE) { if (get_bits1(&s->gb)) { /* skip mb */ diff -r 7ce36cf13055 -r de80712db90b h263dec.c --- a/h263dec.c Sat Nov 17 21:14:54 2001 +0000 +++ b/h263dec.c Mon Nov 19 02:13:14 2001 +0000 @@ -140,6 +140,12 @@ /* decode each macroblock */ for(s->mb_y=0; s->mb_y < s->mb_height; s->mb_y++) { + /* Check for GOB headers on H.263 */ + /* FIXME: In the future H.263+ will have intra prediction */ + /* and we are gonna need another way to detect MPEG4 */ + if (s->mb_y && !s->h263_pred) { + s->first_gob_line = h263_decode_gob_header(s); + } for(s->mb_x=0; s->mb_x < s->mb_width; s->mb_x++) { #ifdef DEBUG printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y); diff -r 7ce36cf13055 -r de80712db90b mpegvideo.c --- a/mpegvideo.c Sat Nov 17 21:14:54 2001 +0000 +++ b/mpegvideo.c Mon Nov 19 02:13:14 2001 +0000 @@ -249,6 +249,9 @@ s->width = avctx->width; s->height = avctx->height; s->gop_size = avctx->gop_size; + s->rtp_mode = avctx->rtp_mode; + s->rtp_payload_size = avctx->rtp_payload_size; + if (s->gop_size <= 1) { s->intra_only = 1; s->gop_size = 12; @@ -276,6 +279,8 @@ break; case CODEC_ID_H263P: s->out_format = FMT_H263; + s->rtp_mode = 1; + s->rtp_payload_size = 1200; s->h263_plus = 1; s->unrestricted_mv = 1; @@ -819,7 +824,7 @@ static void encode_picture(MpegEncContext *s, int picture_number) { - int mb_x, mb_y, wrap; + int mb_x, mb_y, wrap, last_gob; UINT8 *ptr; int i, motion_x, motion_y; @@ -869,7 +874,29 @@ s->mv_type = MV_TYPE_16X16; s->mv_dir = MV_DIR_FORWARD; + /* Get the GOB height based on picture height */ + if (s->out_format == FMT_H263 && s->h263_plus) { + if (s->height <= 400) + s->gob_index = 1; + else if (s->height <= 800) + s->gob_index = 2; + else + s->gob_index = 4; + } + for(mb_y=0; mb_y < s->mb_height; mb_y++) { + /* Put GOB header based on RTP MTU */ + if (!mb_y) { + s->ptr_lastgob = s->pb.buf_ptr; + s->ptr_last_mb_line = s->pb.buf_ptr; + } else if (s->out_format == FMT_H263 && s->h263_plus) { + last_gob = h263_encode_gob_header(s, mb_y); + if (last_gob) { + //fprintf(stderr,"\nLast GOB size: %d", last_gob); + s->first_gob_line = 1; + } else + s->first_gob_line = 0; + } for(mb_x=0; mb_x < s->mb_width; mb_x++) { s->mb_x = mb_x; @@ -981,7 +1008,17 @@ MPV_decode_mb(s, s->block); } + /* Obtain average MB line size for RTP */ + if (!mb_y) + s->mb_line_avgsize = s->pb.buf_ptr - s->ptr_last_mb_line; + else + s->mb_line_avgsize = (s->mb_line_avgsize + s->pb.buf_ptr - s->ptr_last_mb_line) >> 1; + //fprintf(stderr, "\nMB line: %d\tSize: %u\tAvg. Size: %u", s->mb_y, + // (s->pb.buf_ptr - s->ptr_last_mb_line), s->mb_line_avgsize); + s->ptr_last_mb_line = s->pb.buf_ptr; } + //if (s->gob_number) + // fprintf(stderr,"\nNumber of GOB: %d", s->gob_number); } static int dct_quantize(MpegEncContext *s, diff -r 7ce36cf13055 -r de80712db90b mpegvideo.h --- a/mpegvideo.h Sat Nov 17 21:14:54 2001 +0000 +++ b/mpegvideo.h Mon Nov 19 02:13:14 2001 +0000 @@ -131,6 +131,7 @@ /* H.263 specific */ int gob_number; + int gob_index; int first_gob_line; /* H.263+ specific */ @@ -185,7 +186,14 @@ int interlaced_dct; int last_qscale; int first_slice; - + + /* RTP specific */ + int rtp_mode; + int rtp_payload_size; + UINT8 *ptr_lastgob; + UINT8 *ptr_last_mb_line; + UINT32 mb_line_avgsize; + DCTELEM block[6][64] __align8; void (*dct_unquantize)(struct MpegEncContext *s, DCTELEM *block, int n, int qscale); @@ -236,7 +244,7 @@ void init_rl(RLTable *rl); void init_vlc_rl(RLTable *rl); -static inline int get_rl_index(const RLTable *rl, int last, int run, int level) +extern inline int get_rl_index(const RLTable *rl, int last, int run, int level) { int index; index = rl->index_run[last][run]; @@ -251,6 +259,7 @@ DCTELEM block[6][64], int motion_x, int motion_y); void h263_encode_picture_header(MpegEncContext *s, int picture_number); +int h263_encode_gob_header(MpegEncContext * s, int mb_line); void h263_dc_scale(MpegEncContext *s); INT16 *h263_pred_motion(MpegEncContext * s, int block, int *px, int *py); @@ -261,6 +270,7 @@ void h263_decode_init_vlc(MpegEncContext *s); int h263_decode_picture_header(MpegEncContext *s); +int h263_decode_gob_header(MpegEncContext *s); int mpeg4_decode_picture_header(MpegEncContext * s); int intel_h263_decode_picture_header(MpegEncContext *s); int h263_decode_mb(MpegEncContext *s,