This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Linux/AM5728: 8-bit raw encode issue

Part Number: AM5728


Tool/software: Linux

Hi all,

we use 8-bit raw  video input ,  connect it with vip1 vin1a of am5728.

when i use gst  cmd   "gst-launch-1.0 -e v4l2src device=/dev/video1 ! 'video/x-raw,format=(string)NV12, width=(int)640, height=(int)480, framerate=(fraction)30/1' ! ducatih264enc ! filesink location=test.h264"

the video  image is not correct .

my sdk  is  ti-processor-sdk-linux-am57xx-evm-03.00.00.04

Any solution for this?

Regards

  • Hello,

    What you mean is not correct, could you link a image?
    Do you observe the same issue with the latest PSDK?
    Could you try to add ... ! vpe num-input-buffers=8 ! .... element before the encoder?
    I would recommend you to add h264parse element after the encoder also because there is possibilities the saved video to be corrupted even if in the pipeline there is -e option.
    When you try with yavta do you see it correct?

    BR
    Margarita
  • hi Margarita,


    i have not used the latest PSDK.

    Under your suggestion, i use

    " gst-launch-1.0 -e v4l2src device=/dev/video1 ! 'video/x-raw,format=(string)NV12, width=(int)640, height=(int)480, framerate=(fraction)30/1' ! vpe num-input-buffers=8 ! 'video/x-raw,format=(string)NV12, width=(int)640, height=(int)480, framerate=(fraction)30/1' ! ducatih264enc! h264parse ! filesink location=youjia.h264 "

    but  video image is stll not corrcet,  As shown

    i have not use yata but i write a test program to get image  from V4L2 ,The image is the same as  show.

    this is  my test.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <sys/ioctl.h>
    #include <sys/mman.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <linux/videodev2.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    
    #include <time.h>
    
    struct v4l2_user_buffer {
        int index;
        int length;
        char *addr;
    };
    struct v4l2_user_buffer user_buffer[5];
    
    int main(void)
    {
        int fp;
        int i = 0;
        int status = 0;
        int v4l2_fd = 0;
        struct v4l2_format format;
        struct v4l2_requestbuffers requestbuffers;
        struct v4l2_buffer buffer;
    
        struct timeval tpstart;
        unsigned int timems =0, lasttime = 0;
    
        fp = open("frame.yuv", O_RDWR | O_CREAT | O_TRUNC);
        if (fp < 0) {
            printf("%d: fopen error\n", __LINE__);
            return -1;
        }
    
        v4l2_fd = open("/dev/video1", O_RDWR);
        if (v4l2_fd == -1) {
            printf("%d: open error\n", __LINE__);
            return -1;
        }
    
        memset(&format, 0x00, sizeof(struct v4l2_format));
        format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        format.fmt.pix.width = 640;
        format.fmt.pix.height = 480;
        format.fmt.pix.field = V4L2_FIELD_NONE;
        format.fmt.pix.pixelformat = V4L2_PIX_FMT_NV12;
        status = ioctl(v4l2_fd, VIDIOC_S_FMT, &format);
        if (status < 0) {
            printf("%d: ioctl VIDIOC_S_FMT error\n", __LINE__);
            return -1;
        }
    
        memset(&format, 0x00, sizeof(struct v4l2_format));
        format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        status = ioctl(v4l2_fd, VIDIOC_G_FMT, &format);
        if (status < 0) {
            printf("%d: ioctl VIDIOC_G_FMT error\n", __LINE__);
            return -1;
        }
        printf("format width: [%d]\n", format.fmt.pix.width);
        printf("format height: [%d]\n", format.fmt.pix.height);
    
        memset(&requestbuffers, 0x00, sizeof(struct v4l2_requestbuffers));
        requestbuffers.count = 2;// max is 5
        requestbuffers.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        requestbuffers.memory = V4L2_MEMORY_MMAP;
        status = ioctl(v4l2_fd, VIDIOC_REQBUFS, &requestbuffers);
        if (status < 0) {
            printf("%d: ioctl VIDIOC_REQBUFS error\n", __LINE__);
            return -1;
        }
    
    
        for (i = 0; i < requestbuffers.count ; i++) {
            buffer.index = i;
            buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
            buffer.memory = V4L2_MEMORY_MMAP;
            status = ioctl(v4l2_fd, VIDIOC_QUERYBUF, &buffer);
            if (status < 0) {
                printf("%d: ioctl VIDIOC_QUERYBUF error\n", __LINE__);
                return -1;
            }
    
            user_buffer[i].index = i;
            user_buffer[i].length = buffer.length;
            user_buffer[i].addr = (char *)mmap(NULL,
                    buffer.length,
                    PROT_READ | PROT_WRITE,
                    MAP_SHARED,
                    v4l2_fd,
                    buffer.m.offset);
            if (user_buffer[i].addr == MAP_FAILED) {
                printf("%d: mmap error\n", __LINE__);
                return -1;
            }
            printf("user_buffer index: [%d]\n", user_buffer[i].index);
            printf("user_buffer length: [%d]\n", user_buffer[i].length);
            printf("user_buffer addr: [%p]\n", user_buffer[i].addr);
        }
    
        for (i = 0; i < requestbuffers.count ; i ++) {
            buffer.index = i;
            buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
            buffer.memory = V4L2_MEMORY_MMAP;
            status = ioctl(v4l2_fd, VIDIOC_QBUF, &buffer);
            if (status < 0) {
                printf("%d: ioctl VIDIOC_QBUF error\n", __LINE__);
                return -1;
            }
        }
    
        int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        status = ioctl(v4l2_fd, VIDIOC_STREAMON, &type);
        if (status < 0) {
            printf("%d: ioctl VIDIOC_STREAMOFF error\n", __LINE__);
            return -1;
        }
    
        for (i = 0 ; i < 10; i++) {
    
            buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
            buffer.memory = V4L2_MEMORY_MMAP;
            status = ioctl(v4l2_fd, VIDIOC_DQBUF, &buffer);
            if (status < 0) {
                printf("%d: ioctl VIDIOC_DQBUF error\n", __LINE__);
                return -1;
            }
    
    #if 1
            printf("buf index  %d len %d get frame %d :",buffer.index ,user_buffer[buffer.index].length ,i);
            gettimeofday(&tpstart,NULL);
            timems = (tpstart.tv_sec * 1000) + (tpstart.tv_usec / 1000) ;
            printf("len %d time %u user time %u \n",user_buffer[buffer.index].length, timems ,timems - lasttime);
            lasttime = timems;
    #endif
            write(fp,user_buffer[buffer.index].addr,user_buffer[buffer.index].length);
    
            buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
            buffer.memory = V4L2_MEMORY_MMAP;
            buffer.m.offset = (unsigned long)user_buffer[buffer.index].addr;
            status = ioctl(v4l2_fd, VIDIOC_QBUF, &buffer);
            if (status < 0) {
                printf("%d: ioctl VIDIOC_DQBUF error\n", __LINE__);
                return -1;
            }
    
        }
    
        type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        status = ioctl(v4l2_fd, VIDIOC_STREAMOFF, &type);
        if (status < 0) {
            printf("%d: ioctl VIDIOC_STREAMOFF error\n", __LINE__);
            return -1;
        }
    
        close (v4l2_fd);
        close(fp);
        return status;
    }
    
     when i input YUYV 16bit to vip i can use

    "gst-launch-1.0 -e v4l2src device=/dev/video1 ! 'video/x-raw,format=(string)NV12, width=(int)640, height=(int)480, framerate=(fraction)30/1' !  ducatih264enc! ! filesink location=youjia.h264"  get the correct image. 

    when i input raw  8bit Grayscale to  vip , am5728 encode still  use "format=(string)NV12,"? or need  other format

  • Hello,

    Are you sure the format is correct?

    BR
    Margarita
  • hi Margarita,
    What format does the vip need in raw mode ?

    BR
    Jiffy

  • Hello,

    Please check this guide:
    processors.wiki.ti.com/.../Linux_Core_VIP_User's_Guide
    You could also try this pipeline:
    gst-launch-1.0 -e v4l2src device=/dev/video1 ! 'video/x-raw,format=(string)NV12, width=(int)640, height=(int)480, framerate=(fraction)30/1' ! filesink location=x.yuv to check is it the output of v4l2src element is correct.
    This issue doesn't seems to me as encoder issue.


    BR
    Margarita
  • hi Margarita,

    ok, thanks a lot.

    I find in this guide:

    Two separate 24-bit video ports for parallel RGB/YUV/RAW (or BT656/1120) data, up to 165 MHz

    The meaning of this is that RAW mode need input BT656 or BT1120 ?

    BR
    Jiffy

  • In RAW capture mode, VIP is a interface to just bring the data as is, no further processing is done inside the VIP module. Now, encoder needs NV12 (separate Y and UV interleaved buffer) data format to encode. When you are capturing in RAW mode, what's the data format used by sensor to stream the data? If it is sending data in RAW Bayer pattern, then the data needs to be converted to NV12 format first before sending it to IVA encoder. AM5728 doesn't have any hardware accelerator like ISP to do the RAW Bayer to YUV conversion. This will need to be done in software.