From 48e2c4cebf3b195466d7b0fa3eb58e8b02577bdb Mon Sep 17 00:00:00 2001 From: sam Date: Fri, 16 Jan 2009 14:23:14 +0000 Subject: [PATCH] storyboard.c: - generate smaller thumbnail mosaics - process more images (1 out of 15 instead of 20) - try to rule out more similar images - cope with streams that do not advertise their picture size in the headers git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/libpipi/trunk@3351 92316355-f0b4-4df1-b90c-862c8a59935f --- examples/storyboard.c | 114 ++++++++++++++++++++++++++---------------- 1 file changed, 71 insertions(+), 43 deletions(-) diff --git a/examples/storyboard.c b/examples/storyboard.c index 43ceb38..ba3c589 100644 --- a/examples/storyboard.c +++ b/examples/storyboard.c @@ -24,14 +24,16 @@ #include -#define STEP 20 +#define STEP 15 #define TWIDTH 90 #define THEIGHT 60 #define TCOLS 10 -#define TROWS 200 +#define TROWS 50 #define NTHUMBS (TCOLS*TROWS) +static int similar(uint8_t *img1, uint8_t *img2); + int main(int argc, char *argv[]) { char fmtstr[1024]; @@ -40,7 +42,7 @@ int main(int argc, char *argv[]) AVCodecContext *ctx; AVCodec *codec; AVFrame *frame; - struct SwsContext *sws; + struct SwsContext *sws = NULL; pipi_image_t *image; pipi_pixels_t *p; uint8_t *buffer; @@ -83,10 +85,6 @@ int main(int argc, char *argv[]) frame = avcodec_alloc_frame(); - sws = sws_getContext(ctx->width, ctx->height, ctx->pix_fmt, - TWIDTH, THEIGHT, PIX_FMT_RGB32, - SWS_BICUBIC, NULL, NULL, NULL); - for(;;) { int finished, ret; @@ -95,7 +93,6 @@ int main(int argc, char *argv[]) if(idx == NTHUMBS || (idx > 0 && ret < 0)) { - /* Only process every 20th image */ char buf[1024]; sprintf(buf, fmtstr, k++); printf("saving %i thumbs in %s\n", idx, buf); @@ -120,29 +117,27 @@ int main(int argc, char *argv[]) continue; } - n++; - - if((n % STEP) == STEP / 2) + /* Only process every 20th image */ + if((++n % STEP) == STEP / 2) { - int pitch = TWIDTH * TCOLS * 4; uint8_t *start; + int pitch = TWIDTH * TCOLS * 4; + int good = 1; start = buffer + (idx % TCOLS) * TWIDTH * 4 + (idx / TCOLS) * TWIDTH * TCOLS * 4 * THEIGHT; + if(!sws) + sws = sws_getContext(ctx->width, ctx->height, ctx->pix_fmt, + TWIDTH, THEIGHT, PIX_FMT_RGB32, + SWS_BICUBIC, NULL, NULL, NULL); + sws_scale(sws, frame->data, frame->linesize, 0, ctx->height, &start, &pitch); - /* Now check whether the new image is really different - * from the previous one (> 8% pixel changes) */ - if(idx == 0) - { - idx++; - } - else + if(idx > 0) { uint8_t *prev; - int x, y, t, a, b, changed = 0; if(idx % TCOLS) prev = start - TWIDTH * 4; @@ -150,29 +145,15 @@ int main(int argc, char *argv[]) prev = start + (TCOLS - 1) * TWIDTH * 4 - TWIDTH * TCOLS * 4 * THEIGHT; - for(y = 0; y < THEIGHT; y++) - for(x = 0; x < TWIDTH; x++) - { - int ok = 0; - - for(t = 0; t < 3; t++) - { - int offset = y * TWIDTH * TCOLS + x; - a = start[offset * 4 + t]; - b = prev[offset * 4 + t]; - - if(a < b - 5 || a > b + 5) - { - ok = 1; - break; - } - } - - changed += ok; - } - - if(changed > TWIDTH * THEIGHT * 8 / 100) - idx++; + /* Now check whether the new image is really different + * from the previous one (> 10% pixel changes) */ + if(similar(start, prev)) + good = 0; + } + + if(good) + { + idx++; } } @@ -182,3 +163,50 @@ int main(int argc, char *argv[]) return EXIT_SUCCESS; } +static int similar(uint8_t *img1, uint8_t *img2) +{ + int x, y, t, a, b, changed = 0; + + for(y = 1; y < THEIGHT - 1; y++) + for(x = 1; x < TWIDTH - 1; x++) + { + int offset = y * TWIDTH * TCOLS + x; + int ok = 0; + + for(t = 0; t < 3; t++) + { + a = 2 * img1[offset * 4 + t]; + a += img1[(offset - TWIDTH * TCOLS - 1) * 4 + t]; + a += img1[(offset - TWIDTH * TCOLS) * 4 + t]; + a += img1[(offset - TWIDTH * TCOLS + 1) * 4 + t]; + a += img1[(offset - 1) * 4 + t]; + a += img1[(offset + 1) * 4 + t]; + a += img1[(offset + TWIDTH * TCOLS - 1) * 4 + t]; + a += img1[(offset + TWIDTH * TCOLS) * 4 + t]; + a += img1[(offset + TWIDTH * TCOLS + 1) * 4 + t]; + a /= 10; + + b = 2 * img2[offset * 4 + t]; + b += img2[(offset - TWIDTH * TCOLS - 1) * 4 + t]; + b += img2[(offset - TWIDTH * TCOLS) * 4 + t]; + b += img2[(offset - TWIDTH * TCOLS + 1) * 4 + t]; + b += img2[(offset - 1) * 4 + t]; + b += img2[(offset + 1) * 4 + t]; + b += img2[(offset + TWIDTH * TCOLS - 1) * 4 + t]; + b += img2[(offset + TWIDTH * TCOLS) * 4 + t]; + b += img2[(offset + TWIDTH * TCOLS + 1) * 4 + t]; + b /= 10; + + if(a < b - 8 || a > b + 8) + { + ok = 1; + break; + } + } + + changed += ok; + } + + return changed < (TWIDTH * THEIGHT * 10 / 100); +} +