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

📄 video_thread.c

📁 TI workshop 培训资料。 是关于如何创建DAVINCI平台下codec engine
💻 C
字号:
/* * video_thread.c *//* Standard Linux headers */#include <stdio.h>		// always include stdio.h#include <stdlib.h>		// always include stdlib.h#include <string.h>             // defines memset and memcpy methods#include <sys/ioctl.h>		// defines ioctl method#include <linux/fb.h>		// defines framebuffer driver methods#include <asm/types.h>          // standard typedefs required by v4l2 header#include <linux/videodev2.h>    // v4l2 driver definitions/* Codec Engine headers */#include <xdc/std.h>			// xdc base definitions. Must come 1st#include <ti/sdo/ce/Engine.h>		// required for any CE application#include <ti/sdo/ce/CERuntime.h>	// required for any CE application#include <ti/sdo/ce/video/viddec.h>	// defines video decoder functions#include <ti/sdo/ce/video/videnc.h>	// defines video encoder functions/* Application header files */#include "debug.h"		// DBG and ERR macros#include "video_thread.h"	// video thread definitions#include "video_osd.h"          // OSD window functions#include "video_output.h" 	// Video display device functions#include "video_input.h" 	// Video input device functions#include "engine.h"             // Helper utilities for engine_open and close#include "video_decoder.h"	// Video decoder functions#include "video_encoder.h"	// Video encoder functions/* Video encoder and decoder used */#define VIDEO_ENCODER "video_encoder"#define VIDEO_DECODER "video_decoder"/* Video capture and display devices used */#define FBVID_VIDEO "/dev/fb/3"#define FBVID_ATTR "/dev/fb/2"#define FBVID_OSD "/dev/fb/0"#define V4L2_DEVICE "/dev/video0"/* Input file */#define INPUTFILE "/tmp/video.raw"#define PICTUREFILE "osd.r16"/* Double-buffered display, triple-buffered capture */#define NUM_DISP_BUFS 2#define NUM_CAP_BUFS 3/* Other Definitions */#define SCREEN_BPP 16#define D1_WIDTH 720#define D1_HEIGHT 480/* Macro for clearing structures */#define CLEAR(x) memset (&(x), 0, sizeof (x))/****************************************************************************** * video_thread_fxn ******************************************************************************//*  input parameters:                                                         *//*      void *arg  --  a pointer to a video_thread_env structure as           *//*                     defined in video_thread.h                              *//*                                                                            *//*          arg.quit    -- when quit != 0, thread will cleanup and exit       *//*                                                                            *//*  return value:                                                             *//*      void *     --  VIDEO_THREAD_SUCCESS or VIDEO_THREAD_FAILURE as        *//*                     defined in video_thread.h                              *//******************************************************************************/void *video_thread_fxn(void *arg){/* Thread parameters and return value */    video_thread_env *env    = arg;			// see above    void             *status = VIDEO_THREAD_SUCCESS;	// see above/* The levels of initialization for initMask */#define OSDSETUPCOMPLETE	 0x1#define DISPLAYDEVICEINITIALIZED 0x2#define CAPTUREDEVICEINITIALIZED 0x4#define VIDEOENCODERCREATED      0x8#define VIDEODECODERCREATED      0x10#define ENCODEDBUFFERALLOCATED   0x20#define ENGINEOPENED		 0x40    unsigned int       initMask       = 0x0;/* Capture and display driver variables */    FILE              *inputFile      = NULL;  // input file pointer    int                osdFd	      = 0;     // OSD file descriptor    int                attrFd	      = 0;     // attr window file descriptor    int 	       fbFd 	      = 0;     // video fb driver file desc    int                captureFd      = 0;  // capture driver file descriptor    unsigned short    *osdDisplay;		// OSD display buffer    unsigned short    *attrDisplay;		// attribute display buffer    VideoBuffer       *vidBufs;			// capture frame descriptors    unsigned int       numVidBufs = NUM_CAP_BUFS; // number of capture frames    int                captureWidth;		// width of a capture frame    int                captureHeight;		// height of a capture frame    int                captureSize;		// bytes in a capture frame    struct v4l2_buffer v4l2buf;			// stores a dequeue'd frame#define PICTURE_HEIGHT 60#define PICTURE_WIDTH 720    unsigned short     picture[PICTURE_HEIGHT * PICTURE_WIDTH]; // osd picture    char              *displays[NUM_DISP_BUFS]; // display frame pointers    int 	       displayWidth;		// width of a display frame    int		       displayHeight;		// height of a display frame    int 	       displayBufSize;		// bytes in a display frame    int                displayIdx     = 0;	// frame being displayed    int                workingIdx     = 1;	// next frame, being built    char              *dst;			// pointer to working frame/* OSD scrolling variables */    int xoffset = 0;    int yoffset = 0;/*  Intermediate buffer for encoded video */    char              *encBuf   = NULL;	 // pointer to encoded buffer    int                encBufSize = 0;	 // size of encoded buffer (numbytes =    int		       numbytes;	 //    how full, numbytes < encBufSize) /*  Codec engine variables */    Engine_Handle	engineHandle = NULL;    VIDENC_Handle	encoderHandle = NULL;	 // handle to video encoder    VIDDEC_Handle	decoderHandle = NULL;	 // handle to video decoder    /* Thread Setup Phase -- secure and initialize resources */    /*  Initialize video attribute window to fully opaque OSD (0x77)     */    if( video_osd_setup(&osdFd, &attrFd, FBVID_OSD, FBVID_ATTR, 0x00, 			&osdDisplay, &attrDisplay) == VOSD_FAILURE ){	ERR("Failed video_osd_setup in video_thread_function\n");	status = VIDEO_THREAD_FAILURE;	goto cleanup;    }    initMask |= OSDSETUPCOMPLETE;    /* Place a circular alpha-blended OSD frame around video screen */    video_osd_circframe(osdDisplay, attrDisplay, 0xFFFF, 0x33);    /* Open the display picture for OSD */        if((inputFile = fopen(PICTUREFILE, "r")) == NULL) {	ERR("Failed to open input file %s\n", PICTUREFILE);	status = VIDEO_THREAD_FAILURE;	goto cleanup;    }    DBG("Opened file %s with FILE pointer %p\n", PICTUREFILE, inputFile);    /* read in picture */    if(fread(picture, sizeof(short), PICTURE_HEIGHT * PICTURE_WIDTH, inputFile)					< PICTURE_HEIGHT * PICTURE_WIDTH){ 	    ERR("Error reading osd picture from file\n");	    fclose(inputFile);	    goto cleanup;    }    fclose(inputFile);    DBG("OSD Picture read successful, placing picture\n");    video_osd_place(osdDisplay, attrDisplay, picture, 0x77, 				0, 420, PICTURE_WIDTH, PICTURE_HEIGHT);    /* Initialize the video display device */    displayWidth = D1_WIDTH;    displayHeight = D1_HEIGHT;    if( video_output_setup(&fbFd, FBVID_VIDEO, displays, NUM_DISP_BUFS, 			&displayWidth, &displayHeight, ZOOM_1X) 				== VOUT_FAILURE) {        ERR("Failed video_output_setup in video_thread_function\n");	status = VIDEO_THREAD_FAILURE;	goto cleanup;    }    /*  Calculate size of a display buffer in bytes */    displayBufSize = displayWidth * displayHeight * SCREEN_BPP/8;    /* Record that display device was opened in initialization bitmask */    initMask |= DISPLAYDEVICEINITIALIZED;    /* Initialize the video capture device */    captureWidth = D1_WIDTH;    captureHeight = D1_HEIGHT;        if( video_input_setup(&captureFd, V4L2_DEVICE, &vidBufs, &numVidBufs,                        &captureWidth, &captureHeight) == VIN_FAILURE) {	ERR("Failed video_input_setup in video_thread_function\n");	status = VIDEO_THREAD_FAILURE;	goto cleanup;    }    /* Calculate size of a raw frame */    captureSize = captureWidth * captureHeight * SCREEN_BPP / 8;    /* Record that cpature device was opened in initialization bitmask */    initMask |= CAPTUREDEVICEINITIALIZED;    /* open the codec engine */    /* note: codec engine should be opened in each thread that uses it */    if(engine_setup(&engineHandle, env->engineName, NULL) != ENGINE_SUCCESS){	ERR("engine_setup failed in video_thread_fxn\n");	status = VIDEO_THREAD_FAILURE;	goto cleanup;    }     initMask |= ENGINEOPENED;    /* Allocate and initialize video encoder on the engine */    /*     uses engineHandle global variable assumed set before entry */    if (video_encoder_setup(engineHandle, VIDEO_ENCODER, &encoderHandle) 						== VENC_FAILURE) {	ERR("Failed video_encoder_setup in video_thread_fxn\n");	status = VIDEO_THREAD_FAILURE;	goto cleanup;    }    initMask |= VIDEOENCODERCREATED;    /* Allocate and initialize video decoder on the engine */    /*     uses numbytes as a temporary variable for minInBufSize */    if (video_decoder_setup(engineHandle, VIDEO_DECODER, &decoderHandle) 						== VDEC_FAILURE) {	ERR("Failed video_decoder_setup in video_thread_fxn");	status = VIDEO_THREAD_FAILURE;	goto cleanup;    }    initMask |= VIDEODECODERCREATED;    /* Set buffer size for intermediate buffer (for encoded data)          */    /* as the maximum of the encoders max output size and the decoders     */    /*       minimum input size                                            */    encBufSize = captureSize;    /* Allocate intermediate buffer */    /* Must use contiguous buffers if passed to DSP! */    /* (Driver buffers are automatically allocated contiguous */    encBuf = (char *) malloc(encBufSize);    if (encBuf == NULL) {        ERR("Failed to allocate video buffer in video_thread_fxn.\n");	status = VIDEO_THREAD_FAILURE;	goto cleanup;    }    initMask |= ENCODEDBUFFERALLOCATED;    DBG("Allocated intermediate video buffer of size %d\n", encBufSize);    DBG("\tat location %p\n", encBuf);    /* Thread Execute Phase -- perform I/O and processing */    DBG("Entering video_thread_fxn processing loop.\n");    while (!env->quit) {#define X_RATE 5#define Y_RATE 0    	xoffset += X_RATE;    	yoffset += Y_RATE;     	if(xoffset >= PICTURE_WIDTH)	    xoffset = 0;    	if(yoffset >= PICTURE_HEIGHT)	    yoffset = 0;    	video_osd_scroll(osdDisplay, attrDisplay, picture, 0, 420, 			PICTURE_WIDTH, PICTURE_HEIGHT, xoffset, yoffset);	/*  Read input buffer from video capture device */         if (wait_for_frame(captureFd) == VIN_FAILURE) {	    ERR("wait_for_frame failed in video_thread_fxn\n");            status = VIDEO_THREAD_FAILURE;	    break;        }        CLEAR(v4l2buf);        v4l2buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;        v4l2buf.memory = V4L2_MEMORY_MMAP;        /* Dequeue a frame buffer from the capture device driver */        if (ioctl(captureFd, VIDIOC_DQBUF, &v4l2buf) == -1) {//            if (errno == EAGAIN) {//                continue;//            }            ERR("VIDIOC_DQBUF failed in video_thread_fxn\n");	    status = VIDEO_THREAD_FAILURE;            break;        }	/* on input, numbytes specifies full size of intermediate buffer */	numbytes = encBufSize;        /* Encode the buffer */        if (encode_video(encoderHandle, vidBufs[v4l2buf.index].start,                      captureSize, encBuf, &numbytes) == VENC_FAILURE) {            ERR("encode_video failed in video_thread_fxn\n");	    status = VIDEO_THREAD_FAILURE;	    break;        }	dst = displays[workingIdx];        /* Decode the buffer */        if (decode_video(decoderHandle, encBuf, numbytes, dst, displayBufSize) 			== VDEC_FAILURE) {	    ERR("decode_video failed in video_thread_fxn\n");            status = VIDEO_THREAD_FAILURE;	    break;        }        /* Issue capture buffer back to capture device driver */        if (ioctl(captureFd, VIDIOC_QBUF, &v4l2buf) == -1) {            ERR("VIDIOC_QBUF failed in video_thread_fxn\n");            status = VIDEO_THREAD_FAILURE;	    break;        }        /* Flip display buffer and working buffer */        displayIdx = (displayIdx + 1) % NUM_DISP_BUFS;        workingIdx = (workingIdx + 1) % NUM_DISP_BUFS;        flip_display_buffers(fbFd, displayIdx);    }cleanup:    DBG("Exited video_thread_fxn processing loop\n");    DBG("\tStarting video thread cleanup\n");    /* Thread Cleanup Phase -- free resources no longer needed by thread */    /* Uses the init_bitmask to only free resources that were allocated  */    /* Cleanup osd */    if (initMask & OSDSETUPCOMPLETE) {	DBG("Closing FILE ptr %p\n", inputFile);	video_osd_cleanup(osdFd, attrFd, osdDisplay, attrDisplay);        }    /* Close video capture device */    if (initMask & CAPTUREDEVICEINITIALIZED) {        video_input_cleanup(captureFd, vidBufs, numVidBufs);    }    /* Close video display device */     if (initMask & DISPLAYDEVICEINITIALIZED) {        video_output_cleanup(fbFd, displays, NUM_DISP_BUFS);    }    /* Delete video decoder */    if (initMask & VIDEODECODERCREATED) {        video_decoder_cleanup(decoderHandle);    }    /* Delete video encoder */    if (initMask & VIDEOENCODERCREATED) {        video_encoder_cleanup(encoderHandle);    }    /* Close the engine */    if (initMask & ENGINEOPENED){	engine_cleanup(engineHandle);    }    /* Free intermediate (encoded) buffer */    if (initMask & ENCODEDBUFFERALLOCATED) {        DBG("Freed intermediate video buffer at %p\n", encBuf);        free(encBuf);    }    /* Return the status of thread execution */    DBG("Video thread cleanup complete. Exiting video_thread_fxn\n");    return status;}

⌨️ 快捷键说明

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