[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