Commit 58fe57d5 authored by Michael Niedermayer's avatar Michael Niedermayer

avcodec/mpeg12enc: Basic support for encoding non even QPs for -non_linear_quant 1

Signed-off-by: 's avatarMichael Niedermayer <michael@niedermayer.cc>
parent bf946402
......@@ -42,12 +42,6 @@
#include "mpegutils.h"
#include "mpegvideo.h"
static const int8_t inv_non_linear_qscale[] = {
0, 2, 4, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16,
-1,17,-1,18,-1,19, -1, 20, -1, 21, -1, 22, -1,
23,-1,24,-1,-1,-1
};
static const uint8_t svcd_scan_offset_placeholder[] = {
0x10, 0x0E, 0x00, 0x80, 0x81, 0x00, 0x80,
0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
......@@ -402,13 +396,7 @@ static inline void encode_mb_skip_run(MpegEncContext *s, int run)
static av_always_inline void put_qscale(MpegEncContext *s)
{
if (s->q_scale_type) {
int qp = inv_non_linear_qscale[s->qscale];
av_assert2(s->qscale >= 1 && qp > 0);
put_bits(&s->pb, 5, qp);
} else {
put_bits(&s->pb, 5, s->qscale);
}
put_bits(&s->pb, 5, s->qscale);
}
void ff_mpeg1_encode_slice_header(MpegEncContext *s)
......
......@@ -114,7 +114,8 @@ static void dct_unquantize_mpeg2_intra_c(MpegEncContext *s,
int i, level, nCoeffs;
const uint16_t *quant_matrix;
qscale <<= 1;
if (s->q_scale_type) qscale = ff_mpeg2_non_linear_qscale[qscale];
else qscale <<= 1;
if(s->alternate_scan) nCoeffs= 63;
else nCoeffs= s->block_last_index[n];
......@@ -144,7 +145,8 @@ static void dct_unquantize_mpeg2_intra_bitexact(MpegEncContext *s,
const uint16_t *quant_matrix;
int sum=-1;
qscale <<= 1;
if (s->q_scale_type) qscale = ff_mpeg2_non_linear_qscale[qscale];
else qscale <<= 1;
if(s->alternate_scan) nCoeffs= 63;
else nCoeffs= s->block_last_index[n];
......@@ -177,7 +179,8 @@ static void dct_unquantize_mpeg2_inter_c(MpegEncContext *s,
const uint16_t *quant_matrix;
int sum=-1;
qscale <<= 1;
if (s->q_scale_type) qscale = ff_mpeg2_non_linear_qscale[qscale];
else qscale <<= 1;
if(s->alternate_scan) nCoeffs= 63;
else nCoeffs= s->block_last_index[n];
......
......@@ -97,6 +97,11 @@ void ff_convert_matrix(MpegEncContext *s, int (*qmat)[64],
for (qscale = qmin; qscale <= qmax; qscale++) {
int i;
int qscale2;
if (s->q_scale_type) qscale2 = ff_mpeg2_non_linear_qscale[qscale];
else qscale2 = qscale << 1;
if (fdsp->fdct == ff_jpeg_fdct_islow_8 ||
#if CONFIG_FAANDCT
fdsp->fdct == ff_faandct ||
......@@ -104,40 +109,40 @@ void ff_convert_matrix(MpegEncContext *s, int (*qmat)[64],
fdsp->fdct == ff_jpeg_fdct_islow_10) {
for (i = 0; i < 64; i++) {
const int j = s->idsp.idct_permutation[i];
int64_t den = (int64_t) qscale * quant_matrix[j];
int64_t den = (int64_t) qscale2 * quant_matrix[j];
/* 16 <= qscale * quant_matrix[i] <= 7905
* Assume x = ff_aanscales[i] * qscale * quant_matrix[i]
* 19952 <= x <= 249205026
* (1 << 36) / 19952 >= (1 << 36) / (x) >= (1 << 36) / 249205026
* 3444240 >= (1 << 36) / (x) >= 275 */
qmat[qscale][i] = (int)((UINT64_C(1) << QMAT_SHIFT) / den);
qmat[qscale][i] = (int)((UINT64_C(2) << QMAT_SHIFT) / den);
}
} else if (fdsp->fdct == ff_fdct_ifast) {
for (i = 0; i < 64; i++) {
const int j = s->idsp.idct_permutation[i];
int64_t den = ff_aanscales[i] * (int64_t) qscale * quant_matrix[j];
int64_t den = ff_aanscales[i] * (int64_t) qscale2 * quant_matrix[j];
/* 16 <= qscale * quant_matrix[i] <= 7905
* Assume x = ff_aanscales[i] * qscale * quant_matrix[i]
* 19952 <= x <= 249205026
* (1 << 36) / 19952 >= (1 << 36) / (x) >= (1 << 36) / 249205026
* 3444240 >= (1 << 36) / (x) >= 275 */
qmat[qscale][i] = (int)((UINT64_C(1) << (QMAT_SHIFT + 14)) / den);
qmat[qscale][i] = (int)((UINT64_C(2) << (QMAT_SHIFT + 14)) / den);
}
} else {
for (i = 0; i < 64; i++) {
const int j = s->idsp.idct_permutation[i];
int64_t den = (int64_t) qscale * quant_matrix[j];
int64_t den = (int64_t) qscale2 * quant_matrix[j];
/* We can safely suppose that 16 <= quant_matrix[i] <= 255
* Assume x = qscale * quant_matrix[i]
* So 16 <= x <= 7905
* so (1 << 19) / 16 >= (1 << 19) / (x) >= (1 << 19) / 7905
* so 32768 >= (1 << 19) / (x) >= 67 */
qmat[qscale][i] = (int)((UINT64_C(1) << QMAT_SHIFT) / den);
qmat[qscale][i] = (int)((UINT64_C(2) << QMAT_SHIFT) / den);
//qmat [qscale][i] = (1 << QMAT_SHIFT_MMX) /
// (qscale * quant_matrix[i]);
qmat16[qscale][0][i] = (1 << QMAT_SHIFT_MMX) / den;
qmat16[qscale][0][i] = (2 << QMAT_SHIFT_MMX) / den;
if (qmat16[qscale][0][i] == 0 ||
qmat16[qscale][0][i] == 128 * 256)
......@@ -167,22 +172,19 @@ void ff_convert_matrix(MpegEncContext *s, int (*qmat)[64],
static inline void update_qscale(MpegEncContext *s)
{
if (s->q_scale_type == 1) {
if (s->q_scale_type == 1 && 0) {
int i;
int bestdiff=INT_MAX;
int best = 1;
static const uint8_t non_linear_qscale[] = {
1,2,3,4,5,6,7,8,9,10,11,12,14,16,18,20,22,24,26,28
};
for (i = 0 ; i<FF_ARRAY_ELEMS(non_linear_qscale); i++) {
int diff = FFABS((non_linear_qscale[i]<<(FF_LAMBDA_SHIFT + 7)) - (int)s->lambda * 139);
if (non_linear_qscale[i] < s->avctx->qmin ||
(non_linear_qscale[i] > s->avctx->qmax && !s->vbv_ignore_qmax))
for (i = 0 ; i<FF_ARRAY_ELEMS(ff_mpeg2_non_linear_qscale); i++) {
int diff = FFABS((ff_mpeg2_non_linear_qscale[i]<<(FF_LAMBDA_SHIFT + 6)) - (int)s->lambda * 139);
if (ff_mpeg2_non_linear_qscale[i] < s->avctx->qmin ||
(ff_mpeg2_non_linear_qscale[i] > s->avctx->qmax && !s->vbv_ignore_qmax))
continue;
if (diff < bestdiff) {
bestdiff = diff;
best = non_linear_qscale[i];
best = i;
}
}
s->qscale = best;
......@@ -3854,6 +3856,7 @@ static int dct_quantize_trellis_c(MpegEncContext *s,
uint8_t * length;
uint8_t * last_length;
const int lambda= s->lambda2 >> (FF_LAMBDA_SHIFT - 6);
int mpeg2_qscale;
s->fdsp.fdct(block);
......@@ -3862,6 +3865,9 @@ static int dct_quantize_trellis_c(MpegEncContext *s,
qmul= qscale*16;
qadd= ((qscale-1)|1)*8;
if (s->q_scale_type) mpeg2_qscale = ff_mpeg2_non_linear_qscale[qscale];
else mpeg2_qscale = qscale << 1;
if (s->mb_intra) {
int q;
if (!s->h263_aic) {
......@@ -3978,10 +3984,10 @@ static int dct_quantize_trellis_c(MpegEncContext *s,
}else{ //MPEG1
j = s->idsp.idct_permutation[scantable[i]]; // FIXME: optimize
if(s->mb_intra){
unquant_coeff = (int)( alevel * qscale * matrix[j]) >> 3;
unquant_coeff = (int)( alevel * mpeg2_qscale * matrix[j]) >> 4;
unquant_coeff = (unquant_coeff - 1) | 1;
}else{
unquant_coeff = ((( alevel << 1) + 1) * qscale * ((int) matrix[j])) >> 4;
unquant_coeff = ((( alevel << 1) + 1) * mpeg2_qscale * ((int) matrix[j])) >> 5;
unquant_coeff = (unquant_coeff - 1) | 1;
}
unquant_coeff<<= 3;
......@@ -4097,7 +4103,7 @@ static int dct_quantize_trellis_c(MpegEncContext *s,
if(s->out_format == FMT_H263 || s->out_format == FMT_H261){
unquant_coeff= (alevel*qmul + qadd)>>3;
}else{ //MPEG1
unquant_coeff = ((( alevel << 1) + 1) * qscale * ((int) matrix[0])) >> 4;
unquant_coeff = ((( alevel << 1) + 1) * mpeg2_qscale * ((int) matrix[0])) >> 5;
unquant_coeff = (unquant_coeff - 1) | 1;
}
unquant_coeff = (unquant_coeff + 4) >> 3;
......
......@@ -25,6 +25,7 @@
#include "libavutil/x86/cpu.h"
#include "libavcodec/avcodec.h"
#include "libavcodec/mpegvideo.h"
#include "libavcodec/mpegvideodata.h"
#if HAVE_MMX_INLINE
......@@ -308,7 +309,8 @@ static void dct_unquantize_mpeg2_intra_mmx(MpegEncContext *s,
av_assert2(s->block_last_index[n]>=0);
qscale <<= 1;
if (s->q_scale_type) qscale = ff_mpeg2_non_linear_qscale[qscale];
else qscale <<= 1;
if(s->alternate_scan) nCoeffs= 63; //FIXME
else nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ];
......@@ -375,7 +377,8 @@ static void dct_unquantize_mpeg2_inter_mmx(MpegEncContext *s,
av_assert2(s->block_last_index[n]>=0);
qscale <<= 1;
if (s->q_scale_type) qscale = ff_mpeg2_non_linear_qscale[qscale];
else qscale <<= 1;
if(s->alternate_scan) nCoeffs= 63; //FIXME
else nCoeffs= s->intra_scantable.raster_end[ s->block_last_index[n] ];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment