encoder/set.c encoder/macroblock.c encoder/cabac.c \
encoder/cavlc.c encoder/encoder.c encoder/eval.c
+# Visualization sources
+ifeq ($(VIS),yes)
+SRCS += common/visualize.c common/display-x11.c
+endif
+
# MMX/SSE optims
ifeq ($(ARCH),X86)
SRCS += common/i386/mc-c.c common/i386/dct-c.c common/i386/predict.c
x264_vlc_table_t *x264_total_zeros_lookup[15];
x264_vlc_table_t *x264_total_zeros_dc_lookup[3];
x264_vlc_table_t *x264_run_before_lookup[7];
+
+#if VISUALIZE
+ struct visualize_t *visualize;
+#endif
};
#endif
--- /dev/null
+/*****************************************************************************
+ * x264: h264 encoder
+ *****************************************************************************
+ * Copyright (C) 2005 x264 project
+ *
+ * Author: Tuukka Toivonen <tuukkat@ee.oulu.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "display.h"
+
+static long event_mask = ConfigureNotify|ExposureMask|KeyPressMask|ButtonPressMask|StructureNotifyMask|ResizeRedirectMask;
+
+static Display *disp_display = NULL;
+static struct disp_window {
+ int init;
+ Window window;
+} disp_window[10];
+
+static inline void disp_chkerror(int cond, char *e) {
+ if (!cond) return;
+ fprintf(stderr, "error: %s\n", e ? e : "?");
+ abort();
+}
+
+static void disp_init_display(void) {
+ Visual *visual;
+ int dpy_class;
+ int screen;
+ int dpy_depth;
+
+ if (disp_display != NULL) return;
+ memset(&disp_window, 0, sizeof(disp_window));
+ disp_display = XOpenDisplay("");
+ disp_chkerror(!disp_display, "no display");
+ screen = DefaultScreen(disp_display);
+ visual = DefaultVisual(disp_display, screen);
+ dpy_class = visual->class;
+ dpy_depth = DefaultDepth(disp_display, screen);
+ disp_chkerror(!((dpy_class == TrueColor && dpy_depth == 32)
+ || (dpy_class == TrueColor && dpy_depth == 24)
+ || (dpy_class == TrueColor && dpy_depth == 16)
+ || (dpy_class == PseudoColor && dpy_depth == 8)),
+ "requires 8 bit PseudoColor or 16/24/32 bit TrueColor display");
+}
+
+static void disp_init_window(int num, int width, int height, const unsigned char *tit) {
+ XSizeHints *shint;
+ XSetWindowAttributes xswa;
+ XEvent xev;
+ int screen = DefaultScreen(disp_display);
+ Visual *visual = DefaultVisual (disp_display, screen);
+ unsigned int fg, bg;
+ unsigned int mask;
+ char title[200];
+ Window window;
+ int dpy_depth;
+
+ if (tit) {
+ snprintf(title, 200, "%s: %i/disp", tit, num);
+ } else {
+ snprintf(title, 200, "%i/disp", num);
+ }
+ shint = XAllocSizeHints();
+ disp_chkerror(!shint, "memerror");
+ shint->min_width = shint->max_width = shint->width = width;
+ shint->min_height = shint->max_height = shint->height = height;
+ shint->flags = PSize | PMinSize | PMaxSize;
+ disp_chkerror(num<0 || num>=10, "bad win num");
+ if (!disp_window[num].init) {
+ disp_window[num].init = 1;
+ bg = WhitePixel(disp_display, screen);
+ fg = BlackPixel(disp_display, screen);
+ dpy_depth = DefaultDepth(disp_display, screen);
+ if (dpy_depth==32 || dpy_depth==24 || dpy_depth==16) {
+ mask |= CWColormap;
+ xswa.colormap = XCreateColormap(disp_display, DefaultRootWindow(disp_display), visual, AllocNone);
+ }
+ xswa.background_pixel = bg;
+ xswa.border_pixel = fg;
+ xswa.backing_store = Always;
+ xswa.backing_planes = -1;
+ xswa.bit_gravity = NorthWestGravity;
+ mask = CWBackPixel | CWBorderPixel | CWBackingStore | CWBackingPlanes | CWBitGravity;
+ window = XCreateWindow(disp_display, DefaultRootWindow(disp_display),
+ shint->x, shint->y, shint->width, shint->height,
+ 1, dpy_depth, InputOutput, visual, mask, &xswa);
+ disp_window[num].window = window;
+
+ XSelectInput(disp_display, window, event_mask);
+ XSetStandardProperties(disp_display, window, title, title, None, NULL, 0, shint); /* Tell other applications about this window */
+ XMapWindow(disp_display, window); /* Map window. */
+ do { /* Wait for map. */
+ XNextEvent(disp_display, &xev);
+ } while (xev.type!=MapNotify || xev.xmap.event!=window);
+ //XSelectInput(disp_display, window, KeyPressMask); /* XSelectInput(display, window, NoEventMask);*/
+ }
+ window = disp_window[num].window;
+ XSetStandardProperties(disp_display, window, title, title, None, NULL, 0, shint); /* Tell other applications about this window */
+ XResizeWindow(disp_display, window, width, height);
+ XSync(disp_display, 1);
+ XFree(shint);
+}
+
+void disp_sync(void) {
+ XSync(disp_display, 1);
+}
+
+void disp_setcolor(unsigned char *name) {
+ int screen;
+ GC gc;
+ XColor c_exact, c_nearest;
+ Colormap cm;
+ Status st;
+
+ screen = DefaultScreen(disp_display);
+ gc = DefaultGC(disp_display, screen); /* allocate colors */
+ cm = DefaultColormap(disp_display, screen);
+ st = XAllocNamedColor(disp_display, cm, name, &c_nearest, &c_exact);
+ disp_chkerror(st!=1, "XAllocNamedColor error");
+ XSetForeground(disp_display, gc, c_nearest.pixel);
+}
+
+void disp_gray(int num, char *data, int width, int height, int stride, const unsigned char *tit) {
+ Visual *visual;
+ XImage *ximage;
+ unsigned char *image;
+ int y,x,pixelsize;
+ char dummy;
+ int t = 1;
+ int dpy_depth;
+ int screen;
+ GC gc;
+ //XEvent xev;
+
+ disp_init_display();
+ disp_init_window(num, width, height, tit);
+ screen = DefaultScreen(disp_display);
+ visual = DefaultVisual(disp_display, screen);
+ dpy_depth = DefaultDepth(disp_display, screen);
+ ximage = XCreateImage(disp_display, visual, dpy_depth, ZPixmap, 0, &dummy, width, height, 8, 0);
+ disp_chkerror(!ximage, "no ximage");
+ if (*(char *)&t == 1) {
+ ximage->byte_order = LSBFirst;
+ ximage->bitmap_bit_order = LSBFirst;
+ } else {
+ ximage->byte_order = MSBFirst;
+ ximage->bitmap_bit_order = MSBFirst;
+ }
+ pixelsize = dpy_depth>8 ? sizeof(int) : sizeof(unsigned char);
+ image = malloc(width * height * pixelsize);
+ disp_chkerror(!image, "malloc failed");
+ for (y=0; y<height; y++) for (x=0; x<width; x++) {
+ memset(&image[(width*y + x)*pixelsize], data[y*stride+x], pixelsize);
+ }
+ ximage->data = image;
+ gc = DefaultGC(disp_display, screen); /* allocate colors */
+
+// XUnmapWindow(disp_display, disp_window[num].window); /* Map window. */
+// XMapWindow(disp_display, disp_window[num].window); /* Map window. */
+ XPutImage(disp_display, disp_window[num].window, gc, ximage, 0, 0, 0, 0, width, height);
+// do { /* Wait for map. */
+// XNextEvent(disp_display, &xev);
+// } while (xev.type!=MapNotify || xev.xmap.event!=disp_window[num].window);
+ XPutImage(disp_display, disp_window[num].window, gc, ximage, 0, 0, 0, 0, width, height);
+
+ XDestroyImage(ximage);
+ XSync(disp_display, 1);
+
+}
+
+void disp_gray_zoom(int num, char *data, int width, int height, int stride, const unsigned char *tit, int zoom) {
+ unsigned char *dataz;
+ int y,x,y0,x0;
+ dataz = malloc(width*zoom * height*zoom);
+ disp_chkerror(!dataz, "malloc");
+ for (y=0; y<height; y++) for (x=0; x<width; x++) {
+ for (y0=0; y0<zoom; y0++) for (x0=0; x0<zoom; x0++) {
+ dataz[(y*zoom + y0)*width*zoom + x*zoom + x0] = data[y*stride+x];
+ }
+ }
+ disp_gray(num, dataz, width*zoom, height*zoom, width*zoom, tit);
+ free(dataz);
+}
+
+void disp_point(int num, int x1, int y1) {
+ int screen;
+ GC gc;
+ screen = DefaultScreen(disp_display);
+ gc = DefaultGC(disp_display, screen); /* allocate colors */
+ XDrawPoint(disp_display, disp_window[num].window, gc, x1, y1);
+// XSync(disp_display, 1);
+}
+
+void disp_line(int num, int x1, int y1, int x2, int y2) {
+ int screen;
+ GC gc;
+ screen = DefaultScreen(disp_display);
+ gc = DefaultGC(disp_display, screen); /* allocate colors */
+ XDrawLine(disp_display, disp_window[num].window, gc, x1, y1, x2, y2);
+// XSync(disp_display, 1);
+}
+
+void disp_rect(int num, int x1, int y1, int x2, int y2) {
+ int screen;
+ GC gc;
+ screen = DefaultScreen(disp_display);
+
+ gc = DefaultGC(disp_display, screen); /* allocate colors */
+ XDrawRectangle(disp_display, disp_window[num].window, gc, x1, y1, x2-x1, y2-y1);
+// XSync(disp_display, 1);
+}
--- /dev/null
+/*****************************************************************************
+ * x264: h264 encoder
+ *****************************************************************************
+ * Copyright (C) 2005 x264 project
+ *
+ * Author: Tuukka Toivonen <tuukkat@ee.oulu.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+
+#ifndef _DISPLAY_H
+#define _DISPLAY_H 1
+
+void disp_sync(void);
+void disp_setcolor(unsigned char *name);
+/* Display a region of byte wide memory as a grayscale image.
+ * num is the window to use for displaying. */
+void disp_gray(int num, char *data, int width, int height,
+ int stride, const unsigned char *title);
+void disp_gray_zoom(int num, char *data, int width, int height,
+ int stride, const unsigned char *title, int zoom);
+void disp_point(int num, int x1, int y1);
+void disp_line(int num, int x1, int y1, int x2, int y2);
+void disp_rect(int num, int x1, int y1, int x2, int y2);
+
+#endif
--- /dev/null
+/*****************************************************************************
+ * x264: h264 encoder
+ *****************************************************************************
+ * Copyright (C) 2005 x264 project
+ *
+ * Author: Tuukka Toivonen <tuukkat@ee.oulu.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+
+/*
+ * Some explanation of the symbols used:
+ * Red/pink: intra block
+ * Blue: inter block
+ * Green: skip block
+ * Yellow: B-block (not visualized properly yet)
+ *
+ * The intra blocks have generally lines drawn perpendicular
+ * to the prediction direction, so for example, if there is a pink block
+ * with horizontal line at the top of it, it is interpolated by assuming
+ * luma to be vertically constant.
+ * DC predicted blocks have both horizontal and vertical lines,
+ * pink blocks with a diagonal line are predicted using the planar function.
+ */
+
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#else
+#include <inttypes.h>
+#endif
+#include <stddef.h> /* NULL */
+#include <stdio.h> /* getchar */
+#include <stdlib.h> /* abort */
+
+#include "common.h"
+#include "visualize.h"
+#include "macroblock.h"
+#include "display.h"
+
+typedef struct {
+ int i_type;
+ int i_partition;
+ int i_sub_partition[4];
+ int i_intra16x16_pred_mode;
+ int intra4x4_pred_mode[4][4];
+ int8_t ref[2][4][4]; /* [list][y][x] */
+ int16_t mv[2][4][4][2]; /* [list][y][x][mvxy] */
+} visualize_t;
+
+/* {{{ [fold] char *get_string(const stringlist_t *sl, int entries, int code) */
+/* Return string from stringlist corresponding to the given code */
+#define GET_STRING(sl, code) get_string((sl), sizeof(sl)/sizeof(*(sl)), code)
+
+typedef struct {
+ int code;
+ char *string;
+} stringlist_t;
+
+static char *get_string(const stringlist_t *sl, int entries, int code)
+{
+ int i;
+
+ for (i=0; i<entries; i++) {
+ if (sl[i].code==code) break;
+ }
+ return (i>=entries) ? "?" : sl[i].string;
+}
+/* }}} */
+/* {{{ [fold] void mv(int x0, int y0, int16_t dmv[2], int zoom, char *col) */
+/* Plot motion vector */
+static void mv(int x0, int y0, int16_t dmv[2], int zoom, char *col)
+{
+ int dx = dmv[0];
+ int dy = dmv[1];
+
+ dx = (dx*zoom)/4; /* Quarter pixel accurate MVs */
+ dy = (dy*zoom)/4;
+ disp_line(0, x0, y0, x0+dx, y0+dy);
+ disp_setcolor("black");
+ disp_point(0, x0, y0);
+ disp_setcolor(col);
+}
+/* }}} */
+
+/* {{{ [fold] void x264_visualize_init( x264_t *h ) */
+void x264_visualize_init( x264_t *h )
+{
+ int mb = h->sps->i_mb_width * h->sps->i_mb_height;
+ h->visualize = x264_malloc(mb * sizeof(visualize_t));
+}
+/* }}} */
+/* {{{ [fold] void x264_visualize_mb( x264_t *h ) */
+void x264_visualize_mb( x264_t *h )
+{
+ visualize_t *v = (visualize_t*)h->visualize + h->mb.i_mb_xy;
+ int i, l, x, y;
+
+ /* Save all data for the MB what we need for drawing the visualization */
+ v->i_type = h->mb.i_type;
+ v->i_partition = h->mb.i_partition;
+ for (i=0; i<4; i++) v->i_sub_partition[i] = h->mb.i_sub_partition[i];
+ for (y=0; y<4; y++) for (x=0; x<4; x++)
+ v->intra4x4_pred_mode[y][x] = h->mb.cache.intra4x4_pred_mode[X264_SCAN8_0+y*8+x];
+ for (l=0; l<2; l++) for (y=0; y<4; y++) for (x=0; x<4; x++) {
+ for (i=0; i<2; i++) {
+ v->mv[l][y][x][i] = h->mb.cache.mv[l][X264_SCAN8_0+y*8+x][i];
+ }
+ v->ref[l][y][x] = h->mb.cache.ref[i][X264_SCAN8_0+y*8+x];
+ }
+ v->i_intra16x16_pred_mode = h->mb.i_intra16x16_pred_mode;
+}
+/* }}} */
+/* {{{ [fold] void x264_visualize_close( x264_t *h ) */
+void x264_visualize_close( x264_t *h )
+{
+ x264_free(h->visualize);
+}
+/* }}} */
+/* {{{ [fold] void x264_visualize( x264_t *h ) */
+/* Display visualization (block types, MVs) of the encoded frame */
+/* FIXME: B-type MBs not handled yet properly
+ * Reference frame number not visualized */
+void x264_visualize_show( x264_t *h )
+{
+ int mb_xy;
+ static const stringlist_t mb_types[] = {
+ /* Block types marked as NULL will not be drawn */
+ { I_4x4 , "red" },
+ { I_16x16 , "pink" },
+ { I_PCM , "violet" },
+ { P_L0 , "SlateBlue" },
+ { P_8x8 , "blue" },
+ { P_SKIP , "green" },
+ { B_DIRECT, "yellow" },
+ { B_L0_L0 , "yellow" },
+ { B_L0_L1 , "yellow" },
+ { B_L0_BI , "yellow" },
+ { B_L1_L0 , "yellow" },
+ { B_L1_L1 , "yellow" },
+ { B_L1_BI , "yellow" },
+ { B_BI_L0 , "yellow" },
+ { B_BI_L1 , "yellow" },
+ { B_BI_BI , "yellow" },
+ { B_8x8 , "yellow" },
+ { B_SKIP , "yellow" },
+ };
+
+ static const int waitkey = 1;
+ static const int drawbox = 1;
+ static const int borders = 0;
+
+ static const int pad = 32;
+ static const int zoom = 2;
+ uint8_t *const frame = h->fdec->plane[0];
+ const int width = h->param.i_width;
+ const int height = h->param.i_height;
+ const int stride = h->fdec->i_stride[0];
+
+ if (borders) {
+ disp_gray_zoom(0, frame - pad*stride - pad, width+2*pad, height+2*pad, stride, "fdec", zoom);
+ } else {
+ disp_gray_zoom(0, frame, width, height, stride, "fdec", zoom);
+ }
+
+ for( mb_xy = 0; mb_xy < h->sps->i_mb_width * h->sps->i_mb_height; mb_xy++ )
+ {
+ visualize_t *v = (visualize_t*)h->visualize + mb_xy;
+ const int mb_y = mb_xy / h->sps->i_mb_width;
+ const int mb_x = mb_xy % h->sps->i_mb_width;
+ int x = mb_x*16*zoom;
+ int y = mb_y*16*zoom;
+ if (borders) {
+ x += pad*zoom;
+ y += pad*zoom;
+ }
+ int l = 0;
+ char *col = GET_STRING(mb_types, v->i_type);
+ unsigned int i, j;
+ if (col==NULL) continue;
+ disp_setcolor(col);
+ if (drawbox) disp_rect(0, x, y, x+16*zoom-1, y+16*zoom-1);
+
+ if (v->i_type==P_L0 || v->i_type==P_8x8 || v->i_type==P_SKIP) {
+
+ /* Predicted (inter) mode, with motion vector */
+ if (v->i_partition==D_16x16 || v->i_type==P_SKIP) {
+ mv(x+8*zoom, y+8*zoom, v->mv[l][0][0], zoom, col);
+ }
+ if (v->i_partition==D_16x8) {
+ if (drawbox) disp_rect(0, x, y, x+16*zoom, y+8*zoom);
+ mv(x+8*zoom, y+4*zoom, v->mv[l][0][0], zoom, col);
+ if (drawbox) disp_rect(0, x, y+8*zoom, x+16*zoom, y+16*zoom);
+ mv(x+8*zoom, y+12*zoom, v->mv[l][2][0], zoom, col);
+ }
+ if (v->i_partition==D_8x16) {
+ if (drawbox) disp_rect(0, x, y, x+8*zoom, y+16*zoom);
+ mv(x+4*zoom, y+8*zoom, v->mv[l][0][0], zoom, col);
+ if (drawbox) disp_rect(0, x+8*zoom, y, x+16*zoom, y+16*zoom);
+ mv(x+12*zoom, y+8*zoom, v->mv[l][0][2], zoom, col);
+ }
+ if (v->i_partition==D_8x8) {
+ for (i=0; i<2; i++) for (j=0; j<2; j++) {
+ int sp = v->i_sub_partition[i*2+j];
+ const int x0 = x + j*8*zoom;
+ const int y0 = y + i*8*zoom;
+ if (sp==D_L1_8x8) sp = D_L0_8x8;
+ if (sp==D_L1_4x8) sp = D_L0_4x8;
+ if (sp==D_L1_8x4) sp = D_L0_8x4;
+ if (sp==D_L1_4x4) sp = D_L0_4x4;
+ if (sp==D_L0_8x8) {
+ if (drawbox) disp_rect(0, x0, y0, x0+8*zoom, y0+8*zoom);
+ mv(x0+4*zoom, y0+4*zoom, v->mv[l][2*i][2*j], zoom, col);
+ }
+ if (sp==D_L0_8x4) {
+ if (drawbox) disp_rect(0, x0, y0, x0+8*zoom, y0+4*zoom);
+ if (drawbox) disp_rect(0, x0, y0+4*zoom, x0+8*zoom, y0+8*zoom);
+ mv(x0+4*zoom, y0+2*zoom, v->mv[l][2*i][2*j], zoom, col);
+ mv(x0+4*zoom, y0+6*zoom, v->mv[l][2*i+1][2*j], zoom, col);
+ }
+ if (sp==D_L0_4x8) {
+ if (drawbox) disp_rect(0, x0, y0, x0+4*zoom, y0+8*zoom);
+ if (drawbox) disp_rect(0, x0+4*zoom, y0, x0+8*zoom, y0+8*zoom);
+ mv(x0+2*zoom, y0+4*zoom, v->mv[l][2*i][2*j], zoom, col);
+ mv(x0+6*zoom, y0+4*zoom, v->mv[l][2*i][2*j+1], zoom, col);
+ }
+ if (sp==D_L0_4x4) {
+ if (drawbox) disp_rect(0, x0, y0, x0+4*zoom, y0+4*zoom);
+ if (drawbox) disp_rect(0, x0+4*zoom, y0, x0+8*zoom, y0+4*zoom);
+ if (drawbox) disp_rect(0, x0, y0+4*zoom, x0+4*zoom, y0+8*zoom);
+ if (drawbox) disp_rect(0, x0+4*zoom, y0+4*zoom, x0+8*zoom, y0+8*zoom);
+ mv(x0+2*zoom, y0+2*zoom, v->mv[l][2*i][2*j], zoom, col);
+ mv(x0+6*zoom, y0+2*zoom, v->mv[l][2*i][2*j+1], zoom, col);
+ mv(x0+2*zoom, y0+6*zoom, v->mv[l][2*i+1][2*j], zoom, col);
+ mv(x0+6*zoom, y0+6*zoom, v->mv[l][2*i+1][2*j+1], zoom, col);
+ }
+ }
+ }
+ }
+
+ if (v->i_type==I_4x4 || v->i_type==I_16x16 || v->i_type==I_PCM) {
+ /* Intra coded */
+ if (v->i_type==I_16x16) {
+ switch (v->i_intra16x16_pred_mode) {
+ case I_PRED_16x16_V:
+ disp_line(0, x+2*zoom, y+2*zoom, x+14*zoom, y+2*zoom);
+ break;
+ case I_PRED_16x16_H:
+ disp_line(0, x+2*zoom, y+2*zoom, x+2*zoom, y+14*zoom);
+ break;
+ case I_PRED_16x16_DC:
+ case I_PRED_16x16_DC_LEFT:
+ case I_PRED_16x16_DC_TOP:
+ case I_PRED_16x16_DC_128:
+ disp_line(0, x+2*zoom, y+2*zoom, x+14*zoom, y+2*zoom);
+ disp_line(0, x+2*zoom, y+2*zoom, x+2*zoom, y+14*zoom);
+ break;
+ case I_PRED_16x16_P:
+ disp_line(0, x+2*zoom, y+2*zoom, x+8*zoom, y+8*zoom);
+ break;
+ default: abort();
+ }
+ }
+ if (v->i_type==I_4x4) {
+ for (i=0; i<4; i++) for (j=0; j<4; j++) {
+ const int x0 = x + j*4*zoom;
+ const int y0 = y + i*4*zoom;
+ if (drawbox) disp_rect(0, x0, y0, x0+4*zoom, y0+4*zoom);
+ switch (v->intra4x4_pred_mode[i][j]) {
+ case I_PRED_4x4_V: /* Vertical */
+ disp_line(0, x0+0*zoom, y0+1*zoom, x0+4*zoom, y0+1*zoom);
+ break;
+ case I_PRED_4x4_H: /* Horizontal */
+ disp_line(0, x0+1*zoom, y0+0*zoom, x0+1*zoom, y0+4*zoom);
+ break;
+ case I_PRED_4x4_DC: /* DC, average from top and left sides */
+ case I_PRED_4x4_DC_LEFT:
+ case I_PRED_4x4_DC_TOP:
+ case I_PRED_4x4_DC_128:
+ disp_line(0, x0+1*zoom, y0+1*zoom, x0+4*zoom, y0+1*zoom);
+ disp_line(0, x0+1*zoom, y0+1*zoom, x0+1*zoom, y0+4*zoom);
+ break;
+ case I_PRED_4x4_DDL: /* Topright-downleft */
+ disp_line(0, x0+0*zoom, y0+0*zoom, x0+4*zoom, y0+4*zoom);
+ break;
+ case I_PRED_4x4_DDR: /* Topleft-downright */
+ disp_line(0, x0+0*zoom, y0+4*zoom, x0+4*zoom, y0+0*zoom);
+ break;
+ case I_PRED_4x4_VR: /* Mix of topleft-downright and vertical */
+ disp_line(0, x0+0*zoom, y0+2*zoom, x0+4*zoom, y0+1*zoom);
+ break;
+ case I_PRED_4x4_HD: /* Mix of topleft-downright and horizontal */
+ disp_line(0, x0+2*zoom, y0+0*zoom, x0+1*zoom, y0+4*zoom);
+ break;
+ case I_PRED_4x4_VL: /* Mix of topright-downleft and vertical */
+ disp_line(0, x0+0*zoom, y0+1*zoom, x0+4*zoom, y0+2*zoom);
+ break;
+ case I_PRED_4x4_HU: /* Mix of topright-downleft and horizontal */
+ disp_line(0, x0+1*zoom, y0+0*zoom, x0+2*zoom, y0+4*zoom);
+ break;
+ default: abort();
+ }
+ }
+ }
+ }
+ }
+
+ disp_sync();
+ if (waitkey) getchar();
+}
+/* }}} */
+
+//EOF
--- /dev/null
+/*****************************************************************************
+ * x264: h264 encoder
+ *****************************************************************************
+ * Copyright (C) 2005 x264 project
+ *
+ * Author: Tuukka Toivonen <tuukkat@ee.oulu.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+
+#ifndef _VISUALIZE_H
+#define _VISUALIZE_H 1
+
+#include "common/common.h"
+
+void x264_visualize_init( x264_t *h );
+void x264_visualize_mb( x264_t *h );
+void x264_visualize_show( x264_t *h );
+void x264_visualize_close( x264_t *h );
+
+#endif
echo " --enable-mp4-output enables mp4 output (using gpac)"
echo " --enable-vfw compiles the VfW frontend"
echo " --enable-debug adds -g, doesn't strip"
+echo " --enable-visualize enables visualization (X11 only)"
echo " --extra-cflags=ECFLAGS add ECFLAGS to CFLAGS"
echo " --extra-ldflags=ELDFLAGS add ELDFLAGS to LDFLAGS"
echo ""
mp4_output="no"
debug="no"
vfw="no"
+vis="no"
CC="gcc"
CFLAGS="-Wall -I. -O4 -funroll-loops -ffast-math -D__X264__"
--enable-vfw)
vfw="yes"
;;
+ --enable-visualize)
+ LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11"
+ CFLAGS="$CFLAGS -DVISUALIZE=1"
+ vis="yes"
+ ;;
*)
echo "Unknown option $opt, ignored"
;;
ASFLAGS=$ASFLAGS
VFW=$vfw
EXE=$EXE
+VIS=$vis
EOF
if [ "$vfw" == "yes" ]; then
echo "mp4 output: $mp4_output"
echo "vfw: $vfw"
echo "debug: $debug"
+echo "visualize: $vis"
echo
echo "You can run 'make' now."
#include "ratecontrol.h"
#include "macroblock.h"
+#if VISUALIZE
+#include "common/visualize.h"
+#endif
+
//#define DEBUG_MB_TYPE
//#define DEBUG_DUMP_FRAME
//#define DEBUG_BENCHMARK
h->mb.i_last_qp = h->pps->i_pic_init_qp + h->sh.i_qp_delta;
h->mb.i_last_dqp = 0;
+#if VISUALIZE
+ if( h->param.b_visualize )
+ x264_visualize_init( h );
+#endif
+
for( mb_xy = 0, i_skip = 0; mb_xy < h->sps->i_mb_width * h->sps->i_mb_height; mb_xy++ )
{
const int i_mb_y = mb_xy / h->sps->i_mb_width;
}
TIMER_STOP( i_mtime_write );
+#if VISUALIZE
+ if( h->param.b_visualize )
+ x264_visualize_mb( h );
+#endif
+
/* save cache */
x264_macroblock_cache_save( h );
x264_nal_end( h );
+#if VISUALIZE
+ if( h->param.b_visualize )
+ {
+ x264_visualize_show( h );
+ x264_visualize_close( h );
+ }
+#endif
+
/* Compute misc bits */
h->stat.frame.i_misc_bits = bs_pos( &h->out.bs )
+ NALU_OVERHEAD * 8
static void SigIntHandler( int a )
{
i_ctrl_c = 1;
+#if VISUALIZE
+ exit(0);
+#endif
}
/* input file operation function pointers */
" --quiet Quiet Mode\n"
" -v, --verbose Print stats for each frame\n"
" --progress Show a progress indicator while encoding\n"
+ " --visualize Show MB types overlayed on the encoded video\n"
" --aud Use access unit delimiters\n"
"\n",
X264_BUILD, X264_VERSION,
#define OPT_VBVMAXRATE 287
#define OPT_VBVBUFSIZE 288
#define OPT_VBVINIT 289
+#define OPT_VISUALIZE 290
static struct option long_options[] =
{
{ "quiet", no_argument, NULL, OPT_QUIET },
{ "verbose", no_argument, NULL, 'v' },
{ "progress",no_argument, NULL, OPT_PROGRESS },
+ { "visualize",no_argument, NULL, OPT_VISUALIZE },
{ "aud", no_argument, NULL, OPT_AUD },
{0, 0, 0, 0}
};
case OPT_PROGRESS:
*b_progress = 1;
break;
+ case OPT_VISUALIZE:
+#ifdef VISUALIZE
+ param->b_visualize = 1;
+#else
+ fprintf( stderr, "not compiled with visualization support\n" );
+#endif
+ break;
default:
fprintf( stderr, "unknown option (%c)\n", optopt );
return -1;
void (*pf_log)( void *, int i_level, const char *psz, va_list );
void *p_log_private;
int i_log_level;
+ int b_visualize;
/* Encoder analyser parameters */
struct