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:
parent
cc15c93127
commit
dba019daba
5
ffmpeg.c
5
ffmpeg.c
@ -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" },
|
||||||
|
@ -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 */
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user