From 61eb3b3b714dfd3d2947ed8181321bffbbc2c092 Mon Sep 17 00:00:00 2001 From: Ari Koivula Date: Tue, 1 Oct 2013 19:55:45 +0300 Subject: [PATCH] Improve cu-visualization by arranging them to picture dimensions and colors. --- src/debug.c | 68 +++++++++++++++++++++++++++++++++++++++++++++------- src/debug.h | 2 +- src/search.c | 11 +++++---- 3 files changed, 66 insertions(+), 15 deletions(-) diff --git a/src/debug.c b/src/debug.c index c90f03b4..45f6fda0 100644 --- a/src/debug.c +++ b/src/debug.c @@ -31,23 +31,73 @@ void close_cu_file(FILE *fp) { fclose(fp); } +void yuv2rgb(unsigned char yuv[3], unsigned char rgb[3]) +{ + int y = yuv[0]; + int u = yuv[1]; + int v = yuv[2]; + + int r = 1.164 * y + 1.596 * (v - 128); + int g = 1.165 * y - 0.392 * (u - 128) - 0.813 * (v - 128); + int b = 1.164 * y + 2.017 * (u - 128); + + rgb[0] = CLIP(0, 255, r); + rgb[1] = CLIP(0, 255, g); + rgb[2] = CLIP(0, 255, b); +} + /** * Print information about the Coding Unit (CU) into the FILE* provided by open_cu_file. */ -unsigned render_cu_file(encoder_control *encoder, unsigned depth, uint16_t xCtb, uint16_t yCtb, FILE *fp) +unsigned render_cu_file(encoder_control *encoder, picture *pic, + unsigned depth, uint16_t xCtb, uint16_t yCtb, FILE *fp) { - cu_info *cu = &encoder->in.cur_pic->cu_array[depth][xCtb + yCtb * (encoder->in.width_in_lcu<in.cur_pic->cu_array[MAX_DEPTH][xCtb + yCtb * (encoder->in.width_in_lcu<cu_array[depth][xCtb + yCtb * (pic->width_in_lcu<cu_array[MAX_DEPTH][xCtb + yCtb * (pic->width_in_lcu<QP]) << 4; unsigned sum = 0; unsigned best_cost = -1; char type = cu->type == CU_INTRA ? 'I' : 'P'; + unsigned x = xCtb * CU_MIN_SIZE_PIXELS; + unsigned y = yCtb * CU_MIN_SIZE_PIXELS; + unsigned luma = y * pic->width + x; + unsigned chroma = (y >> 1) * (pic->width >> 1) + (x >> 1); + unsigned char yuv[3] = { 0, 0, 0 }; + unsigned char rgb[3] = { 0, 0, 0 }; + + if (x > pic->width || y > pic->width) { + // Don't output anything for CU's completely outside the botders. + return 0; + } + + if (encoder->ref->used_size > 0) { + const picture *ref_pic = encoder->ref->pics[0]; + yuv[0] = ref_pic->y_recdata[luma]; + yuv[1] = ref_pic->u_recdata[chroma]; + yuv[2] = ref_pic->v_recdata[chroma]; + yuv2rgb(yuv, rgb); + } + + // Enclose everything in a table with the assumption that this function is + // called from left to right and from top to down. + if (depth == 0) { + if (yCtb == 0 && xCtb == 0) { + fprintf(fp, "
"); + } else if (xCtb == 0) { + fprintf(fp, "
"); + } else if (xCtb == NO_SCU_IN_LCU(pic->width_in_lcu) + && yCtb == NO_SCU_IN_LCU(pic->height_in_lcu)) { + fprintf(fp, "
"); + } else { + fprintf(fp, ""); + } + } fprintf(fp, - "\n
" + "\n\n", - depth, + depth, rgb[0], rgb[1], rgb[2], depth, xCtb, yCtb, (cu->type == CU_INTRA ? 'I' : 'P'), cu->inter.cost, cu->inter.mv[0], cu->inter.mv[1]); @@ -58,15 +108,15 @@ unsigned render_cu_file(encoder_control *encoder, unsigned depth, uint16_t xCtb, uint8_t change = 1<<(MAX_DEPTH-1-depth); fprintf(fp, ""); fprintf(fp, ""); fprintf(fp, "", diff --git a/src/debug.h b/src/debug.h index 768b5261..996934f0 100644 --- a/src/debug.h +++ b/src/debug.h @@ -21,6 +21,6 @@ FILE * open_cu_file(char *filename); void close_cu_file(FILE *fp); -unsigned render_cu_file(encoder_control *encoder, unsigned depth, uint16_t x_cu, uint16_t y_cu, FILE *fp); +unsigned render_cu_file(encoder_control *encoder, picture *pic, unsigned depth, uint16_t x_cu, uint16_t y_cu, FILE *fp); #endif diff --git a/src/search.c b/src/search.c index 51eadfa5..963b3ab8 100644 --- a/src/search.c +++ b/src/search.c @@ -26,6 +26,7 @@ // Temporarily for debugging. #define USE_INTRA_IN_P 0 +//#define RENDER_CU encoder->frame==2 #define RENDER_CU 0 #define USE_FULL_SEARCH 0 #define USE_CHROMA_IN_MV_SEARCH 0 @@ -489,7 +490,7 @@ void search_slice_data(encoder_control *encoder) int16_t x_lcu, y_lcu; FILE *fp = 0, *fp2 = 0; - if (RENDER_CU && encoder->frame == 1) { + if (RENDER_CU) { fp = open_cu_file("cu_search.html"); fp2 = open_cu_file("cu_best.html"); } @@ -500,14 +501,14 @@ void search_slice_data(encoder_control *encoder) uint8_t depth = 0; // Recursive function for looping through all the sub-blocks search_tree(encoder, x_lcu << MAX_DEPTH, y_lcu << MAX_DEPTH, depth); - if (RENDER_CU && encoder->frame == 1) { - render_cu_file(encoder, depth, x_lcu << MAX_DEPTH, y_lcu << MAX_DEPTH, fp); + if (RENDER_CU) { + render_cu_file(encoder, encoder->in.cur_pic, depth, x_lcu << MAX_DEPTH, y_lcu << MAX_DEPTH, fp); } // Decide actual coding modes search_best_mode(encoder, x_lcu << MAX_DEPTH, y_lcu << MAX_DEPTH, depth); - if (RENDER_CU && encoder->frame == 1) { - render_cu_file(encoder, depth, x_lcu << MAX_DEPTH, y_lcu << MAX_DEPTH, fp2); + if (RENDER_CU) { + render_cu_file(encoder, encoder->in.cur_pic, depth, x_lcu << MAX_DEPTH, y_lcu << MAX_DEPTH, fp2); } } }
" "%u (%u, %u), %c, " "c=%u, mv=(%d, %d)
"); - sum += render_cu_file(encoder, depth + 1, xCtb, yCtb, fp); + sum += render_cu_file(encoder, pic, depth + 1, xCtb, yCtb, fp); fprintf(fp, ""); - sum += render_cu_file(encoder, depth + 1, xCtb + change, yCtb, fp); + sum += render_cu_file(encoder, pic, depth + 1, xCtb + change, yCtb, fp); fprintf(fp, "
"); - sum += render_cu_file(encoder, depth + 1, xCtb, yCtb + change, fp); + sum += render_cu_file(encoder, pic, depth + 1, xCtb, yCtb + change, fp); fprintf(fp, ""); - sum += render_cu_file(encoder, depth + 1, xCtb + change, yCtb + change, fp); + sum += render_cu_file(encoder, pic, depth + 1, xCtb + change, yCtb + change, fp); fprintf(fp, "
sum=%u, sum+lambda=%u