⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 video.c

📁 基于嵌入式linux的程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * video.c * * ============================================================================ * Copyright (c) Texas Instruments Inc 2005 * * Use of this software is controlled by the terms and conditions found in the * license agreement under which this software has been supplied or provided. * ============================================================================ *//* Standard Linux headers */#include <stdio.h>#include <fcntl.h>#include <errno.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <pthread.h>#include <sys/mman.h>#include <sys/ioctl.h>#include <asm/types.h>#include <linux/videodev2.h>/* Davinci specific kernel headers */#include <media/davinci_vpfe.h>#include <media/tvp5146.h>/* Codec Engine headers */#include <xdc/std.h>#include <ti/sdo/ce/Engine.h>#include <ti/sdo/ce/osal/Memory.h>#include <ti/sdo/ce/video/videnc.h>/* Demo headers */#include <rendezvous.h>#include <fifoutil.h>#include "encode.h"#include "video.h"#include "display.h"#include "writer.h"/* Macro for clearing structures */#define CLEAR(x) memset (&(x), 0, sizeof (x))/* The levels of initialization */#define INFIFODISPLAYOPENED      0x1#define OUTFIFODISPLAYOPENED     0x2#define DISPLAYTHREADCREATED     0x4#define INFIFOWRITEROPENED       0x8#define OUTFIFOWRITEROPENED      0x10#define WRITERTHREADCREATED      0x20#define CAPTUREDEVICEINITIALIZED 0x40#define ENGINEOPENED             0x80#define VIDEOENCODERCREATED      0x100#define ENCODEDBUFFERSALLOCATED   0x200/* Black color in UYVY format */#define UYVY_BLACK               0x10801080/* Triple buffering for the capture driver */#define NUM_BUFS                 3/* Number of buffers for the writer thread */#define IO_BUFFERS               2/* Describes a capture frame buffer */typedef struct VideoBuffer {    void   *start;    size_t  length;} VideoBuffer;char *videoEncodeAlgNames[NUM_VIDEO_ENCODERS] = {    "mpeg4enc",    "h264enc"};/* Local function prototypes */static int  videoEncodeAlgCreate(Engine_Handle hEngine,                                 VIDENC_Handle *hEncodePtr,                                 VideoEncoder videoEncoder,                                 int width, int height, int bitrate);static int encodeVideoBuffer(VIDENC_Handle hEncode, char *inBuf, int inBufSize,                             char *outBuf, int *outBufSize);static int  initCaptureDevice(VideoBuffer **vidBufsPtr, int *numVidBufsPtr,                              int svideoInput, int captureWidth,                              int captureHeight);static void cleanupCaptureDevice(int fd, VideoBuffer *vidBufs, int numVidBufs);/****************************************************************************** * videoEncodeAlgCreate ******************************************************************************/static int  videoEncodeAlgCreate(Engine_Handle hEngine,                                 VIDENC_Handle *hEncodePtr,                                 VideoEncoder videoEncoder,                                 int width, int height, int bitrate){    VIDENC_DynamicParams   dynamicParams;    VIDENC_Status          encStatus;    VIDENC_Params          params;    XDAS_Int32             status;    char                  *algName;    VIDENC_Handle          hEncode;    algName = videoEncodeAlgNames[videoEncoder];    params.size                  = sizeof(VIDENC_Params);    params.encodingPreset        = XDM_DEFAULT;    params.rateControlPreset     = bitrate < 0 ? IVIDEO_NONE : IVIDEO_LOW_DELAY;    params.maxHeight             = D1_HEIGHT;    params.maxWidth              = D1_WIDTH;    params.maxFrameRate          = gblGetYFactor() == NTSCSTD ? 30000 : 25000;    params.maxBitRate            = bitrate < 0 ? 0 : bitrate;    params.dataEndianness        = XDM_BYTE;    params.maxInterFrameInterval = 0;    params.inputChromaFormat     = XDM_YUV_422ILE;    params.inputContentType      = IVIDEO_PROGRESSIVE;    /* Create video encoder instance */    hEncode = VIDENC_create(hEngine, algName, &params);    if (hEncode == NULL) {        ERR("Failed to open video encode algorithm\n");        return FAILURE;     }    dynamicParams.size                = sizeof(VIDENC_DynamicParams);    dynamicParams.inputHeight         = height;    dynamicParams.inputWidth          = width;    dynamicParams.targetBitRate       = bitrate < 0 ? 0 : bitrate;    dynamicParams.intraFrameInterval  = 30;    dynamicParams.generateHeader      = XDM_ENCODE_AU;    dynamicParams.captureWidth        = 0;    dynamicParams.forceIFrame         = 0;    if (gblGetYFactor() == NTSCSTD) {        dynamicParams.targetFrameRate = 30000;        dynamicParams.refFrameRate    = 30000;    }    else {        dynamicParams.targetFrameRate = 25000;        dynamicParams.refFrameRate    = 25000;    }    /* Set video encoder dynamic parameters */    encStatus.size = sizeof(VIDENC_Status);    status = VIDENC_control(hEncode, XDM_SETPARAMS, &dynamicParams,                            &encStatus);    if (status != VIDENC_EOK) {        ERR("XDM_SETPARAMS failed, status=%ld\n", status);        return FAILURE;    }    *hEncodePtr = hEncode;    return SUCCESS;}/****************************************************************************** * encodeVideoBuffer ******************************************************************************/static int encodeVideoBuffer(VIDENC_Handle hEncode, char *inBuf, int inBufSize,                             char *outBuf, int *outBufSize){    XDM_BufDesc             inBufDesc;    XDM_BufDesc             outBufDesc;    XDAS_Int32              inBufSizeArray[1];    XDAS_Int32              outBufSizeArray[1];    XDAS_Int32              status;    VIDENC_InArgs           inArgs;    VIDENC_OutArgs          outArgs;    inBufSizeArray[0]       = inBufSize;    outBufSizeArray[0]      = D1_FRAME_SIZE;    inBufDesc.numBufs       = 1;    inBufDesc.bufSizes      = inBufSizeArray;    inBufDesc.bufs          = (XDAS_Int8 **) &inBuf;    outBufDesc.numBufs      = 1;    outBufDesc.bufSizes     = outBufSizeArray;    outBufDesc.bufs         = (XDAS_Int8 **) &outBuf;    inArgs.size             = sizeof(VIDENC_InArgs);    outArgs.size            = sizeof(VIDENC_OutArgs);    /* Encode video buffer */    status = VIDENC_process(hEncode, &inBufDesc, &outBufDesc, &inArgs,                            &outArgs);    if (status != VIDENC_EOK) {        ERR("VIDENC_process() failed with a fatal error (%ld ext: %#lx\n",            status, outArgs.extendedError);        return FAILURE;    }    *outBufSize = outArgs.bytesGenerated;    return SUCCESS;}/****************************************************************************** * initCaptureDevice ******************************************************************************/static int initCaptureDevice(VideoBuffer **vidBufsPtr, int *numVidBufsPtr,                             int svideoInput, int captureWidth,                             int captureHeight){    struct v4l2_requestbuffers  req;    struct v4l2_capability      cap;    struct v4l2_cropcap         cropCap;    struct v4l2_crop            crop;    struct v4l2_format          fmt;    struct v4l2_buffer          buf;    enum v4l2_buf_type          type;    v4l2_std_id                 std;    int                         input;    int                         fd;    int                         ret;    VideoBuffer                *buffers;    int                         numBufs;    DBG("captureWidth = %d, captureHeight = %d\n", captureWidth, captureHeight);    /* Open video capture device */    fd = open(V4L2_DEVICE, O_RDWR | O_NONBLOCK, 0);    if (fd == -1) {        ERR("Cannot open %s (%s)\n", V4L2_DEVICE, strerror(errno));        return FAILURE;    }    /* Select the video input */    if (svideoInput == TRUE) {        input = TVP5146_AMUX_SVIDEO;    }    else {        input = TVP5146_AMUX_COMPOSITE;    }    if (ioctl(fd, VIDIOC_S_INPUT, &input) == -1) {        ERR("Failed to set video input to %d\n", input);        return FAILURE;    }    DBG("Set the capture input to id %d\n", input);    /* Query for capture device capabilities */    if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1) {        if (errno == EINVAL) {            ERR("%s is no V4L2 device\n", V4L2_DEVICE);            return FAILURE;        }        ERR("Failed VIDIOC_QUERYCAP on %s (%s)\n", V4L2_DEVICE,            strerror(errno));        return FAILURE;    }    if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {        ERR("%s is no video capture device\n", V4L2_DEVICE);        return FAILURE;    }    if (!(cap.capabilities & V4L2_CAP_STREAMING)) {        ERR("%s does not support streaming i/o\n", V4L2_DEVICE);        return FAILURE;    }    cropCap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;    if (ioctl(fd, VIDIOC_CROPCAP, &cropCap) == -1) {        ERR("VIDIOC_CROPCAP failed %d, %s\n", errno, strerror(errno));        return FAILURE;    }    /* Auto detect PAL or NTSC using the capture driver as sanity check */     std = VPFE_STD_AUTO;    if(ioctl(fd, VIDIOC_S_STD, &std) == -1) {        ERR("VIDIOC_S_STD (auto) failed on %s (%s)\n", V4L2_DEVICE,                                                       strerror(errno));        return FAILURE;    }    DBG("Checking video standard\n");    do {        ret = ioctl(fd, VIDIOC_QUERYSTD, &std);    } while (ret == -1 && errno == EAGAIN);    if (ret == -1) {        ERR("VIDIOC_QUERYSTD failed on %s (%s)\n", V4L2_DEVICE,                                                   strerror(errno));        return FAILURE;    }    switch (std) {        case V4L2_STD_NTSC:            DBG("NTSC camera detected\n");            if (gblGetYFactor() == PALSTD) {                ERR("NTSC camera connected but PAL selected.\n");                return FAILURE;            }            break;        case V4L2_STD_PAL:            DBG("PAL camera detected\n");            if (gblGetYFactor() == NTSCSTD) {                ERR("PAL camera connected but NTSC selected.\n");                return FAILURE;            }            break;        default:            ERR("Camera (%s) using unsupported video standard\n", V4L2_DEVICE);            return FAILURE;    }    /* Use either NTSC or PAL depending on display kernel parameter */    std = gblGetYFactor() == NTSCSTD ? V4L2_STD_NTSC : V4L2_STD_PAL;    if(ioctl(fd, VIDIOC_S_STD, &std) == -1) {        ERR("VIDIOC_S_STD failed on %s (%s)\n", V4L2_DEVICE,                                                strerror(errno));        return FAILURE;    }    /* Set the video capture image format */    CLEAR(fmt);    fmt.type                = V4L2_BUF_TYPE_VIDEO_CAPTURE;    fmt.fmt.pix.width       = D1_WIDTH;    fmt.fmt.pix.height      = D1_HEIGHT;    fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;    fmt.fmt.pix.field       = V4L2_FIELD_INTERLACED;    DBG("Setting capture video format\n");    /* Set the video capture format */    if (ioctl(fd, VIDIOC_S_FMT, &fmt) == -1) {        ERR("VIDIOC_S_FMT failed on %s (%s)\n", V4L2_DEVICE,                                                strerror(errno));        return FAILURE;    }    crop.type     = V4L2_BUF_TYPE_VIDEO_CAPTURE;    crop.c.left   = D1_WIDTH / 2 - captureWidth / 2;    crop.c.top    = D1_HEIGHT / 2 - captureHeight / 2;    crop.c.width  = captureWidth;    crop.c.height = captureHeight;    DBG("Setting capture cropping (%dx%d)\n", crop.c.width, crop.c.height);    /* Crop the image depending on requested image size */    if (ioctl(fd, VIDIOC_S_CROP, &crop) == -1) {        ERR("VIDIOC_S_CROP failed %d, %s\n", errno, strerror(errno));        return FAILURE;    }    printf("Capturing %dx%d video (cropped to %dx%d)\n",           fmt.fmt.pix.width, fmt.fmt.pix.height, crop.c.width, crop.c.height);    CLEAR(req);    req.count  = NUM_BUFS;    req.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;    req.memory = V4L2_MEMORY_MMAP;    /* Allocate buffers in the capture device driver */    if (ioctl(fd, VIDIOC_REQBUFS, &req) == -1) {        ERR("VIDIOC_REQBUFS failed on %s (%s)\n", V4L2_DEVICE,                                                  strerror(errno));        return FAILURE;    }    DBG("%d capture buffers were successfully allocated.\n", req.count);    if (req.count < NUM_BUFS) {        ERR("Insufficient buffer memory on %s\n", V4L2_DEVICE);        return FAILURE;    }    buffers = calloc(req.count, sizeof(*buffers));    if (!buffers) {        ERR("Failed to allocate memory for capture buffer structs.\n");        return FAILURE;    }    /* Map the allocated buffers to user space */    for (numBufs = 0; numBufs < req.count; numBufs++) {        CLEAR(buf);        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;        buf.memory = V4L2_MEMORY_MMAP;        buf.index = numBufs;        if (ioctl(fd, VIDIOC_QUERYBUF, &buf) == -1) {            ERR("Failed VIDIOC_QUERYBUF on %s (%s)\n", V4L2_DEVICE,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -