| 1 | //***************************************************************************** |
| 2 | // This code is meant for use in debugging the CommDetect class and shouldn't |
| 3 | // be used in normal compiled Myth versions. |
| 4 | |
| 5 | #include "commercial_debug.h" |
| 6 | |
| 7 | #ifdef SHOW_DEBUG_WIN |
| 8 | |
| 9 | #include <X11/Xlib.h> |
| 10 | //#include <X11/extensions/Xvlib.h> |
| 11 | |
| 12 | extern "C" { |
| 13 | #include "libavcodec/avcodec.h" |
| 14 | #include "libswscale/swscale.h" |
| 15 | } |
| 16 | |
| 17 | // INPUT_PIX_FMT is used when we convert an input YUV420 frame to a RGB ZPixmap |
| 18 | // Since the commercial detection algorithms only look at the Y luma channel, |
| 19 | // it can be useful to display only that channel. |
| 20 | // But there may be times when you want to see the color images. |
| 21 | // If you want to display color images, use AV_PIX_FMT_YUV420P |
| 22 | // If you want display grayscale images, use AV_PIX_FMT_GRAY8 |
| 23 | // #define INPUT_PIX_FMT AV_PIX_FMT_YUV420P |
| 24 | #define INPUT_PIX_FMT AV_PIX_FMT_GRAY8 |
| 25 | |
| 26 | Window comm_win; |
| 27 | GC comm_gc; |
| 28 | Display *comm_display; |
| 29 | int comm_width = 0; |
| 30 | int comm_width8 = 0; |
| 31 | int comm_height = 0; |
| 32 | int comm_depth = 24; |
| 33 | XImage *comm_image = NULL; |
| 34 | char *comm_buf = NULL; |
| 35 | struct SwsContext *scontext; |
| 36 | |
| 37 | void comm_debug_init( int width, int height ) |
| 38 | { |
| 39 | comm_display = XOpenDisplay(NULL); |
| 40 | |
| 41 | Screen* comm_screen = DefaultScreenOfDisplay(comm_display); |
| 42 | int comm_screen_num = DefaultScreen(comm_display); |
| 43 | |
| 44 | comm_depth = DefaultDepthOfScreen(comm_screen); |
| 45 | |
| 46 | comm_width = width; |
| 47 | // FFmpeg likes linesizes that are multiples of 8. |
| 48 | comm_width8 = (width + 7) & ~7; |
| 49 | comm_height = height; |
| 50 | |
| 51 | comm_win = XCreateSimpleWindow(comm_display, |
| 52 | DefaultRootWindow(comm_display), |
| 53 | 100, 100, comm_width, comm_height, 0, |
| 54 | XWhitePixel(comm_display, comm_screen_num), |
| 55 | XBlackPixel(comm_display, comm_screen_num) ); |
| 56 | |
| 57 | XMapRaised(comm_display, comm_win); |
| 58 | |
| 59 | XSync(comm_display, 0); |
| 60 | |
| 61 | comm_gc = XCreateGC(comm_display, comm_win, 0, 0); |
| 62 | |
| 63 | comm_buf = new char[4 * comm_width8 * comm_height]; |
| 64 | memset(comm_buf, 0, 4 * comm_width8 * comm_height); |
| 65 | |
| 66 | comm_image = XCreateImage(comm_display, DefaultVisual(comm_display, 0), |
| 67 | comm_depth, ZPixmap, 0, comm_buf, |
| 68 | comm_width8, comm_height, 8, 0); |
| 69 | |
| 70 | XSync(comm_display, 0); |
| 71 | |
| 72 | printf( "Commercial Detection debug window created at %dx%dx%d\n", |
| 73 | comm_width, comm_height, comm_depth ); |
| 74 | } |
| 75 | |
| 76 | static void comm_debug_show( AVPicture* pic); |
| 77 | |
| 78 | void comm_debug_show( unsigned char *frame ) |
| 79 | { |
| 80 | AVPicture image_in; |
| 81 | |
| 82 | avpicture_fill(&image_in, (uint8_t *)frame, AV_PIX_FMT_YUV420P, |
| 83 | comm_width, comm_height); |
| 84 | |
| 85 | comm_debug_show(&image_in); |
| 86 | } |
| 87 | |
| 88 | void comm_debug_show( VideoFrame *frame ) |
| 89 | { |
| 90 | AVPicture image_in; |
| 91 | |
| 92 | for (int i = 0; i < 3; i++) |
| 93 | { |
| 94 | image_in.data[i] = frame->buf + frame->offsets[i]; |
| 95 | image_in.linesize[i] = frame->pitches[i]; |
| 96 | } |
| 97 | |
| 98 | comm_debug_show(&image_in); |
| 99 | } |
| 100 | |
| 101 | void comm_debug_show(AVPicture* pic) |
| 102 | { |
| 103 | AVPicture image_out; |
| 104 | AVPixelFormat av_format; |
| 105 | |
| 106 | switch (comm_depth) |
| 107 | { |
| 108 | case 16: av_format = AV_PIX_FMT_RGB565; break; |
| 109 | case 24: av_format = AV_PIX_FMT_RGB32; break; |
| 110 | case 32: av_format = AV_PIX_FMT_RGB32; break; |
| 111 | default: |
| 112 | printf("Unable to display debug video window in %d depth.\n", |
| 113 | comm_depth); |
| 114 | exit(1); |
| 115 | } |
| 116 | |
| 117 | avpicture_fill(&image_out, (uint8_t *)comm_image->data, av_format, |
| 118 | comm_width8, comm_height); |
| 119 | |
| 120 | scontext = sws_getCachedContext(scontext, comm_width, comm_height, |
| 121 | INPUT_PIX_FMT, comm_width, comm_height, av_format, |
| 122 | SWS_FAST_BILINEAR, NULL, NULL, NULL); |
| 123 | if (!scontext) |
| 124 | { |
| 125 | printf("Cannot initialize the image conversion context"); |
| 126 | exit(1); |
| 127 | } |
| 128 | |
| 129 | sws_scale(scontext, pic->data, pic->linesize, 0, comm_height, |
| 130 | image_out.data, image_out.linesize); |
| 131 | |
| 132 | XPutImage(comm_display, comm_win, comm_gc, comm_image, |
| 133 | 0, 0, 0, 0, comm_width, comm_height ); |
| 134 | |
| 135 | XSync(comm_display, 0); |
| 136 | } |
| 137 | |
| 138 | void comm_debug_destroy() |
| 139 | { |
| 140 | XFree(comm_image); |
| 141 | delete comm_buf; |
| 142 | XDestroyWindow(comm_display, comm_win); |
| 143 | XCloseDisplay(comm_display); |
| 144 | } |
| 145 | |
| 146 | #endif |