summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2008-06-08 21:33:21 +0000
committerjstebbins <[email protected]>2008-06-08 21:33:21 +0000
commit2861d8a12526539b5e3b372168fe9dfaaefbe0db (patch)
tree43c12e9bca07183c63a871ae67736ab62e177a26
parenteae2b0f3e10c035140077ed4d23c3059d99f6e24 (diff)
Improve image quality for ffmpeg constant quality
Allow entry of QP for ffmpeg git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@1503 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--libhb/encavcodec.c27
-rw-r--r--test/test.c2
2 files changed, 24 insertions, 5 deletions
diff --git a/libhb/encavcodec.c b/libhb/encavcodec.c
index 5e55b0083..2d3f33418 100644
--- a/libhb/encavcodec.c
+++ b/libhb/encavcodec.c
@@ -45,7 +45,7 @@ int encavcodecInit( hb_work_object_t * w, hb_job_t * job )
"failed" );
}
context = avcodec_alloc_context();
- if( job->vquality < 0.0 || job->vquality > 1.0 )
+ if( job->vquality < 0.0 )
{
/* Rate control */
context->bit_rate = 1000 * job->vbitrate;
@@ -54,10 +54,26 @@ int encavcodecInit( hb_work_object_t * w, hb_job_t * job )
else
{
/* Constant quantizer */
- context->qmin = 31 - job->vquality * 30;
- context->qmax = context->qmin;
+ // These settings produce better image quality than
+ // what was previously used
+ context->flags |= CODEC_FLAG_QSCALE;
+ if (job->vquality < 1.0)
+ {
+ float vquality;
+ vquality = 31 - job->vquality * 31;
+ // A value of 0 has undefined behavior
+ // and ffmpeg qp has integral increments
+ if (vquality < 1.0)
+ vquality = 1.0;
+ context->global_quality = FF_QP2LAMBDA * vquality + 0.5;
+ }
+ else
+ {
+ context->global_quality = FF_QP2LAMBDA * job->vquality + 0.5;
+ }
+ context->mb_decision = 1;
hb_log( "encavcodec: encoding at constant quantizer %d",
- context->qmin );
+ context->global_quality );
}
context->width = job->width;
context->height = job->height;
@@ -188,6 +204,9 @@ int encavcodecWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
frame->linesize[0] = job->width;
frame->linesize[1] = job->width / 2;
frame->linesize[2] = job->width / 2;
+ // For constant quality, setting the quality in AVCodecContext
+ // doesn't do the trick. It must be set in the AVFrame.
+ frame->quality = pv->context->global_quality;
/* Should be way too large */
buf = hb_buffer_init( 3 * job->width * job->height / 2 );
diff --git a/test/test.c b/test/test.c
index 2c91287a6..81b6486a6 100644
--- a/test/test.c
+++ b/test/test.c
@@ -861,7 +861,7 @@ static int HandleEvents( hb_handle_t * h )
hb_fix_aspect( job, HB_KEEP_WIDTH );
}
- if( vquality >= 0.0 && ( ( vquality <= 1.0 ) || ( vcodec == HB_VCODEC_X264 ) ) )
+ if( vquality >= 0.0 && ( ( vquality <= 1.0 ) || ( vcodec == HB_VCODEC_X264 ) || (vcodec == HB_VCODEC_FFMPEG) ) )
{
job->vquality = vquality;
job->vbitrate = 0;