[FFmpeg-devel] Hardware CSC conversion segfault
Umar Qureshey
umar at janteq.com
Sat Jul 13 00:09:55 CEST 2013
Hi,
I am a newbie in the ffmpeg world. I am attempting to offload the colorspace conversion to hardware in the i.MX6 SoC. So far I have the following:
static int imx6_yuv420_to_rgb565le(SwsContext *c, uint8_t *src[], int srcStride[],
int srcSliceY, int srcSliceH,
uint8_t *dst[], int dstStride[])
{
int isize, osize, ret = 0, i;
void *inbuf=NULL, *outbuf=NULL;
//Clear task struct.
memset(&c->task, 0, sizeof(c->task));
//Open the Image Processing Unit.
c->fd_ipu = open("/dev/mxc_ipu", O_RDWR, 0);
if (c->fd_ipu < 0)
{
av_log(c, AV_LOG_ERROR, "open ipu dev fail\n");
return 0;
}
//1) Allocate physical memory to for image processing unit.
//1a) Calculate size of input/output buffers.
INPUT_WIDTH(c) = c->srcW;
OUTPUT_WIDTH(c) = c->dstW;
INPUT_HEIGHT(c) = c->srcH;
OUTPUT_HEIGHT(c) = c->dstH;
INPUT_FORMAT(c) = IPU_PIX_FMT_YUV420P;
OUTPUT_FORMAT(c) = IPU_PIX_FMT_RGB565;
OUTPUT_ROTATION(c) = 0;
isize = INPUT_PADDR(c) = (INPUT_WIDTH(c) * INPUT_HEIGHT(c) * fmt_to_bpp(INPUT_FORMAT(c))/8);
osize = OUTPUT_PADDR(c) = (OUTPUT_WIDTH(c) * OUTPUT_HEIGHT(c) * fmt_to_bpp(OUTPUT_FORMAT(c))/8);
//1b) Allocate contiguous physical memory for input/output image.
// input.paddr and output.paddr contains the amount needed.
// These values will be replaced with physical address on success.
ret = ioctl(c->fd_ipu, IPU_ALLOC, &INPUT_PADDR(c));
if (ret < 0)
{
av_log(c, AV_LOG_ERROR, "physical memory allocation of input buffer failed: (errno = %d)\n", errno);
goto done;
}
ret = ioctl(c->fd_ipu, IPU_ALLOC, &OUTPUT_PADDR(c));
if (ret < 0)
{
av_log(c, AV_LOG_ERROR, "physical memory allocation of output buffer failed: (errno = %d)\n", errno);
goto done;
}
//2) Get the virtual addresses for the physical input/output buffers so we can access them from userland here.
inbuf = mmap(0, isize, PROT_READ | PROT_WRITE, MAP_SHARED, c->fd_ipu, INPUT_PADDR(c));
if (!inbuf)
{
av_log(c, AV_LOG_ERROR, "inbuf mmap failed\n");
goto done;
}
outbuf = mmap(0, osize, PROT_READ | PROT_WRITE, MAP_SHARED, c->fd_ipu, OUTPUT_PADDR(c));
if (!outbuf)
{
av_log(c, AV_LOG_ERROR, "outbuf mmap failed\n");
goto done;
}
//3) Copy the raw image to the input IPU buffer.
memcpy(inbuf, src[0], isize); //<-- SEG FAULT at memcpy on the second invocation of this function.
//4) Perform the colorspace conversion.
ret = ioctl(c->fd_ipu, IPU_QUEUE_TASK, &c->task);
if (ret < 0)
{
av_log(c, AV_LOG_ERROR, "ioct IPU_QUEUE_TASK fail %x\n", ret);
goto done;
}
//5) Copy converted buffer.
memcpy(dst[0], outbuf, osize);
done:
if (outbuf)
munmap(outbuf, osize);
if (OUTPUT_PADDR(c))
ioctl(c->fd_ipu, IPU_FREE, &OUTPUT_PADDR(c));
if (inbuf)
munmap(inbuf, isize);
if (INPUT_PADDR(c))
ioctl(c->fd_ipu, IPU_FREE, &INPUT_PADDR(c));
if (c->fd_ipu)
close(c->fd_ipu);
return srcSliceH;
}
I am getting a seg fault as indicated above when copying from the src[0] to inbuf.
My question is does src hold pointer to one contiguous memory buffer holding the different planes of YUV data or can they discontinuous?
The hardware simply takes a contiguous memory buffer of a specified data format (YUV420P in this case) and outputs a buffer of a specified data format (RGB565LE in this case).
Any tips appreciated.
Thx
More information about the ffmpeg-devel
mailing list