[FFmpeg-devel] Hardware CSC conversion segfault

Reimar Döffinger Reimar.Doeffinger at gmx.de
Sat Jul 13 01:58:54 CEST 2013


On 13.07.2013, at 01:31, Michael Niedermayer <michaelni at gmx.at> wrote:
> On Fri, Jul 12, 2013 at 10:09:55PM +0000, Umar Qureshey wrote:
>> 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?
> 
> discontinuous

While you're certainly right in the general case (and since memcpy is used anyway in ths case there is no need to add complexity or assumptions), if making use of DR1 an application is free to provide a continuous buffer to the decoder.


More information about the ffmpeg-devel mailing list