コード例 #1
0
ファイル: video_mfc.cpp プロジェクト: HarveyLiuFly/rebvo
int EncoderMFC::Initialize(int width, int height,int codec,float rate,int bitrate,int in_bufs,int out_bufs, int stream_b_size){

    if(state!=MFC_ST_OPEN)
        return -1;

    if(SetFormat(width,height)<0)
        return -1;

    if(SetCodec(codec,stream_b_size)<0)
        return -1;

    SetRate(rate);

    if(bitrate>0)
        SetBitRate(bitrate);

    if(InitBuffers(DIR_IN,in_bufs)<0)
        return -1;

    if(InitBuffers(DIR_OUT,out_bufs)<0)
        return -1;


    for (int bi=0;bi<out_bufs;bi++){


        struct v4l2_buffer buf;
        struct v4l2_plane planes[MFC_MAX_PLANES];

        buf.type = io_dir_to_type(DIR_OUT);
        buf.memory = V4L2_MEMORY_MMAP;
        buf.m.planes = planes;
        buf.length = NPPBuf[DIR_OUT];

        buf.index=bi;


        for (u_int i = 0; i < NPPBuf[DIR_OUT]; i++){
            planes[i].length=PlanesLen[DIR_OUT][i];
            planes[i].bytesused=0;
            planes[i].m.userptr=(u_long)BufAddr[DIR_OUT][bi][i];
        }

        int ret = ioctl(fd, VIDIOC_QBUF, &buf);
        if (ret != 0) {
            printf("\nEncoderMFC: Init, Queue buffer %d error! %s\n",buf.index,strerror(errno));
        }

    }

    BufInx[DIR_OUT]=0;

    state=MFC_ST_OK;
    return 0;

}
コード例 #2
0
ファイル: video_mfc.cpp プロジェクト: HarveyLiuFly/rebvo
int EncoderMFC::PopFrame(char *stream_buf,int b_size)
{
    struct v4l2_buffer buf;
    struct v4l2_plane planes[NPPBuf[DIR_OUT]];
    int ret;

    memzero(buf);

    buf.type = io_dir_to_type(DIR_OUT);
    buf.memory = V4L2_MEMORY_MMAP;
    buf.m.planes = planes;
    buf.length = NPPBuf[DIR_OUT];

    buf.index=BufInx[DIR_OUT];


    ret = ioctl(fd, VIDIOC_DQBUF, &buf);
    if (ret != 0) {
        printf("\nEncoderMFC: Pop, Dequeue buffer %d error, %s!\n",buf.index,strerror(errno));
        return -1;
    }



    BufInx[DIR_OUT]=buf.index;

    if(BufInx[DIR_OUT]>=NBufs[DIR_OUT]){
        printf("\nEncoderMFC: Pop, Index error!\n");
        return -1;
    }


    if(buf.m.planes[0].bytesused>b_size){
        printf("\nEncoderMFC: Pop, Buffer %d overrun %d error!",buf.index,buf.m.planes[0].bytesused);
    }else{
        b_size=buf.m.planes[0].bytesused;
    }

    memcpy(stream_buf,BufAddr[DIR_OUT][buf.index][0],b_size);

    //printf("\nEncoderMFC: Enc frame %d,%d\n",buf.m.planes[0].bytesused,BufInx[DIR_OUT]);

    ret = ioctl(fd, VIDIOC_QBUF, &buf);
    if (ret != 0) {
        printf("\nEncoderMFC: Pop, Queue buffer %d error! %s\n",BufInx[DIR_OUT],strerror(errno));
        return -1;
    }

    //BufInx[DIR_OUT]++;

    return b_size;
}
コード例 #3
0
ファイル: mfc.c プロジェクト: ChangerR/learn
int mfc_set_codec(struct io_dev *dev, enum io_dir dir, int codec)
{
	struct v4l2_format fmt;
	int ret;

	memzero(fmt);
	fmt.type = io_dir_to_type(dir);
	fmt.fmt.pix_mp.pixelformat = codec;
	fmt.fmt.pix_mp.plane_fmt[0].sizeimage = MAX_STREAM_SIZE;

	ret = ioctl(dev->fd, VIDIOC_S_FMT, &fmt);

	return ret;
}
コード例 #4
0
ファイル: video_mfc.cpp プロジェクト: HarveyLiuFly/rebvo
int EncoderMFC::SetFormat(int width, int height)
{
    v4l2_format fmt;
    int ret;

    this->width=width;
    this->height=height;

    memzero(fmt);
    fmt.type = io_dir_to_type(DIR_IN);
    fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M;
    fmt.fmt.pix_mp.width = width;
    fmt.fmt.pix_mp.height = height;


    BytesPerLine=align(width, 128);

    fmt.fmt.pix_mp.num_planes = 2;
    fmt.fmt.pix_mp.plane_fmt[0].bytesperline = BytesPerLine;
    fmt.fmt.pix_mp.plane_fmt[0].sizeimage = align(BytesPerLine * height, 2048);
    fmt.fmt.pix_mp.plane_fmt[1].bytesperline = BytesPerLine;
    fmt.fmt.pix_mp.plane_fmt[1].sizeimage = align(BytesPerLine * (height / 2),2048);


    printf("\nEncoderMFC: bpl = %d,%d \n",BytesPerLine,fmt.fmt.pix_mp.plane_fmt[0].sizeimage);

    ret = ioctl(fd, VIDIOC_S_FMT, &fmt);
    if (ret != 0){
        printf("\nEncoderMFC: Cannot set format!\n");
        state=MFC_ST_ERROR;
        return -1;
    }

    ret = ioctl(fd, VIDIOC_G_FMT, &fmt);
    if (ret != 0){
        printf("\nEncoderMFC: Cannot check format!\n");
        state=MFC_ST_ERROR;
        return -1;
    }

    BytesPerLine=fmt.fmt.pix_mp.plane_fmt[0].bytesperline;
    printf("\nEncoderMFC: get bpl = %d,%d \n",BytesPerLine,fmt.fmt.pix_mp.plane_fmt[1].bytesperline);
    return ret;
}
コード例 #5
0
ファイル: video_mfc.cpp プロジェクト: HarveyLiuFly/rebvo
int EncoderMFC::SetCodec(int codec,int stream_b_size)
{
    v4l2_format fmt;
    int ret;

    memzero(fmt);
    fmt.type = io_dir_to_type(DIR_OUT);
    fmt.fmt.pix_mp.pixelformat = codec;
    fmt.fmt.pix_mp.plane_fmt[0].sizeimage = stream_b_size;

    ret = ioctl(fd, VIDIOC_S_FMT, &fmt);

    if (ret != 0){
        printf("\nEncoderMFC: Cannot set codec!\n");
        state=MFC_ST_ERROR;
    }

    return ret;
}
コード例 #6
0
ファイル: video_mfc.cpp プロジェクト: HarveyLiuFly/rebvo
int EncoderMFC::ReqBufs(MFC_io_dir dir, int nbuf)
{
    int ret;
    struct v4l2_requestbuffers reqbuf;

    memzero(reqbuf);
    reqbuf.count = nbuf;
    reqbuf.type = io_dir_to_type(dir);
    reqbuf.memory = V4L2_MEMORY_MMAP;

    ret = ioctl(fd, VIDIOC_REQBUFS, &reqbuf);
    if (ret != 0) {
        printf("\nEncoderMFC: Failed to request %d buffers for %s device\n", nbuf,
               dir==DIR_IN?"Input":"Output");
        state=MFC_ST_ERROR;
        return -1;
    }

    printf("\nEncoderMFC: Succesfully requested %d buffers for %s device\n", nbuf,
           dir==DIR_IN?"Input":"Output");

    return reqbuf.count;
}
コード例 #7
0
ファイル: mfc.c プロジェクト: ChangerR/learn
/* set format with proper alignement */
int mfc_set_fmt(struct io_dev *dev, enum io_dir dir, int width, int height)
{
	struct v4l2_format fmt;
	int ret;

	memzero(fmt);
	fmt.type = io_dir_to_type(dir);
	fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12M;
	fmt.fmt.pix_mp.width = width;
	fmt.fmt.pix_mp.height = height;

	fmt.fmt.pix_mp.num_planes = 2;
	fmt.fmt.pix_mp.plane_fmt[0].bytesperline = align(width, 128);
	fmt.fmt.pix_mp.plane_fmt[0].sizeimage = align(width * height, 2048);
	fmt.fmt.pix_mp.plane_fmt[1].bytesperline = align(width, 128);
	fmt.fmt.pix_mp.plane_fmt[1].sizeimage = align(width * (height / 2),
									2048);

	ret = ioctl(dev->fd, VIDIOC_S_FMT, &fmt);
	if (ret != 0)
		err("Cannot set format on %d:%d", dev->fd, dir);

	return ret;
}
コード例 #8
0
ファイル: video_mfc.cpp プロジェクト: HarveyLiuFly/rebvo
/* enqueue buffer, start stream when needed */
int EncoderMFC::PushFrame(union RGB24Pixel *data)
{
    struct v4l2_buffer buf;
    struct v4l2_plane planes[MFC_MAX_PLANES];
    int ret;

    memzero(buf);

    buf.index=(BufInx[DIR_IN]);
    buf.type = io_dir_to_type(DIR_IN);
    buf.memory = V4L2_MEMORY_MMAP;
    buf.m.planes = planes;
    buf.length = NPPBuf[DIR_IN];




    float Y,Cr,Cb;

    for(int y=0,i=0;y<height;y++,i+=BytesPerLine-width){
        for(int x=0;x<width;x++,i++){

            Y=(0.299 * (float)data[i].pix.r) + (0.587 * (float)data[i].pix.g) + (0.114 * (float)data[i].pix.b);

            ((unsigned char *)(BufAddr[DIR_IN][buf.index][0]))[i]  = Y;

        }
    }


    planes[0].bytesused=height*BytesPerLine;
    planes[0].length = PlanesLen[DIR_IN][0];
    planes[0].m.userptr = (u_long)BufAddr [DIR_IN][buf.index][0];


    for(int y=0,i=0,j=0;y<height/2;y++,i+=width,j+=BytesPerLine-width){
        for(int x=0;x<width;x+=2,i+=2,j+=2){
            float r,g,b;

            r=(data[i].pix.r+data[i+1].pix.r+data[i+width].pix.r+data[i+width+1].pix.r)/4.0;
            g=(data[i].pix.g+data[i+1].pix.g+data[i+width].pix.g+data[i+width+1].pix.g)/4.0;
            b=(data[i].pix.b+data[i+1].pix.b+data[i+width].pix.b+data[i+width+1].pix.b)/4.0;

            Cr = (0.5 * r) - (0.4186 * g) - (0.08131 * b);
            Cb =-(0.1687 * r) - (0.3312 * g) + (0.5 * b);

            Cr+=128.0;
            Cb+=128.0;

            ((unsigned char *)(BufAddr[DIR_IN][buf.index][1]))[j+1]  = Cr;
            ((unsigned char *)(BufAddr[DIR_IN][buf.index][1]))[j]  = Cb;

        }
    }


    planes[1].bytesused=height*BytesPerLine/2;
    planes[1].length = PlanesLen[DIR_IN][1];
    planes[1].m.userptr = (u_long)BufAddr [DIR_IN][buf.index][1];




    ret = ioctl(fd, VIDIOC_QBUF, &buf);
    if (ret != 0) {
        printf("\nEncoderMFC: Push, Queue buffer %d error!\n",BufInx[DIR_IN]);
    }

    if(state==MFC_ST_OK)
        StreamOn(true);

    if((++(BufInx[DIR_IN]))>=NBufs[DIR_IN]){
        BufInx[DIR_IN]=0;
    }

    buf.index=(BufInx[DIR_IN]);
    buf.type = io_dir_to_type(DIR_IN);
    buf.memory = V4L2_MEMORY_MMAP;
    buf.m.planes = planes;
    buf.length = NPPBuf[DIR_IN];

    ret = ioctl(fd, VIDIOC_DQBUF, &buf);
    if (ret != 0) {
        printf("\nEncoderMFC: Push, Dequeue buffer %d error! %s\n",BufInx[DIR_IN],strerror(errno));
        return -1;
    }

    return 0;
}
コード例 #9
0
ファイル: video_mfc.cpp プロジェクト: HarveyLiuFly/rebvo
int  EncoderMFC::InitBuffers(MFC_io_dir dir,int nbuf)
{
    struct v4l2_buffer qbuf;
    int ret;

    v4l2_plane planes[MFC_MAX_PLANES];


    if (ReqBufs(dir,nbuf) < 0)
        return -1;

    NBufs[dir]=nbuf;

    BufAddr[dir] = new void**[nbuf];


    memzero(qbuf);
    qbuf.type = io_dir_to_type(dir);
    qbuf.memory = V4L2_MEMORY_MMAP;
    qbuf.m.planes = planes;
    qbuf.length = MFC_MAX_PLANES;

    for (int n = 0; n < nbuf; n++) {
        qbuf.index = n;

        ret = ioctl(fd, VIDIOC_QUERYBUF, &qbuf);
        if (ret != 0) {
            printf("\nEncoderMFC: QUERYBUF failed\n");
            return -1;
        }

        if (n == 0) {
            int i;
            for (i = 0; i < qbuf.length; ++i)
                if (qbuf.m.planes[i].length == 0)
                    break;
            NPPBuf[dir] = i;
            PlanesLen[dir]=new int[i];


            for (i = 0; i < NPPBuf[dir]; ++i)
                PlanesLen[dir][i] = qbuf.m.planes[i].length;


        }

        BufAddr[dir][n] = new void*[NPPBuf[dir]];

        for (int i = 0; i < NPPBuf[dir]; ++i) {
            BufAddr[dir][n][i] = (void *)mmap(NULL,qbuf.m.planes[i].length, PROT_READ | PROT_WRITE, MAP_SHARED, fd,\
                        qbuf.m.planes[i].m.mem_offset);
            if (BufAddr[dir][n][i]  == MAP_FAILED) {
                printf("\nEncoderMFC: Failed mmap buffer %d for plane %d!\n", n,i);
                state=MFC_ST_ERROR;
                return -1;
            }
        }
        /*ret = in->ops->enq_buf(in, DIR_OUT, n);
        if (ret < 0)
            return -1;*/
    }


    printf(" \nMFC Log: Dir = %d NB = %d \n",dir,NBufs[dir]);

    for(int i=0;i<NBufs[dir];i++){

        printf("\nNPP = %d ",NPPBuf[dir]);

        for(int j=0;j<NPPBuf[dir];j++)
            printf(" PL = %d A = %lx ",PlanesLen[dir][j],(unsigned long)BufAddr[dir][i][j]);

    }

    printf("\n");

    BufInx[dir]=0;

    return 0;
}