Пример #1
0
void
close_meram(shvpu_meram_t *mdata)
{
	if (!mdata || !mdata->meram)
		return;
	if (mdata->decY_icb)
		release_icb(mdata, mdata->decY_icb);
	if (mdata->decC_icb)
		release_icb(mdata, mdata->decC_icb);
	meram_close(mdata->meram);
}
Пример #2
0
int main (int argc, char * argv[])
{
	UIOMux * uiomux;
	uiomux_resource_t uiores;

	char * infilename[2] = {NULL, NULL}, * outfilename = NULL;
	FILE * infile[2], * outfile = NULL;
	size_t nread;
	size_t input_size[2], output_size;
	SHVIO *vio;
	struct ren_vid_surface src[2];
	const struct ren_vid_surface *srclist[2] = {
		&src[0], &src[1]
	};
	struct ren_vid_surface dst;
	void *inbuf[2], *outbuf;
	int ret;
	int frameno=0;

	int show_version = 0;
	int show_help = 0;
	int show_list_vio = 0;
	char * progname;
	char * viodev = NULL;
	int error = 0;

	int c;
	char * optstring = "hvo:O:c:s:C:S:f:u:l";

#ifdef HAVE_GETOPT_LONG
	static struct option long_options[] = {
		{"help", no_argument, 0, 'h'},
		{"version", no_argument, 0, 'v'},
		{"output", required_argument, 0, 'o'},
		{"overlay", required_argument, 0, 'O'},
		{"input-colorspace", required_argument, 0, 'c'},
		{"input-size", required_argument, 0, 's'},
		{"output-colorspace", required_argument, 0, 'C'},
		{"output-size", required_argument, 0, 'S'},
		{"filter", required_argument, 0, 'f'},
		{"vio", required_argument, 0, 'u'},
		{"list", no_argument, 0, 'l'},
		{NULL,0,0,0}
	};
#endif

#if defined(USE_MERAM_RA) || defined(USE_MERAM_WB)
#define ALIGN16(_x)	(((_x) + 15) / 16 * 16)
#define ADJUST_PITCH(_p, _w)			\
	{					\
		(_p) = ((_w) - 1) | 1023;	\
		(_p) = (_p) | ((_p) >> 1);	\
		(_p) = (_p) | ((_p) >> 2);	\
		(_p) += 1;			\
	}

	unsigned long val;
	MERAM *meram = meram_open();
	MERAM_REG *regs = meram_lock_reg(meram);
	size_t sz;
	unsigned long mblock;
	ICB *icbr, *icbw;
#endif /* defined(USE_MERAM_RA) || defined(USE_MERAM_WB) */
	memset(src, 0, sizeof (src[0]) * 2);
	src[0].w = -1;
	src[0].h = -1;
	dst.w = -1;
	dst.h = -1;
	src[0].format = REN_UNKNOWN;
	dst.format = REN_UNKNOWN;
	src[0].bpitchy = src[0].bpitchc = src[0].bpitcha = 0;
	dst.bpitchy = dst.bpitchc = dst.bpitcha = 0;

	memcpy((void *)&src[1], (void *)&src[0], sizeof(src[0]));

	src[1].blend_out.x = 0;
	src[1].blend_out.y = 0;
	src[1].blend_out.w = 220;
	src[1].blend_out.h = 440;

	progname = argv[0];

	if (argc < 2) {
		usage (progname);
		return (1);
	}

	while (1) {
#ifdef HAVE_GETOPT_LONG
		c = getopt_long (argc, argv, optstring, long_options, NULL);
#else
		c = getopt (argc, argv, optstring);
#endif
		if (c == -1) break;
		if (c == ':') {
			usage (progname);
			goto exit_err;
		}

		switch (c) {
		case 'h': /* help */
			show_help = 1;
			break;
		case 'v': /* version */
			show_version = 1;
			break;
		case 'o': /* output */
			outfilename = optarg;
			break;
		case 'O': /* ovalery */
			infilename[1] = optarg;
			break;
		case 'c': /* input colorspace */
			set_colorspace (optarg, &src[0].format);
			break;
		case 's': /* input size */
			set_size (optarg, &src[0].w, &src[0].h);
			break;
		case 'C': /* output colorspace */
			set_colorspace (optarg, &dst.format);
			break;
		case 'S': /* output size */
			set_size (optarg, &dst.w, &dst.h);
			break;
		case 'f': /* filter mode */
			rotation = strtoul(optarg, NULL, 0);
			break;
		case 'l':
			show_list_vio = 1;
			break;
		case 'u':
			viodev = optarg;
			break;
		default:
			break;
		}
	}

	if (show_version) {
		printf ("%s version " VERSION "\n", progname);
	}

	if (show_help) {
		usage (progname);
	}
#if 0
	if (show_list_vio) {
		char **vio;
		int i, n;

		if (shvio_list_vio(&vio, &n) < 0) {
			printf ("Can't get a list of VIO available...\n");
		} else {
			for(i = 0; i < n; i++)
				printf("%s", vio[i]);
			printf("Total: %d VIOs available.\n", n);
		}
	}
#endif

	if (show_version || show_help || show_list_vio) {
		goto exit_ok;
	}

	if (optind >= argc) {
		usage (progname);
		goto exit_err;
	}

	infilename[0] = argv[optind++];

	if (optind < argc) {
		outfilename = argv[optind++];
	}

	printf ("Input file: %s\n", infilename[0]);
	if (infilename[1] != NULL)
		printf ("Overlay file: %s\n", infilename[1]);
	printf ("Output file: %s\n", outfilename);

	guess_colorspace (infilename[0], &src[0].format);
	if (infilename[1])
		guess_colorspace (infilename[1], &src[1].format);
	guess_colorspace (outfilename, &dst.format);
	/* If the output colorspace isn't given and can't be guessed, then default to
	 * the input colorspace (ie. no colorspace conversion) */
	if (dst.format == REN_UNKNOWN)
		dst.format = src[0].format;

	guess_size (infilename[0], src[0].format, &src[0].w, &src[0].h);
	if (rotation & 0xF) {
		/* Swap width/height for rotation */
		dst.w = src[0].h;
		dst.h = src[0].w;
	} else if (dst.w == -1 && dst.h == -1) {
		/* If the output size isn't given and can't be guessed, then default to
		 * the input size (ie. no rescaling) */
		dst.w = src[0].w;
		dst.h = src[0].h;
	}
	if (infilename[1])
		guess_size (infilename[1], src[1].format, &src[1].w, &src[1].h);

	/* Setup memory pitch */
	src[0].pitch = src[0].w;
	src[1].pitch = src[1].w;
	dst.pitch = dst.w;

	/* Check that all parameters are set */
	if (src[0].format == REN_UNKNOWN) {
		fprintf (stderr, "ERROR: Input colorspace unspecified\n");
		error = 1;
	}
	if (src[0].w == -1) {
		fprintf (stderr, "ERROR: Input width unspecified\n");
		error = 1;
	}
	if (src[0].h == -1) {
		fprintf (stderr, "ERROR: Input height unspecified\n");
		error = 1;
	}

	if (dst.format == REN_UNKNOWN) {
		fprintf (stderr, "ERROR: Output colorspace unspecified\n");
		error = 1;
	}
	if (dst.w == -1) {
		fprintf (stderr, "ERROR: Output width unspecified\n");
		error = 1;
	}
	if (dst.h == -1) {
		fprintf (stderr, "ERROR: Output height unspecified\n");
		error = 1;
	}

	if (error) goto exit_err;

	printf ("Input colorspace:\t%s\n", show_colorspace (src[0].format));
	printf ("Input size:\t\t%dx%d %s\n", src[0].w, src[0].h, show_size (src[0].w, src[0].h));
	printf ("Output colorspace:\t%s\n", show_colorspace (dst.format));
	printf ("Output size:\t\t%dx%d %s\n", dst.w, dst.h, show_size (dst.w, dst.h));
	printf ("Rotation:\t\t%s\n", show_rotation (rotation));

	input_size[0] = imgsize (src[0].format, src[0].w, src[0].h);
	if (infilename[1] != NULL)
		input_size[1] = imgsize (src[1].format, src[1].w, src[1].h);
	output_size = imgsize (dst.format, dst.w, dst.h);

	if (/*viodev*/ 1) {
		const char *blocks[2] = { "VPU5", NULL };
		uiomux = uiomux_open_named(blocks);
		uiores = 1 << 0;

	} else {
		uiomux = uiomux_open ();
		uiores = UIOMUX_SH_VEU;
	} 

	/* Set up memory buffers */
	src[0].py = inbuf[0] = uiomux_malloc (uiomux, uiores, input_size[0], 32);
	if (src[0].format == REN_RGB565) {
		src[0].pc = 0;
	} else if (src[0].format == REN_YV12) {
		src[0].pc2 = src[0].py + (src[0].w * src[0].h);	/* Cr(V) */
		src[0].pc = src[0].pc2 + (src[0].w * src[0].h) / 4;	/* Cb(U) */
	} else if (src[0].format == REN_YV16) {
		src[0].pc2 = src[0].py + (src[0].w * src[0].h);	/* Cr(V) */
		src[0].pc = src[0].pc2 + (src[0].w * src[0].h) / 2;	/* Cb(U) */
	} else {
		src[0].pc = src[0].py + (src[0].w * src[0].h);	/* CbCr(UV) */
	}

	if (infilename[1] != NULL) {
		src[1].py = inbuf[1] = uiomux_malloc (uiomux, uiores, input_size[1], 32);
		if (src[1].format == REN_RGB565) {
			src[1].pc = 0;
		} else if (src[1].format == REN_YV12) {
			src[1].pc2 = src[1].py + (src[1].w * src[1].h);	/* Cr(V) */
			src[1].pc = src[1].pc2 + (src[1].w * src[1].h) / 4;	/* Cb(U) */
		} else if (src[1].format == REN_YV16) {
			src[1].pc2 = src[1].py + (src[1].w * src[1].h);	/* Cr(V) */
			src[1].pc = src[1].pc2 + (src[1].w * src[1].h) / 2;	/* Cb(U) */
		} else {
			src[1].pc = src[1].py + (src[1].w * src[1].h);	/* CbCr(UV) */
		}
	}

	dst.py = outbuf = uiomux_malloc (uiomux, uiores, output_size, 32);
	if (dst.format == REN_RGB565) {
		dst.pc = 0;
	} else if (dst.format == REN_YV12) {
		dst.pc2 = dst.py + (dst.w * dst.h);	/* Cr(V) */
		dst.pc = dst.pc2 + (dst.w * dst.h) / 4;	/* Cb(U) */
	} else if (dst.format == REN_YV16) {
		dst.pc2 = dst.py + (dst.w * dst.h);	/* Cr(V) */
		dst.pc = dst.pc2 + (dst.w * dst.h) / 2;	/* Cb(U) */
	} else {
		dst.pc = dst.py + (dst.w * dst.h);	/* CbCr(UV) */
	}

#if defined(USE_MERAM_RA) || defined(USE_MERAM_WB)
#error aaaa
	meram_read_reg(meram, regs, MEVCR1, &val);
	val |= 1 << 29;		/* use 0xc0000000-0xdfffffff */
	meram_write_reg(meram, regs, MEVCR1, val);
	meram_unlock_reg(meram, regs);
#endif /* defined(USE_MERAM_RA) || defined(USE_MERAM_WB) */

#if defined(USE_MERAM_RA)
#error bbbb
	/* calcurate byte-pitch */
	src[0].bpitchy = size_y(src[0].format, src[0].pitch, 0);

	/* set up read-ahead cache for input */
	icbr = meram_lock_icb(meram, 0);
	val = (3 << 24) |		/* KRBNM: ((3+1) << 1) = 8 lines */
		((16 - 1) << 16);	/* BNM: 16 = KRBNM * 2 lines */
	ADJUST_PITCH(sz, src[0].bpitchy);
	sz *= 16;			/* 16 lines */
	if (src[0].format == REN_NV12) {
		val |= 2 << 12;	/* CPL: YCbCr420 */
		sz = sz * 3 / 2;
	} else if (src[0].format == REN_NV16) {
		val |= 3 << 12;	/* CPL: YCbCr422 */
		sz = sz * 2;
	}
	meram_write_icb(meram, icbr, MExxMCNF, val);

	sz = (sz + 1023) / 1024;
	mblock = meram_alloc_icb_memory(meram, icbr,
					    (sz == 0) ? 1 : sz);
	val = (1 << 28) |		/* BSZ: 2^1 line/block */
		(mblock << 16) |	/* MSAR */
		(3 << 9) |		/* WD: (constant) */
		(1 << 8) |		/* WS: (constant) */
		(1 << 3) |		/* CM: address mode 1 */
		1;			/* MD: read buffer mode */
	meram_write_icb(meram, icbr, MExxCTRL, val);

	val = ((src[0].h - 1) << 16) |	/* YSZM1 */
		(src[0].bpitchy - 1);	/* XSZM1 */
	meram_write_icb(meram, icbr, MExxBSIZE, val);
	val = ALIGN16(src[0].bpitchy);	/* SBSIZE: 16 bytes aligned */
	meram_write_icb(meram, icbr, MExxSBSIZE, val);

	ADJUST_PITCH(src[0].bpitchy, src[0].bpitchy);
	src[0].bpitchc = src[0].bpitcha = src[0].bpitchy;

	val = uiomux_all_virt_to_phys(src[0].py);
	meram_write_icb(meram, icbr, MExxSSARA, val);

	src[0].py = (void *)meram_get_icb_address(meram, icbr, 0);
	uiomux_register(src[0].py, (unsigned long)src[0].py, 8 << 20);
	if (is_ycbcr(src[0].format)) {
		val = uiomux_all_virt_to_phys(src[0].pc);
		meram_write_icb(meram, icbr, MExxSSARB, val);
		src[0].pc = (void *)meram_get_icb_address(meram, icbr, 1);
		uiomux_register(src[0].pc, (unsigned long)src[0].pc, 8 << 20);
	} else {
		meram_write_icb(meram, icbr, MExxSSARB, 0);
	}
#endif /* defined(USE_MERAM_RA) */

#if defined(USE_MERAM_WB)
	/* calcurate byte-pitch */
	dst.bpitchy = size_y(dst.format, dst.pitch, 0);

	/* set up write-back cache for input */
	icbw = meram_lock_icb(meram, 1);
	val = (3 << 28) |		/* KWBNM: ((3+1) << 1) = 8 lines */
		((16 - 1) << 16);	/* BNM: 16 = KWBNM * 2 lines */
	ADJUST_PITCH(sz, dst.bpitchy);
	sz *= 16;			/* 16 lines */
	if (dst.format == REN_NV12) {
		val |= 2 << 12;	/* CPL: YCbCr420 */
		sz = sz * 3 / 2;
	} else if (dst.format == REN_NV16) {
		val |= 3 << 12;	/* CPL: YCbCr422 */
		sz = sz * 2;
	}
	meram_write_icb(meram, icbw, MExxMCNF, val);
	sz = (sz + 1023) / 1024;
	mblock = meram_alloc_icb_memory(meram, icbw,
					(sz == 0) ? 1 : sz);
	val = (1 << 28) |		/* BSZ: 2^1 line/block */
		(mblock << 16) |	/* MSAR */
		(3 << 9) |		/* WD: (constant) */
		(1 << 8) |		/* WS: (constant) */
		(1 << 3) |		/* CM: address mode 1 */
		2;			/* MD: write buffer mode */
	meram_write_icb(meram, icbw, MExxCTRL, val);

	val = ((dst.h - 1) << 16) |	/* YSZM1 */
		(dst.bpitchy - 1);	/* XSZM1 */
	meram_write_icb(meram, icbw, MExxBSIZE, val);
	val = ALIGN16(dst.bpitchy);	/* SBSIZE: 16 bytes aligned */
	meram_write_icb(meram, icbw, MExxSBSIZE, val);

	ADJUST_PITCH(dst.bpitchy, dst.bpitchy);
	dst.bpitchc = dst.bpitcha = dst.bpitchy;

	val = uiomux_all_virt_to_phys(dst.py);
	meram_write_icb(meram, icbw, MExxSSARA, val);

	dst.py = (void *)meram_get_icb_address(meram, icbw, 0);
	uiomux_register(dst.py, (unsigned long)dst.py, 8 << 20);
	if (is_ycbcr(dst.format)) {
		val = uiomux_all_virt_to_phys(dst.pc);
		meram_write_icb(meram, icbw, MExxSSARB, val);
		dst.pc = (void *)meram_get_icb_address(meram, icbw, 1);
		uiomux_register(dst.pc, (unsigned long)dst.pc, 8 << 20);
	} else {
		meram_write_icb(meram, icbw, MExxSSARB, 0);
	}
#endif /* defined(USE_MERAM_WB) */

	if (strcmp (infilename[0], "-") == 0) {
		infile[0] = stdin;
	} else {
		infile[0] = fopen (infilename[0], "rb");
		if (infile[0] == NULL) {
			fprintf (stderr, "%s: unable to open input file %s\n",
				 progname, infilename[0]);
			goto exit_err;
		}
	}

	if (infilename[1] != NULL) {
		infile[1] = fopen (infilename[1], "rb");
		if (infile[1] == NULL) {
			fprintf (stderr, "%s: unable to open input file %s\n",
				 progname, infilename[1]);
			goto exit_err;
		}
	}

	if (outfilename != NULL) {
		if (strcmp (outfilename, "-") == 0) {
			outfile = stdout;
		} else {
			outfile = fopen (outfilename, "wb");
			if (outfile == NULL) {
				fprintf (stderr, "%s: unable to open output file %s\n",
					 progname, outfilename);
				goto exit_err;
			}
		}
	}

	if (!viodev)
		vio = shvio_open();
	else
		vio = shvio_open_named(viodev);

	if (vio == 0) {
		fprintf (stderr, "Error opening VIO\n");
		goto exit_err;
	}

	while (1) {
#ifdef DEBUG
		fprintf (stderr, "%s: Converting frame %d\n", progname, frameno);
#endif

		/* Read input */
		if ((nread = fread (inbuf[0], 1, input_size[0], infile[0])) != input_size[0]) {
			if (nread == 0 && feof (infile[0])) {
				break;
			} else {
				fprintf (stderr, "%p, %s: errors reading input file %s %d %d %d\n", inbuf[0],
					 progname, infilename[0], nread, input_size[0], ferror(infile[0]));
			}
		}
#if 1
		if (infilename[1] != NULL) {
			if ((nread = fread (inbuf[1], 1, input_size[1], infile[1])) != input_size[1]) {
				if (nread == 0 && feof (infile[1])) {
					break;
				} else {
					fprintf (stderr, "%s: error reading input file %s\n",
						 progname, infilename[1]);
				}
			}

			printf("invoke shvio_setup_blend()...\n");
			ret = shvio_setup_blend(vio, NULL, srclist, 2, &dst);
			shvio_start(vio);
			printf("shvio_start_blend() = %d\n", ret);
			ret = shvio_wait(vio);
		} else {
#endif
			if (rotation) {
				ret = shvio_rotate(vio, &src[0], &dst, rotation);
			} else {
				ret = shvio_resize(vio, &src[0], &dst);
			}
		}

#if defined(USE_MERAM_WB)
		meram_read_icb(meram, icbw, MExxCTRL, &val);
		val |= 1 << 5;	/* WF: flush data */
		meram_write_icb(meram, icbw, MExxCTRL, val);
#endif
#if defined(USE_MERAM_RA)
		meram_read_icb(meram, icbr, MExxCTRL, &val);
		val |= 1 << 4;	/* RF: flush data */
		meram_write_icb(meram, icbr, MExxCTRL, val);
#endif

		/* Write output */
		if (outfile && fwrite (outbuf, 1, output_size, outfile) != output_size) {
				fprintf (stderr, "%s: error writing input file %s\n",
					 progname, outfilename);
		}

		frameno++;
	}

	shvio_close (vio);

#if defined(USE_MERAM_RA)
	/* finialize the read-ahead cache */
	uiomux_unregister(src[0].py);
	if (is_ycbcr(src[0].format))
		uiomux_unregister(src[0].pc);
	meram_free_icb_memory(meram, icbr);
	meram_unlock_icb(meram, icbr);
#endif
#if defined(USE_MERAM_WB)
	/* finialize the write-back cache */
	uiomux_unregister(dst.py);
	if (is_ycbcr(dst.format))
		uiomux_unregister(dst.pc);
	meram_free_icb_memory(meram, icbw);
	meram_unlock_icb(meram, icbw);
#endif
#if defined(USE_MERAM_RA) || defined(USE_MERAM_WB)
	meram_close(meram);
#endif

	uiomux_free (uiomux, uiores, src[0].py, input_size[0]);
	if (infilename[1] != NULL)
		uiomux_free (uiomux, uiores, src[1].py, input_size[1]);
	uiomux_free (uiomux, uiores, dst.py, output_size);
	uiomux_close (uiomux);

	if (infile[0] != stdin) fclose (infile[0]);
	if (infilename[1] != NULL)
		fclose (infile[1]);

	if (outfile == stdout) {
		fflush (stdout);
	} else if (outfile) {
		fclose (outfile);
	}

	printf ("Frames:\t\t%d\n", frameno);

exit_ok:
	exit (0);

exit_err:
	exit (1);
}