From d6eb3c500aeab8ae9f138f8eb70d045ac47100ee Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 22 Aug 2003 22:18:08 +0000 Subject: [PATCH] custom quant matrix encoding support Originally committed as revision 2135 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavcodec/avcodec.h | 18 ++++++++++++++++-- libavcodec/h263.c | 20 ++++++++++++++------ libavcodec/mpeg12.c | 5 +++-- libavcodec/mpegvideo.c | 16 ++++++++++++++++ libavcodec/mpegvideo.h | 1 + 5 files changed, 50 insertions(+), 10 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index f049cb1931..61fc553a94 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -15,8 +15,8 @@ extern "C" { #define LIBAVCODEC_VERSION_INT 0x000406 #define LIBAVCODEC_VERSION "0.4.6" -#define LIBAVCODEC_BUILD 4674 -#define LIBAVCODEC_BUILD_STR "4674" +#define LIBAVCODEC_BUILD 4675 +#define LIBAVCODEC_BUILD_STR "4675" #define LIBAVCODEC_IDENT "FFmpeg" LIBAVCODEC_VERSION "b" LIBAVCODEC_BUILD_STR @@ -1186,6 +1186,20 @@ typedef struct AVCodecContext { #define FF_MB_DECISION_SIMPLE 0 ///< uses mb_cmp #define FF_MB_DECISION_BITS 1 ///< chooses the one which needs the fewest bits #define FF_MB_DECISION_RD 2 ///< rate distoration + + /** + * custom intra quantization matrix + * - encoding: set by user, can be NULL + * - decoding: set by lavc + */ + uint16_t *intra_matrix; + + /** + * custom inter quantization matrix + * - encoding: set by user, can be NULL + * - decoding: set by lavc + */ + uint16_t *inter_matrix; } AVCodecContext; diff --git a/libavcodec/h263.c b/libavcodec/h263.c index ec30214031..592e92c7b1 100644 --- a/libavcodec/h263.c +++ b/libavcodec/h263.c @@ -1859,7 +1859,11 @@ static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_n s->quant_precision=5; put_bits(&s->pb, 1, 0); /* not 8 bit == false */ put_bits(&s->pb, 1, s->mpeg_quant); /* quant type= (0=h263 style)*/ - if(s->mpeg_quant) put_bits(&s->pb, 2, 0); /* no custom matrixes */ + + if(s->mpeg_quant){ + ff_write_quant_matrix(&s->pb, s->avctx->intra_matrix); + ff_write_quant_matrix(&s->pb, s->avctx->inter_matrix); + } if (vo_ver_id != 1) put_bits(&s->pb, 1, s->quarter_sample); @@ -4551,14 +4555,15 @@ static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){ skip_bits(gb, 4); //video_object_layer_shape_extension } - skip_bits1(gb); /* marker */ + check_marker(gb, "before time_increment_resolution"); s->time_increment_resolution = get_bits(gb, 16); s->time_increment_bits = av_log2(s->time_increment_resolution - 1) + 1; if (s->time_increment_bits < 1) s->time_increment_bits = 1; - skip_bits1(gb); /* marker */ + + check_marker(gb, "before fixed_vop_rate"); if (get_bits1(gb) != 0) { /* fixed_vop_rate */ skip_bits(gb, s->time_increment_bits); @@ -4648,8 +4653,8 @@ static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){ /* replicate last value */ for(; i<64; i++){ int j= s->dsp.idct_permutation[ ff_zigzag_direct[i] ]; - s->intra_matrix[j]= v; - s->chroma_intra_matrix[j]= v; + s->intra_matrix[j]= last; + s->chroma_intra_matrix[j]= last; } } @@ -4842,7 +4847,10 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ printf("my guess is %d bits ;)\n",s->time_increment_bits); } - time_increment= get_bits(gb, s->time_increment_bits); + if(IS_3IV1) time_increment= get_bits1(gb); //FIXME investigate further + else time_increment= get_bits(gb, s->time_increment_bits); + +// printf("%d %X\n", s->time_increment_bits, time_increment); //printf(" type:%d modulo_time_base:%d increment:%d\n", s->pict_type, time_incr, time_increment); if(s->pict_type!=B_TYPE){ s->last_time_base= s->time_base; diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index 438e709799..41c96ec474 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -240,8 +240,9 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s) vbv_buffer_size = (( 20 * s->bit_rate) / (1151929 / 2)) * 8 * 1024; put_bits(&s->pb, 10, (vbv_buffer_size + 16383) / 16384); put_bits(&s->pb, 1, 1); /* constrained parameter flag */ - put_bits(&s->pb, 1, 0); /* no custom intra matrix */ - put_bits(&s->pb, 1, 0); /* no custom non intra matrix */ + + ff_write_quant_matrix(&s->pb, s->avctx->intra_matrix); + ff_write_quant_matrix(&s->pb, s->avctx->inter_matrix); put_header(s, GOP_START_CODE); put_bits(&s->pb, 1, 0); /* do drop frame */ diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index b84875f43e..f9d994509a 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -167,6 +167,18 @@ void ff_init_scantable(uint8_t *permutation, ScanTable *st, const uint8_t *src_s } } +void ff_write_quant_matrix(PutBitContext *pb, int16_t *matrix){ + int i; + + if(matrix){ + put_bits(pb, 1, 1); + for(i=0;i<64;i++) { + put_bits(pb, 8, matrix[ ff_zigzag_direct[i] ]); + } + }else + put_bits(pb, 1, 0); +} + /* init common dct for both encoder and decoder */ int DCT_common_init(MpegEncContext *s) { @@ -812,6 +824,10 @@ int MPV_encode_init(AVCodecContext *avctx) s->intra_matrix[j] = ff_mpeg1_default_intra_matrix[i]; s->inter_matrix[j] = ff_mpeg1_default_non_intra_matrix[i]; } + if(s->avctx->intra_matrix) + s->intra_matrix[j] = s->avctx->intra_matrix[i]; + if(s->avctx->inter_matrix) + s->inter_matrix[j] = s->avctx->inter_matrix[i]; } /* precompute matrix */ diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index 23b93b7905..a80431520d 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -716,6 +716,7 @@ void ff_emulated_edge_mc(uint8_t *buf, uint8_t *src, int linesize, int block_w, int ff_combine_frame( MpegEncContext *s, int next, uint8_t **buf, int *buf_size); void ff_mpeg_flush(AVCodecContext *avctx); void ff_print_debug_info(MpegEncContext *s, Picture *pict); +void ff_write_quant_matrix(PutBitContext *pb, int16_t *matrix); void ff_er_frame_start(MpegEncContext *s); void ff_er_frame_end(MpegEncContext *s);