1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-23 12:43:46 +02:00

h263 alternative inter vlc support

Originally committed as revision 2541 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Michael Niedermayer 2003-11-29 08:37:51 +00:00
parent cc15c93127
commit dba019daba
5 changed files with 69 additions and 13 deletions

View File

@ -113,6 +113,7 @@ static int b_frames = 0;
static int mb_decision = FF_MB_DECISION_SIMPLE; static int mb_decision = FF_MB_DECISION_SIMPLE;
static int use_4mv = 0; static int use_4mv = 0;
static int use_aic = 0; static int use_aic = 0;
static int use_aiv = 0;
static int use_umv = 0; static int use_umv = 0;
static int do_deinterlace = 0; static int do_deinterlace = 0;
static int workaround_bugs = FF_BUG_AUTODETECT; static int workaround_bugs = FF_BUG_AUTODETECT;
@ -2267,6 +2268,9 @@ static void opt_output_file(const char *filename)
if (use_aic) { if (use_aic) {
video_enc->flags |= CODEC_FLAG_H263P_AIC; video_enc->flags |= CODEC_FLAG_H263P_AIC;
} }
if (use_aiv) {
video_enc->flags |= CODEC_FLAG_H263P_AIV;
}
if (use_4mv) { if (use_4mv) {
video_enc->flags |= CODEC_FLAG_4MV; video_enc->flags |= CODEC_FLAG_4MV;
} }
@ -2886,6 +2890,7 @@ const OptionDef options[] = {
{ "vstats", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&do_vstats}, "dump video coding statistics to file" }, { "vstats", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&do_vstats}, "dump video coding statistics to file" },
{ "vhook", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)add_frame_hooker}, "insert video processing module", "module" }, { "vhook", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)add_frame_hooker}, "insert video processing module", "module" },
{ "aic", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&use_aic}, "enable Advanced intra coding (h263+)" }, { "aic", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&use_aic}, "enable Advanced intra coding (h263+)" },
{ "aiv", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&use_aiv}, "enable Alternative inter vlc (h263+)" },
{ "umv", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&use_umv}, "enable Unlimited Motion Vector (h263+)" }, { "umv", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&use_umv}, "enable Unlimited Motion Vector (h263+)" },
{ "intra_matrix", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_intra_matrix}, "specify intra matrix coeffs", "matrix" }, { "intra_matrix", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_intra_matrix}, "specify intra matrix coeffs", "matrix" },
{ "inter_matrix", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_inter_matrix}, "specify inter matrix coeffs", "matrix" }, { "inter_matrix", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_inter_matrix}, "specify inter matrix coeffs", "matrix" },

View File

@ -229,7 +229,7 @@ static const __attribute__((unused)) int Motion_Est_QTab[] =
*/ */
#define CODEC_FLAG_QSCALE 0x0002 ///< use fixed qscale #define CODEC_FLAG_QSCALE 0x0002 ///< use fixed qscale
#define CODEC_FLAG_4MV 0x0004 ///< 4 MV per MB allowed #define CODEC_FLAG_4MV 0x0004 ///< 4 MV per MB allowed / Advanced prediction for H263
#define CODEC_FLAG_QPEL 0x0010 ///< use qpel MC #define CODEC_FLAG_QPEL 0x0010 ///< use qpel MC
#define CODEC_FLAG_GMC 0x0020 ///< use GMC #define CODEC_FLAG_GMC 0x0020 ///< use GMC
#define CODEC_FLAG_MV0 0x0040 ///< always try a MB with MV=<0,0> #define CODEC_FLAG_MV0 0x0040 ///< always try a MB with MV=<0,0>
@ -258,6 +258,7 @@ static const __attribute__((unused)) int Motion_Est_QTab[] =
#define CODEC_FLAG_H263P_UMV 0x02000000 ///< Unlimited motion vector #define CODEC_FLAG_H263P_UMV 0x02000000 ///< Unlimited motion vector
#define CODEC_FLAG_CBP_RD 0x04000000 ///< use rate distortion optimization for cbp #define CODEC_FLAG_CBP_RD 0x04000000 ///< use rate distortion optimization for cbp
#define CODEC_FLAG_QP_RD 0x08000000 ///< use rate distortion optimization for qp selectioon #define CODEC_FLAG_QP_RD 0x08000000 ///< use rate distortion optimization for qp selectioon
#define CODEC_FLAG_H263P_AIV 0x00000008 ///< H263 Alternative inter vlc
/* For advanced prediction mode, we reuse the 4MV flag */ /* For advanced prediction mode, we reuse the 4MV flag */
/* Unsupported options : /* Unsupported options :
* Syntax Arithmetic coding (SAC) * Syntax Arithmetic coding (SAC)
@ -265,7 +266,6 @@ static const __attribute__((unused)) int Motion_Est_QTab[] =
* Slice structured * Slice structured
* Reference Picture Selection * Reference Picture Selection
* Independant Segment Decoding * Independant Segment Decoding
* Alternative Inter * VLC
* Modified Quantization */ * Modified Quantization */
/* /Fx */ /* /Fx */
/* codec capabilities */ /* codec capabilities */

View File

@ -246,7 +246,7 @@ void h263_encode_picture_header(MpegEncContext * s, int picture_number)
put_bits(&s->pb,1,0); /* Slice Structured: off */ put_bits(&s->pb,1,0); /* Slice Structured: off */
put_bits(&s->pb,1,0); /* Reference Picture Selection: off */ 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,0); /* Independent Segment Decoding: off */
put_bits(&s->pb,1,0); /* Alternative Inter VLC: off */ put_bits(&s->pb,1,s->alt_inter_vlc); /* Alternative Inter VLC */
put_bits(&s->pb,1,0); /* Modified Quantization: off */ put_bits(&s->pb,1,0); /* Modified Quantization: off */
put_bits(&s->pb,1,1); /* "1" to prevent start code emulation */ put_bits(&s->pb,1,1); /* "1" to prevent start code emulation */
put_bits(&s->pb,3,0); /* Reserved */ put_bits(&s->pb,3,0); /* Reserved */
@ -1071,9 +1071,10 @@ void h263_encode_mb(MpegEncContext * s,
put_bits(&s->pb, 1, 0); /* mb coded */ put_bits(&s->pb, 1, 0); /* mb coded */
cbpc = cbp & 3; cbpc = cbp & 3;
if(s->dquant) cbpc+= 8;
cbpy = cbp >> 2; cbpy = cbp >> 2;
cbpy ^= 0xf; if(s->alt_inter_vlc==0 || cbpc!=3)
cbpy ^= 0xF;
if(s->dquant) cbpc+= 8;
if(s->mv_type==MV_TYPE_16X16){ if(s->mv_type==MV_TYPE_16X16){
put_bits(&s->pb, put_bits(&s->pb,
inter_MCBPC_bits[cbpc], inter_MCBPC_bits[cbpc],
@ -1804,6 +1805,42 @@ static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n)
i = 0; i = 0;
if (s->h263_aic && s->mb_intra) if (s->h263_aic && s->mb_intra)
rl = &rl_intra_aic; rl = &rl_intra_aic;
if(s->alt_inter_vlc && !s->mb_intra){
int aic_vlc_bits=0;
int inter_vlc_bits=0;
int wrong_pos=-1;
int aic_code;
last_index = s->block_last_index[n];
last_non_zero = i - 1;
for (; i <= last_index; i++) {
j = s->intra_scantable.permutated[i];
level = block[j];
if (level) {
run = i - last_non_zero - 1;
last = (i == last_index);
code = get_rl_index(rl, last, run, level);
aic_code = get_rl_index(&rl_intra_aic, last, run, level);
inter_vlc_bits += rl->table_vlc[code][1]+1;
aic_vlc_bits += rl_intra_aic.table_vlc[aic_code][1]+1;
if (code == rl->n) {
inter_vlc_bits += 1+6+8;
}
if (aic_code == rl_intra_aic.n) {
aic_vlc_bits += 1+6+8;
wrong_pos += run + 1;
}else
wrong_pos += wrong_run[aic_code];
last_non_zero = i;
}
}
i = 0;
if(aic_vlc_bits < inter_vlc_bits && wrong_pos > 63)
rl = &rl_intra_aic;
}
} }
/* AC coefs */ /* AC coefs */
@ -3474,7 +3511,11 @@ int ff_h263_decode_mb(MpegEncContext *s,
s->mcsel= get_bits1(&s->gb); s->mcsel= get_bits1(&s->gb);
else s->mcsel= 0; else s->mcsel= 0;
cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1); cbpy = get_vlc2(&s->gb, cbpy_vlc.table, CBPY_VLC_BITS, 1);
cbp = (cbpc & 3) | ((cbpy ^ 0xf) << 2);
if(s->alt_inter_vlc==0 || (cbpc & 3)!=3)
cbpy ^= 0xF;
cbp = (cbpc & 3) | (cbpy << 2);
if (dquant) { if (dquant) {
change_qscale(s, quant_tab[get_bits(&s->gb, 2)]); change_qscale(s, quant_tab[get_bits(&s->gb, 2)]);
} }
@ -3865,6 +3906,7 @@ static int h263_decode_block(MpegEncContext * s, DCTELEM * block,
int code, level, i, j, last, run; int code, level, i, j, last, run;
RLTable *rl = &rl_inter; RLTable *rl = &rl_inter;
const uint8_t *scan_table; const uint8_t *scan_table;
GetBitContext gb= s->gb;
scan_table = s->intra_scantable.permutated; scan_table = s->intra_scantable.permutated;
if (s->h263_aic && s->mb_intra) { if (s->h263_aic && s->mb_intra) {
@ -3916,7 +3958,7 @@ static int h263_decode_block(MpegEncContext * s, DCTELEM * block,
s->block_last_index[n] = i - 1; s->block_last_index[n] = i - 1;
return 0; return 0;
} }
retry:
for(;;) { for(;;) {
code = get_vlc2(&s->gb, rl->vlc.table, TEX_VLC_BITS, 2); code = get_vlc2(&s->gb, rl->vlc.table, TEX_VLC_BITS, 2);
if (code < 0){ if (code < 0){
@ -3957,6 +3999,14 @@ static int h263_decode_block(MpegEncContext * s, DCTELEM * block,
} }
i += run; i += run;
if (i >= 64){ if (i >= 64){
if(s->alt_inter_vlc && rl == &rl_inter && !s->mb_intra){
//looks like a hack but no, its the way its supposed to work ...
rl = &rl_intra_aic;
i = 0;
s->gb= gb;
memset(block, 0, sizeof(DCTELEM)*64);
goto retry;
}
av_log(s->avctx, AV_LOG_ERROR, "run overflow at %dx%d\n", s->mb_x, s->mb_y); av_log(s->avctx, AV_LOG_ERROR, "run overflow at %dx%d\n", s->mb_x, s->mb_y);
return -1; return -1;
} }
@ -4408,9 +4458,7 @@ int h263_decode_picture_header(MpegEncContext *s)
if (get_bits1(&s->gb) != 0) { if (get_bits1(&s->gb) != 0) {
av_log(s->avctx, AV_LOG_ERROR, "Independent Segment Decoding not supported\n"); av_log(s->avctx, AV_LOG_ERROR, "Independent Segment Decoding not supported\n");
} }
if (get_bits1(&s->gb) != 0) { s->alt_inter_vlc= get_bits1(&s->gb);
av_log(s->avctx, AV_LOG_ERROR, "Alternative Inter VLC not supported\n");
}
if (get_bits1(&s->gb) != 0) { if (get_bits1(&s->gb) != 0) {
av_log(s->avctx, AV_LOG_ERROR, "Modified Quantization not supported\n"); av_log(s->avctx, AV_LOG_ERROR, "Modified Quantization not supported\n");
} }
@ -4491,14 +4539,15 @@ int h263_decode_picture_header(MpegEncContext *s)
} }
if(s->avctx->debug&FF_DEBUG_PICT_INFO){ 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\n", av_log(s->avctx, AV_LOG_DEBUG, "qp:%d %c size:%d rnd:%d%s%s%s%s%s%s\n",
s->qscale, av_get_pict_type_char(s->pict_type), s->qscale, av_get_pict_type_char(s->pict_type),
s->gb.size_in_bits, 1-s->no_rounding, s->gb.size_in_bits, 1-s->no_rounding,
s->obmc ? " AP" : "", s->obmc ? " AP" : "",
s->umvplus ? " UMV" : "", s->umvplus ? " UMV" : "",
s->h263_long_vectors ? " LONG" : "", s->h263_long_vectors ? " LONG" : "",
s->h263_plus ? " +" : "", s->h263_plus ? " +" : "",
s->h263_aic ? " AIC" : "" s->h263_aic ? " AIC" : "",
s->alt_inter_vlc ? " AIV" : ""
); );
} }
#if 1 #if 1

View File

@ -779,6 +779,7 @@ int MPV_encode_init(AVCodecContext *avctx)
/* Fx */ /* Fx */
s->unrestricted_mv=(avctx->flags & CODEC_FLAG_H263P_UMV) ? 1:0; s->unrestricted_mv=(avctx->flags & CODEC_FLAG_H263P_UMV) ? 1:0;
s->h263_aic= (avctx->flags & CODEC_FLAG_H263P_AIC) ? 1:0; s->h263_aic= (avctx->flags & CODEC_FLAG_H263P_AIC) ? 1:0;
s->alt_inter_vlc= (avctx->flags & CODEC_FLAG_H263P_AIV) ? 1:0;
/* /Fx */ /* /Fx */
/* These are just to be sure */ /* These are just to be sure */
s->umvplus = 1; s->umvplus = 1;

View File

@ -519,12 +519,13 @@ typedef struct MpegEncContext {
/* H.263 specific */ /* H.263 specific */
int gob_number; int gob_number;
int gob_index; int gob_index;
int obmc; ///< overlapped block motion compensation
/* H.263+ specific */ /* H.263+ specific */
int umvplus; ///< == H263+ && unrestricted_mv int umvplus; ///< == H263+ && unrestricted_mv
int h263_aic; ///< Advanded INTRA Coding (AIC) 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 obmc; ///< overlapped block motion compensation int alt_inter_vlc; ///< alternative inter vlc
/* mpeg4 specific */ /* mpeg4 specific */
int time_increment_resolution; int time_increment_resolution;