summaryrefslogtreecommitdiffstats
path: root/libhb/scan.c
diff options
context:
space:
mode:
authorvan <[email protected]>2008-06-23 06:18:33 +0000
committervan <[email protected]>2008-06-23 06:18:33 +0000
commit638c308e3eb9a80586885e81ce306aaf7b0b61bc (patch)
tree8bac92546660d9c4bc27f6165a3178dad5db21f7 /libhb/scan.c
parent5bf415fc8aa22376f5f81cf2b9c315bc4751adfe (diff)
Don't let cropping get fooled by dark content - make sure that we only crop a row or column if all pixels are within one quantization level of average value & average value is within one level of black. (fix for bug discussed in http://forum.handbrake.fr/viewtopic.php?f=12&t=6335)
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@1532 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'libhb/scan.c')
-rw-r--r--libhb/scan.c72
1 files changed, 56 insertions, 16 deletions
diff --git a/libhb/scan.c b/libhb/scan.c
index f7ded0524..960332dfc 100644
--- a/libhb/scan.c
+++ b/libhb/scan.c
@@ -252,15 +252,40 @@ static void ScanFunc( void * _data )
// -----------------------------------------------
// stuff related to cropping
-#define DARK 64
+#define DARK 32
+
+static inline int absdiff( int x, int y )
+{
+ return x < y ? y - x : x - y;
+}
+
+static inline int clampBlack( int x )
+{
+ // luma 'black' is 16 and anything less should be clamped at 16
+ return x < 16 ? 16 : x;
+}
static int row_all_dark( hb_title_t *title, uint8_t* luma, int row )
{
- int i = title->width;
- luma += i * row;
- while ( --i >= 0 )
+ luma += title->width * row;
+
+ // compute the average luma value of the row
+ int i, avg = 0;
+ for ( i = 0; i < title->width; ++i )
{
- if ( *luma++ > DARK )
+ avg += clampBlack( luma[i] );
+ }
+ avg /= title->width;
+ if ( avg >= DARK )
+ return 0;
+
+ // since we're trying to detect smooth borders, only take the row if
+ // all pixels are within +-16 of the average (this range is fairly coarse
+ // but there's a lot of quantization noise for luma values near black
+ // so anything less will fail to crop because of the noise).
+ for ( i = 0; i < title->width; ++i )
+ {
+ if ( absdiff( avg, clampBlack( luma[i] ) ) > 16 )
return 0;
}
return 1;
@@ -268,12 +293,25 @@ static int row_all_dark( hb_title_t *title, uint8_t* luma, int row )
static int column_all_dark( hb_title_t *title, uint8_t* luma, int top, int col )
{
- int i = title->height - top;
int stride = title->width;
luma += stride * top + col;
- for ( ; --i >= 0; luma += stride )
+
+ // compute the average value of the column
+ int i = title->height - top, avg = 0, row = 0;
+ for ( ; --i >= 0; row += stride )
{
- if ( *luma > DARK )
+ avg += clampBlack( luma[row] );
+ }
+ avg /= title->height - top;
+ if ( avg >= DARK )
+ return 0;
+
+ // since we're trying to detect smooth borders, only take the column if
+ // all pixels are within +-16 of the average.
+ i = title->height - top, row = 0;
+ for ( ; --i >= 0; row += stride )
+ {
+ if ( absdiff( avg, clampBlack( luma[row] ) ) > 16 )
return 0;
}
return 1;
@@ -543,21 +581,22 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title )
#define Y vid_buf->data
int top, bottom, left, right;
int h4 = title->height / 4, w4 = title->width / 4;
- for ( top = 2; top < h4; ++top )
+ for ( top = 4; top < h4; ++top )
{
if ( ! row_all_dark( title, Y, top ) )
break;
}
- if ( top < 4 )
+ if ( top < 5 )
{
- // we started at row two to avoid the "line 19" noise that shows
+ // we started at row 4 to avoid the "line 21" noise that shows
// up on row 0 & 1 of some TV shows. Since we stopped before row 4
- // check if row 0 & 1 are dark or if we shouldn't crop the top at all.
- if ( row_all_dark( title, Y, 0 ) )
+ // check if the missed rows are dark or if we shouldn't crop at all.
+ for ( top = 0; top < 4; ++top )
{
- top = row_all_dark( title, Y, 1 )? top : 1;
+ if ( ! row_all_dark( title, Y, top ) )
+ break;
}
- else
+ if ( top >= 4 )
{
top = 0;
}
@@ -616,7 +655,8 @@ skip_preview:
}
title->aspect = ( aspect + 0.05 ) * HB_ASPECT_BASE;
- if ( crops->n )
+ // don't try to crop unless we got at least 3 previews
+ if ( crops->n > 2 )
{
sort_crops( crops );
// The next line selects median cropping - at least