diff options
author | jbrjake <[email protected]> | 2008-03-23 19:53:39 +0000 |
---|---|---|
committer | jbrjake <[email protected]> | 2008-03-23 19:53:39 +0000 |
commit | 605848589fbd7397b20aa295277727450d4f364d (patch) | |
tree | e7f01fab10b996cfc22c0ae7661a973bf68c03ba /libhb | |
parent | 64e8482abad07e7d000c7397755d67767c7ea34d (diff) |
= Adds an hb_detect_comb() function that indicates whether or not a frame shows interlacing artifacts.
- Utilitizes that function in scan.c to analyze the preview frames
- Sets a new title->detected_interlacing variable to true if half or more previews show combing, and warns the user in the log.
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@1359 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'libhb')
-rw-r--r-- | libhb/common.h | 1 | ||||
-rw-r--r-- | libhb/hb.c | 106 | ||||
-rw-r--r-- | libhb/hb.h | 5 | ||||
-rw-r--r-- | libhb/scan.c | 25 |
4 files changed, 135 insertions, 2 deletions
diff --git a/libhb/common.h b/libhb/common.h index aa4cfc084..4758d9c8d 100644 --- a/libhb/common.h +++ b/libhb/common.h @@ -427,6 +427,7 @@ struct hb_title_s int rate; int rate_base; int crop[4]; + int detected_interlacing; uint32_t palette[16]; diff --git a/libhb/hb.c b/libhb/hb.c index b2a67119f..fd3cd45ea 100644 --- a/libhb/hb.c +++ b/libhb/hb.c @@ -432,6 +432,112 @@ void hb_get_preview( hb_handle_t * h, hb_title_t * title, int picture, avpicture_free( &pic_in ); } + /** + * Analyzes a frame to detect interlacing artifacts + * and returns true if interlacing (combing) is found. + * + * Code taken from Thomas Oestreich's 32detect filter + * in the Transcode project, with minor formatting changes. + * + * @param buf An hb_buffer structure holding valid frame data + * @param width The frame's width in pixels + * @param height The frame's height in pixels + * @param color_equal Sensitivity for detecting similar colors + * @param color_diff Sensitivity for detecting different colors + * @param threshold Sensitivity for flagging planes as combed + */ +int hb_detect_comb( hb_buffer_t * buf, int width, int height, int color_equal, int color_diff, int threshold ) +{ + int j, k, n, off, block, cc_1, cc_2, cc[3], flag[3]; + uint16_t s1, s2, s3, s4; + cc_1 = 0; cc_2 = 0; + + int offset = 0; + + for( k = 0; k < 3; k++ ) + { + /* One pas for Y, one pass for Cb, one pass for Cr */ + + if( k == 1 ) + { + /* Y has already been checked, now offset by Y's dimensions + and divide all the other values by 2, since Cr and Cb + are half-size compared to Y. */ + offset = width * height; + width >>= 1; + height >>= 1; + threshold >>= 1; + color_equal >>= 1; + color_diff >>= 1; + } + else if ( k == 2 ) + { + /* Y and Cb are done, so the offset needs to be bumped + so it's width*height + (width / 2) * (height / 2) */ + offset *= 5/4; + } + + /* Look at one horizontal line at a time */ + block = width; + + for( j = 0; j < block; ++j ) + { + off = 0; + + for( n = 0; n < ( height - 4 ); n = n + 2 ) + { + /* Look at groups of 4 sequential horizontal lines */ + s1 = ( ( buf->data + offset )[ off + j ] & 0xff ); + s2 = ( ( buf->data + offset )[ off + j + block ] & 0xff ); + s3 = ( ( buf->data + offset )[ off + j + 2 * block ] & 0xff ); + s4 = ( ( buf->data + offset )[ off + j + 3 * block ] & 0xff ); + + /* Note if the 1st and 2nd lines are more different in + color than the 1st and 3rd lines are similar in color.*/ + if ( ( abs( s1 - s3 ) < color_equal ) && + ( abs( s1 - s2 ) > color_diff ) ) + ++cc_1; + + /* Note if the 2nd and 3rd lines are more different in + color than the 2nd and 4th lines are similar in color.*/ + if ( ( abs( s2 - s4 ) < color_equal ) && + ( abs( s2 - s3 ) > color_diff) ) + ++cc_2; + + /* Now move down 2 horizontal lines before starting over.*/ + off += 2 * block; + } + } + + // compare results + /* The final metric seems to be doing some kind of bits per pixel style calculation + to decide whether or not enough lines showed alternating colors for the frame size. */ + cc[k] = (int)( ( cc_1 + cc_2 ) * 1000.0 / ( width * height ) ); + + /* If the plane's cc score meets the threshold, flag it as combed. */ + flag[k] = 0; + if ( cc[k] > threshold ) + { + flag[k] = 1; + } + } + +#if 0 +/* Debugging info */ +// if(flag) + hb_log("flags: %i/%i/%i | cc0: %i | cc1: %i | cc2: %i", flag[0], flag[1], flag[2], cc[0], cc[1], cc[2]); +#endif + + /* When more than one plane shows combing, tell the caller. */ + if (flag[0] || flag[1] || flag[2] ) + { + return 1; + } + + return 0; +} + + /** * Calculates job width and height for anamorphic content, * diff --git a/libhb/hb.h b/libhb/hb.h index 7454b634b..6dfbf7be8 100644 --- a/libhb/hb.h +++ b/libhb/hb.h @@ -76,6 +76,11 @@ void hb_scan( hb_handle_t *, const char * path, Returns the list of valid titles detected by the latest scan. */ hb_list_t * hb_get_titles( hb_handle_t * ); +/* hb_detect_comb() + Analyze a frame for interlacing artifacts, returns true if they're found. + Taken from Thomas Oestreich's 32detect filter in the Transcode project. */ +int hb_detect_comb( hb_buffer_t * buf, int width, int height, int color_equal, int color_diff, int threshold ); + void hb_get_preview( hb_handle_t *, hb_title_t *, int, uint8_t * ); void hb_set_size( hb_job_t *, int ratio, int pixels ); diff --git a/libhb/scan.c b/libhb/scan.c index 5b62fecb0..4aee25bc7 100644 --- a/libhb/scan.c +++ b/libhb/scan.c @@ -286,6 +286,8 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) hb_list_t * list_es, * list_raw; hb_libmpeg2_t * mpeg2; int progressive_count = 0; + int interlaced_preview_count = 0; + int ar16_count = 0, ar4_count = 0; buf_ps = hb_buffer_init( HB_DVD_READ_BUFFER_SIZE ); @@ -419,7 +421,7 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) */ if( progressive_count == 6 ) { - hb_log("Title's mostly progressive NTSC, setting fps to 23.976"); + hb_log("Title's mostly NTSC Film, setting fps to 23.976"); } title->rate_base = 1126125; } @@ -449,7 +451,14 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) } buf_raw = hb_list_item( list_raw, 0 ); - + + /* Check preview for interlacing artifacts */ + if( hb_detect_comb( buf_raw, title->width, title->height, 10, 30, 9 ) ) + { + hb_log("Interlacing detected in preview frame %i", i); + interlaced_preview_count++; + } + hb_get_tempory_filename( data->h, filename, "%x%d", (intptr_t)title, i ); @@ -523,6 +532,18 @@ skip_preview: title->crop[2], title->crop[3], title->aspect == HB_ASPECT_BASE * 16 / 9 ? "16:9" : title->aspect == HB_ASPECT_BASE * 4 / 3 ? "4:3" : "none" ); + + if( interlaced_preview_count >= ( npreviews / 2 ) ) + { + hb_log("Title is likely interlaced or telecined (%i out of %i previews). You should do something about that.", + interlaced_preview_count, npreviews); + title->detected_interlacing = 1; + } + else + { + title->detected_interlacing = 0; + } + goto cleanup; error: |