Mercurial > libavcodec.hg
changeset 1661:4c9fd29f1606 libavcodec
h263 slice structured mode
slice cleanup
author | michael |
---|---|
date | Sun, 07 Dec 2003 01:33:45 +0000 |
parents | 806afb8e9085 |
children | 64c370fe6e88 |
files | avcodec.h h263.c h263dec.c i386/mpegvideo_mmx.c mpegvideo.c mpegvideo.h rv10.c |
diffstat | 7 files changed, 178 insertions(+), 126 deletions(-) [+] |
line wrap: on
line diff
--- a/avcodec.h Fri Dec 05 23:12:03 2003 +0000 +++ b/avcodec.h Sun Dec 07 01:33:45 2003 +0000 @@ -17,7 +17,7 @@ #define FFMPEG_VERSION_INT 0x000408 #define FFMPEG_VERSION "0.4.8" -#define LIBAVCODEC_BUILD 4693 +#define LIBAVCODEC_BUILD 4694 #define LIBAVCODEC_VERSION_INT FFMPEG_VERSION_INT #define LIBAVCODEC_VERSION FFMPEG_VERSION @@ -263,14 +263,11 @@ #define CODEC_FLAG_H263P_AIV 0x00000008 ///< H263 Alternative inter vlc #define CODEC_FLAG_OBMC 0x00000001 ///< OBMC #define CODEC_FLAG_LOOP_FILTER 0x00000800 ///< loop filter -/* For advanced prediction mode, we reuse the 4MV flag */ +#define CODEC_FLAG_H263P_SLICE_STRUCT 0x10000000 /* Unsupported options : * Syntax Arithmetic coding (SAC) - * Deblocking filter internal loop - * Slice structured * Reference Picture Selection - * Independant Segment Decoding - * Modified Quantization */ + * Independant Segment Decoding */ /* /Fx */ /* codec capabilities */ @@ -696,11 +693,8 @@ void *priv_data; - /* The following data is for RTP friendly coding */ - /* By now only H.263/H.263+/MPEG4 coder honours this */ - int rtp_mode; /* 1 for activate RTP friendly-mode */ - /* highers numbers represent more error-prone */ - /* enviroments, by now just "1" exist */ + /* unused, FIXME remove*/ + int rtp_mode; int rtp_payload_size; /* The size of the RTP payload, the coder will */ /* do it's best to deliver a chunk with size */ @@ -1398,7 +1392,27 @@ * - decoding: set by lavc, user can override */ int (*reget_buffer)(struct AVCodecContext *c, AVFrame *pic); - + + /** + * number of bits which should be loaded into the rc buffer before decoding starts + * - encoding: set by user. + * - decoding: unused + */ + int rc_initial_buffer_occupancy; + + /** + * + * - encoding: set by user. + * - decoding: unused + */ + int inter_threshold; + + /** + * CODEC_FLAG2_*. + * - encoding: set by user. + * - decoding: set by user. + */ + int flags2; } AVCodecContext;
--- a/h263.c Fri Dec 05 23:12:03 2003 +0000 +++ b/h263.c Sun Dec 07 01:33:45 2003 +0000 @@ -202,8 +202,6 @@ /* Update the pointer to last GOB */ s->ptr_lastgob = pbBufPtr(&s->pb); - s->gob_number = 0; - put_bits(&s->pb, 22, 0x20); /* PSC */ put_bits(&s->pb, 8, (((int64_t)s->picture_number * 30 * s->avctx->frame_rate_base) / s->avctx->frame_rate) & 0xff); @@ -239,12 +237,12 @@ put_bits(&s->pb, 3, format); put_bits(&s->pb,1,0); /* Custom PCF: off */ - put_bits(&s->pb, 1, s->umvplus); /* Unrestricted Motion Vector */ + put_bits(&s->pb,1, s->umvplus); /* Unrestricted Motion Vector */ put_bits(&s->pb,1,0); /* SAC: off */ put_bits(&s->pb,1,s->obmc); /* Advanced Prediction Mode */ put_bits(&s->pb,1,s->h263_aic); /* Advanced Intra Coding */ put_bits(&s->pb,1,s->loop_filter); /* Deblocking Filter */ - put_bits(&s->pb,1,0); /* Slice Structured: off */ + put_bits(&s->pb,1,s->h263_slice_structured); /* Slice Structured */ put_bits(&s->pb,1,0); /* Reference Picture Selection: off */ put_bits(&s->pb,1,0); /* Independent Segment Decoding: off */ put_bits(&s->pb,1,s->alt_inter_vlc); /* Alternative Inter VLC */ @@ -282,6 +280,8 @@ // put_bits(&s->pb,1,1); /* Limited according tables of Annex D */ //FIXME check actual requested range put_bits(&s->pb,2,1); /* unlimited */ + if(s->h263_slice_structured) + put_bits(&s->pb,2,0); /* no weird submodes */ put_bits(&s->pb, 5, s->qscale); } @@ -300,22 +300,27 @@ /** * Encodes a group of blocks header. */ -int h263_encode_gob_header(MpegEncContext * s, int mb_line) +void h263_encode_gob_header(MpegEncContext * s, int mb_line) { - align_put_bits(&s->pb); - flush_put_bits(&s->pb); - /* Call the RTP callback to send the last GOB */ - if (s->rtp_callback) { - int pdif = pbBufPtr(&s->pb) - s->ptr_lastgob; - s->rtp_callback(s->ptr_lastgob, pdif, s->gob_number); - } - put_bits(&s->pb, 17, 1); /* GBSC */ - s->gob_number = mb_line / s->gob_index; - put_bits(&s->pb, 5, s->gob_number); /* GN */ - put_bits(&s->pb, 2, s->pict_type == I_TYPE); /* GFID */ - put_bits(&s->pb, 5, s->qscale); /* GQUANT */ - //fprintf(stderr,"\nGOB: %2d size: %d", s->gob_number - 1, pdif); - return 0; + put_bits(&s->pb, 17, 1); /* GBSC */ + + if(s->h263_slice_structured){ + put_bits(&s->pb, 1, 1); + + ff_h263_encode_mba(s); + + if(s->mb_num > 1583) + put_bits(&s->pb, 1, 1); + put_bits(&s->pb, 5, s->qscale); /* GQUANT */ + put_bits(&s->pb, 1, 1); + put_bits(&s->pb, 2, s->pict_type == I_TYPE); /* GFID */ + }else{ + int gob_number= mb_line / s->gob_index; + + put_bits(&s->pb, 5, gob_number); /* GN */ + put_bits(&s->pb, 2, s->pict_type == I_TYPE); /* GFID */ + put_bits(&s->pb, 5, s->qscale); /* GQUANT */ + } } static inline int get_block_rate(MpegEncContext * s, DCTELEM block[64], int block_last_index, uint8_t scantable[64]){ @@ -2784,13 +2789,38 @@ return 4; } +int ff_h263_decode_mba(MpegEncContext *s) +{ + int i, mb_pos; + + for(i=0; i<6; i++){ + if(s->mb_num < ff_mba_max[i]) break; + } + mb_pos= get_bits(&s->gb, ff_mba_length[i]); + s->mb_x= mb_pos % s->mb_width; + s->mb_y= mb_pos / s->mb_width; + + return mb_pos; +} + +void ff_h263_encode_mba(MpegEncContext *s) +{ + int i, mb_pos; + + for(i=0; i<6; i++){ + if(s->mb_num < ff_mba_max[i]) break; + } + mb_pos= s->mb_x + s->mb_width*s->mb_y; + put_bits(&s->pb, ff_mba_length[i], mb_pos); +} + /** - * decodes the group of blocks header. + * decodes the group of blocks header or slice header. * @return <0 if an error occured */ static int h263_decode_gob_header(MpegEncContext *s) { - unsigned int val, gfid; + unsigned int val, gfid, gob_number; int left; /* Check for GOB Start Code */ @@ -2808,22 +2838,34 @@ if(left<=13) return -1; -#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 */ + if(s->h263_slice_structured){ + if(get_bits1(&s->gb)==0) + return -1; + + ff_h263_decode_mba(s); + + if(s->mb_num > 1583) + if(get_bits1(&s->gb)==0) + return -1; + + s->qscale = get_bits(&s->gb, 5); /* SQUANT */ + if(get_bits1(&s->gb)==0) + return -1; + gfid = get_bits(&s->gb, 2); /* GFID */ + }else{ + gob_number = get_bits(&s->gb, 5); /* GN */ + s->mb_x= 0; + s->mb_y= s->gob_index* gob_number; + gfid = get_bits(&s->gb, 2); /* GFID */ + s->qscale = get_bits(&s->gb, 5); /* GQUANT */ + } + + if(s->mb_y >= s->mb_height) + return -1; + if(s->qscale==0) return -1; - s->mb_x= 0; - s->mb_y= s->gob_index* s->gob_number; - if(s->mb_y >= s->mb_height) - return -1; -#ifdef DEBUG - fprintf(stderr, "\nGN: %u GFID: %u Quant: %u\n", s->gob_number, gfid, s->qscale); -#endif return 0; } @@ -2889,7 +2931,6 @@ { int mb_num_bits= av_log2(s->mb_num - 1) + 1; - ff_mpeg4_stuffing(&s->pb); put_bits(&s->pb, ff_mpeg4_get_video_packet_prefix_length(s), 0); put_bits(&s->pb, 1, 1); @@ -4759,9 +4800,6 @@ skip_bits1(&s->gb); /* camera off */ skip_bits1(&s->gb); /* freeze picture release off */ - /* Reset GOB number */ - s->gob_number = 0; - format = get_bits(&s->gb, 3); /* 0 forbidden @@ -4820,9 +4858,7 @@ s->loop_filter= get_bits1(&s->gb); s->unrestricted_mv = s->umvplus || s->obmc || s->loop_filter; - if (get_bits1(&s->gb) != 0) { - av_log(s->avctx, AV_LOG_ERROR, "Slice Structured not supported\n"); - } + s->h263_slice_structured= get_bits1(&s->gb); if (get_bits1(&s->gb) != 0) { av_log(s->avctx, AV_LOG_ERROR, "Reference Picture Selection not supported\n"); } @@ -4894,6 +4930,14 @@ if(get_bits1(&s->gb)==0) /* Unlimited Unrestricted Motion Vectors Indicator (UUI) */ skip_bits1(&s->gb); } + if(s->h263_slice_structured){ + if (get_bits1(&s->gb) != 0) { + av_log(s->avctx, AV_LOG_ERROR, "rectangular slices not supported\n"); + } + if (get_bits1(&s->gb) != 0) { + av_log(s->avctx, AV_LOG_ERROR, "unordered slices not supported\n"); + } + } } s->qscale = get_bits(&s->gb, 5); @@ -4913,7 +4957,7 @@ } if(s->avctx->debug&FF_DEBUG_PICT_INFO){ - av_log(s->avctx, AV_LOG_DEBUG, "qp:%d %c size:%d rnd:%d%s%s%s%s%s%s%s%s\n", + av_log(s->avctx, AV_LOG_DEBUG, "qp:%d %c size:%d rnd:%d%s%s%s%s%s%s%s%s%s\n", s->qscale, av_get_pict_type_char(s->pict_type), s->gb.size_in_bits, 1-s->no_rounding, s->obmc ? " AP" : "", @@ -4923,7 +4967,8 @@ s->h263_aic ? " AIC" : "", s->alt_inter_vlc ? " AIV" : "", s->modified_quant ? " MQ" : "", - s->loop_filter ? " LOOP" : "" + s->loop_filter ? " LOOP" : "", + s->h263_slice_structured ? " SS" : "" ); } #if 1
--- a/h263dec.c Fri Dec 05 23:12:03 2003 +0000 +++ b/h263dec.c Sun Dec 07 01:33:45 2003 +0000 @@ -51,7 +51,6 @@ /* select sub codec */ switch(avctx->codec->id) { case CODEC_ID_H263: - s->gob_number = 0; s->unrestricted_mv= 0; break; case CODEC_ID_MPEG4:
--- a/i386/mpegvideo_mmx.c Fri Dec 05 23:12:03 2003 +0000 +++ b/i386/mpegvideo_mmx.c Sun Dec 07 01:33:45 2003 +0000 @@ -39,7 +39,7 @@ qmul = qscale << 1; qadd = (qscale - 1) | 1; - assert(s->block_last_index[n]>=0); + assert(s->block_last_index[n]>=0 || s->h263_aic); if (s->mb_intra) { if (!s->h263_aic) {
--- a/mpegvideo.c Fri Dec 05 23:12:03 2003 +0000 +++ b/mpegvideo.c Sun Dec 07 01:33:45 2003 +0000 @@ -648,10 +648,6 @@ avctx->gop_size=600; } s->gop_size = avctx->gop_size; - s->rtp_mode = avctx->rtp_mode; - s->rtp_payload_size = avctx->rtp_payload_size; - if (avctx->rtp_callback) - s->rtp_callback = avctx->rtp_callback; s->max_qdiff= avctx->max_qdiff; s->qcompress= avctx->qcompress; s->qblur= avctx->qblur; @@ -666,6 +662,7 @@ s->data_partitioning= avctx->flags & CODEC_FLAG_PART; s->quarter_sample= (avctx->flags & CODEC_FLAG_QPEL)!=0; s->mpeg_quant= avctx->mpeg_quant; + s->rtp_mode= !!avctx->rtp_payload_size; if (s->gop_size <= 1) { s->intra_only = 1; @@ -769,8 +766,7 @@ s->out_format = FMT_MPEG1; s->low_delay= 0; //s->max_b_frames ? 0 : 1; avctx->delay= s->low_delay ? 0 : (s->max_b_frames + 1); - s->rtp_mode= 1; // mpeg2 must have slices - if(s->rtp_payload_size == 0) s->rtp_payload_size= 256*256*256; + s->rtp_mode= 1; break; case CODEC_ID_LJPEG: case CODEC_ID_MJPEG: @@ -811,6 +807,7 @@ s->obmc= (avctx->flags & CODEC_FLAG_OBMC) ? 1:0; s->loop_filter= (avctx->flags & CODEC_FLAG_LOOP_FILTER) ? 1:0; s->unrestricted_mv= s->obmc || s->loop_filter || s->umvplus; + s->h263_slice_structured= (s->flags & CODEC_FLAG_H263P_SLICE_STRUCT) ? 1:0; if(s->modified_quant) s->chroma_qscale_table= ff_h263_chroma_qscale_table; @@ -3889,53 +3886,64 @@ /* write gob / video packet header */ #ifdef CONFIG_RISKY - if(s->rtp_mode && mb_y + mb_x>0){ + if(s->rtp_mode){ int current_packet_size, is_gob_start; current_packet_size= pbBufPtr(&s->pb) - s->ptr_lastgob; - is_gob_start=0; + + is_gob_start= s->avctx->rtp_payload_size && current_packet_size >= s->avctx->rtp_payload_size && mb_y + mb_x>0; + + switch(s->codec_id){ + case CODEC_ID_H263: + case CODEC_ID_H263P: + if(!s->h263_slice_structured) + if(s->mb_x || s->mb_y%s->gob_index) is_gob_start=0; + break; + case CODEC_ID_MPEG2VIDEO: + if(s->mb_x==0 && s->mb_y!=0) is_gob_start=1; + case CODEC_ID_MPEG1VIDEO: + if(s->mb_skip_run) is_gob_start=0; + break; + } - if(s->codec_id==CODEC_ID_MPEG4){ - if(current_packet_size >= s->rtp_payload_size){ - - if(s->partitioned_frame){ - ff_mpeg4_merge_partitions(s); - ff_mpeg4_init_partitions(s); - } + if(is_gob_start){ + if(s->codec_id==CODEC_ID_MPEG4 && s->partitioned_frame){ + ff_mpeg4_merge_partitions(s); + ff_mpeg4_init_partitions(s); + } + + if(s->codec_id==CODEC_ID_MPEG4) + ff_mpeg4_stuffing(&s->pb); + + align_put_bits(&s->pb); +// flush_put_bits(&s->pb); + current_packet_size= pbBufPtr(&s->pb) - s->ptr_lastgob; + + if (s->avctx->rtp_callback) + s->avctx->rtp_callback(s->ptr_lastgob, current_packet_size, 0); + + switch(s->codec_id){ + case CODEC_ID_MPEG4: ff_mpeg4_encode_video_packet_header(s); - - if(s->flags&CODEC_FLAG_PASS1){ - int bits= get_bit_count(&s->pb); - s->misc_bits+= bits - s->last_bits; - s->last_bits= bits; - } ff_mpeg4_clean_buffers(s); - is_gob_start=1; - } - }else if(s->codec_id==CODEC_ID_MPEG1VIDEO){ - if( current_packet_size >= s->rtp_payload_size - && s->mb_skip_run==0){ + break; + case CODEC_ID_MPEG1VIDEO: + case CODEC_ID_MPEG2VIDEO: ff_mpeg1_encode_slice_header(s); ff_mpeg1_clean_buffers(s); - is_gob_start=1; - } - }else if(s->codec_id==CODEC_ID_MPEG2VIDEO){ - if( ( current_packet_size >= s->rtp_payload_size || mb_x==0) - && s->mb_skip_run==0){ - ff_mpeg1_encode_slice_header(s); - ff_mpeg1_clean_buffers(s); - is_gob_start=1; + break; + case CODEC_ID_H263: + case CODEC_ID_H263P: + h263_encode_gob_header(s, mb_y); + break; } - }else{ - if(current_packet_size >= s->rtp_payload_size - && s->mb_x==0 && s->mb_y%s->gob_index==0){ - - h263_encode_gob_header(s, mb_y); - is_gob_start=1; + + if(s->flags&CODEC_FLAG_PASS1){ + int bits= get_bit_count(&s->pb); + s->misc_bits+= bits - s->last_bits; + s->last_bits= bits; } - } - - if(is_gob_start){ + s->ptr_lastgob = pbBufPtr(&s->pb); s->first_slice_line=1; s->resync_mb_x=mb_x; @@ -4256,18 +4264,12 @@ ff_mpeg4_stuffing(&s->pb); #endif - //if (s->gob_number) - // fprintf(stderr,"\nNumber of GOB: %d", s->gob_number); - /* Send the last GOB if RTP */ - if (s->rtp_mode) { + if (s->avctx->rtp_callback) { flush_put_bits(&s->pb); pdif = pbBufPtr(&s->pb) - s->ptr_lastgob; /* Call the RTP callback to send the last GOB */ - if (s->rtp_callback) - s->rtp_callback(s->ptr_lastgob, pdif, s->gob_number); - s->ptr_lastgob = pbBufPtr(&s->pb); - //fprintf(stderr,"\nGOB: %2d size: %d (last)", s->gob_number, pdif); + s->avctx->rtp_callback(s->ptr_lastgob, pdif, 0); } }
--- a/mpegvideo.h Fri Dec 05 23:12:03 2003 +0000 +++ b/mpegvideo.h Sun Dec 07 01:33:45 2003 +0000 @@ -523,17 +523,17 @@ ParseContext parse_context; /* H.263 specific */ - int gob_number; int gob_index; int obmc; ///< overlapped block motion compensation /* H.263+ specific */ int umvplus; ///< == H263+ && unrestricted_mv int h263_aic; ///< Advanded INTRA Coding (AIC) - int h263_aic_dir; ///< AIC direction: 0 = left, 1 = top + int h263_aic_dir; ///< AIC direction: 0 = left, 1 = top + int h263_slice_structured; int alt_inter_vlc; ///< alternative inter vlc int modified_quant; - int loop_filter; + int loop_filter; /* mpeg4 specific */ int time_increment_resolution; @@ -663,12 +663,10 @@ int interlaced_dct; int first_slice; int first_field; ///< is 1 for the first field of a field picture 0 otherwise - + /* RTP specific */ - /* These are explained on avcodec.h */ int rtp_mode; - int rtp_payload_size; - void (*rtp_callback)(void *data, int size, int packet_number); + uint8_t *ptr_lastgob; int swap_uv;//vcr2 codec is mpeg2 varint with UV swaped short * pblocks[12]; @@ -825,8 +823,6 @@ extern uint8_t ff_aic_dc_scale_table[32]; extern const int16_t ff_mpeg4_default_intra_matrix[64]; extern const int16_t ff_mpeg4_default_non_intra_matrix[64]; -extern const uint16_t ff_mba_max[6]; -extern const uint8_t ff_mba_length[6]; extern const uint8_t ff_h263_chroma_qscale_table[32]; extern const uint8_t ff_h263_loop_filter_strength[32]; @@ -844,7 +840,7 @@ int motion_x, int motion_y); void h263_encode_picture_header(MpegEncContext *s, int picture_number); void ff_flv_encode_picture_header(MpegEncContext *s, int picture_number); -int h263_encode_gob_header(MpegEncContext * s, int mb_line); +void h263_encode_gob_header(MpegEncContext * s, int mb_line); int16_t *h263_pred_motion(MpegEncContext * s, int block, int *px, int *py); void mpeg4_pred_ac(MpegEncContext * s, DCTELEM *block, int n, @@ -859,7 +855,8 @@ void ff_h263_update_motion_val(MpegEncContext * s); void ff_h263_loop_filter(MpegEncContext * s); void ff_set_qscale(MpegEncContext * s, int qscale); - +int ff_h263_decode_mba(MpegEncContext *s); +void ff_h263_encode_mba(MpegEncContext *s); int intel_h263_decode_picture_header(MpegEncContext *s); int flv_h263_decode_picture_header(MpegEncContext *s);
--- a/rv10.c Fri Dec 05 23:12:03 2003 +0000 +++ b/rv10.c Sun Dec 07 01:33:45 2003 +0000 @@ -403,13 +403,8 @@ } } // printf("%d %d %d %d %d\n", seq, (int)s->time, (int)s->last_non_b_time, s->pp_time, s->pb_time); - - for(i=0; i<6; i++){ - if(s->mb_width*s->mb_height < ff_mba_max[i]) break; - } - mb_pos= get_bits(&s->gb, ff_mba_length[i]); - s->mb_x= mb_pos % s->mb_width; - s->mb_y= mb_pos / s->mb_width; + + ff_h263_decode_mba(s); s->no_rounding= get_bits1(&s->gb); s->f_code = 1;