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

📄 video.c

📁 ti达芬奇开发板H.264视频解码的完整demo程序
💻 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>/* 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/viddec.h>/* Demo headers */#include <rendezvous.h>#include <fifoutil.h>#include "decode.h"#include "video.h"#include "display.h"#include "loader.h"/* The size of the read buffer */#define READBUFSIZE              3 * 1024 * 1024/* The levels of initialization */#define VIDEOFILEINITIALIZED     0x1#define INFIFOOPENED             0x2#define OUTFIFOOPENED            0x4#define DISPLAYTHREADCREATED     0x8#define ENGINEOPENED             0x10#define VIDEODECODERCREATED      0x20#define READBUFFERALLOCATED      0x40#define DISPLAYBUFFERSALLOCATED  0x80/* Number of buffers between video thread and display thread */#define DISPLAY_BUFFERS          3/* Negative value of outputID means the decoder kept the buffer */#define BUFFER_KEPT_SEND_NEW_DST -1#define BUFFER_KEPT_RESUBMIT_DST -2/* Structure containing statistics about the frames in a clip */typedef struct FrameStats {    int framesRejected;    int iFrames;    int pFrames;    int bFrames;    int idrFrames;} FrameStats;/* Video decoder names */static char *videoDecodeAlgNames[NUM_VIDEO_DECODERS] = {    "mpeg4dec",    "h264dec",    "mpeg2dec"};/* Local function prototypes */static int getClipSize(VIDDEC_Handle hDecode, int *widthPtr, int *heightPtr);static int videoDecodeAlgCreate(Engine_Handle hEngine,                                VIDDEC_Handle *hDecodePtr,                                enum VideoDecoder videoDecoder,                                int *readSizePtr);static int decodeVideoBuffer(VIDDEC_Handle hDecode, char *inBuf, int inBufSize,                             int inputID, char *outBuf, int *bytesProcessed,                             int *outputIDPtr, FrameStats *stats,                             int *frameDonePtr);/****************************************************************************** * getClipSize ******************************************************************************/static int getClipSize(VIDDEC_Handle hDecode, int *widthPtr, int *heightPtr){    VIDDEC_DynamicParams    dynamicParams;    VIDDEC_Status           decStatus;    XDAS_Int32              status;    /* Get the codec status (which includes width and height of last frame) */    dynamicParams.size = sizeof(VIDDEC_DynamicParams);    decStatus.size = sizeof(VIDDEC_Status);    status = VIDDEC_control(hDecode, XDM_GETSTATUS, &dynamicParams,                            &decStatus);    if (status != VIDDEC_EOK) {        ERR("XDM_GETSTATUS failed, status=%ld\n", status);        return FAILURE;    }    if (decStatus.outputWidth > D1_WIDTH ||        decStatus.outputHeight > D1_MAX_HEIGHT) {        ERR("Clip size (%ldx%ld) bigger than a D1 screen (%dx%d)\n",            decStatus.outputWidth, decStatus.outputHeight,            D1_WIDTH, D1_MAX_HEIGHT);        return FAILURE;    }    /* Set the global variables for OSD update */    gblSetImageWidth(decStatus.outputWidth);    gblSetImageHeight(decStatus.outputHeight);    *widthPtr = decStatus.outputWidth;    *heightPtr = decStatus.outputHeight;    return SUCCESS;}/****************************************************************************** * videoDecodeAlgCreate ******************************************************************************/static int videoDecodeAlgCreate(Engine_Handle hEngine,                                VIDDEC_Handle *hDecodePtr,                                VideoDecoder videoDecoder,                                int *readSizePtr){    VIDDEC_Handle          hDecode;    VIDDEC_Status          decStatus;    XDAS_Int32             status;    VIDDEC_Params          params;    VIDDEC_DynamicParams   dynamicParams;    char                  *algName;    algName = videoDecodeAlgNames[videoDecoder];    params.size              = sizeof(VIDDEC_Params);    params.maxHeight         = D1_MAX_HEIGHT;    params.maxWidth          = D1_WIDTH;    params.maxFrameRate      = 0;    params.maxBitRate        = 0;    params.dataEndianness    = XDM_BYTE;    params.forceChromaFormat = XDM_YUV_422ILE;    /* Create video decoder instance */    hDecode = VIDDEC_create(hEngine, algName, &params);    if (hDecode == NULL) {        ERR("Failed to open video decode algorithm\n");        return FAILURE;     }    dynamicParams.size          = sizeof(VIDDEC_DynamicParams);    dynamicParams.decodeHeader  = XDM_DECODE_AU;    dynamicParams.displayWidth  = XDM_DEFAULT;    dynamicParams.frameSkipMode = IVIDEO_NO_SKIP;    /* Set video decoder dynamic params */    decStatus.size = sizeof(VIDDEC_Status);    status = VIDDEC_control(hDecode, XDM_SETPARAMS, &dynamicParams,                            &decStatus);    if (status != VIDDEC_EOK) {        ERR("XDM_SETPARAMS failed, status=%ld\n", status);        return FAILURE;    }    /* Get buffer information from video decoder */    decStatus.size = sizeof(VIDDEC_Status);    dynamicParams.size = sizeof(VIDDEC_DynamicParams);    status = VIDDEC_control(hDecode, XDM_GETBUFINFO, &dynamicParams,                            &decStatus);    if (status != VIDDEC_EOK) {        ERR("XDM_GETBUFINFO failed, status=%ld\n", status);        return FAILURE;    }//Liang*readSizePtr = 1024*1024;   // *readSizePtr = decStatus.bufInfo.minInBufSize[0];    *hDecodePtr = hDecode;    return SUCCESS;}/****************************************************************************** * decodeVideoBuffer ******************************************************************************/static int decodeVideoBuffer(VIDDEC_Handle hDecode, char *inBuf, int inBufSize,                             int inputID, char *outBuf, int *bytesProcessed,                             int *outputIDPtr, FrameStats *stats,                             int *frameDonePtr){    VIDDEC_DynamicParams    dynamicParams;    VIDDEC_InArgs           inArgs;    VIDDEC_OutArgs          outArgs;    VIDDEC_Status           decStatus;    XDM_BufDesc             inBufDesc;    XDM_BufDesc             outBufDesc;    XDAS_Int32              inBufSizeArray[1];    XDAS_Int32              outBufSizeArray[1];    XDAS_Int32              status;    dynamicParams.size      = sizeof(VIDDEC_DynamicParams);    decStatus.size          = sizeof(VIDDEC_Status);    inBufSizeArray[0]       = inBufSize;    outBufSizeArray[0]      = D1_MAX_FRAME_SIZE;    inBufDesc.bufSizes      = inBufSizeArray;    inBufDesc.bufs          = (XDAS_Int8 **) &inBuf;    inBufDesc.numBufs       = 1;    outBufDesc.bufSizes     = outBufSizeArray;    outBufDesc.bufs         = (XDAS_Int8 **) &outBuf;    outBufDesc.numBufs      = 1;    inArgs.size             = sizeof(VIDDEC_InArgs);    inArgs.numBytes         = inBufSize;    inArgs.inputID          = inputID;    outArgs.size            = sizeof(VIDDEC_OutArgs);    /* Decode video buffer */    status = VIDDEC_process(hDecode, &inBufDesc, &outBufDesc, &inArgs,                            &outArgs);    *bytesProcessed = outArgs.bytesConsumed;     if (status != VIDDEC_EOK) {        if (status == VIDDEC_ERUNTIME ||            outArgs.bytesConsumed == 0 ||            XDM_ISFATALERROR(outArgs.extendedError)) {            ERR("VIDDEC_process() failed with a fatal error (%ld ext: %#lx)\n",                status, outArgs.extendedError);            return FAILURE;        }        else {            stats->framesRejected++;            return SUCCESS;        }    }    /* Get frame status to see if this was an interlaced frame */    status = VIDDEC_control(hDecode, XDM_GETSTATUS, &dynamicParams,                            &decStatus);    if (status != VIDDEC_EOK) {        ERR("XDM_GETSTATUS failed, status=%ld\n", status);        return FAILURE;    }    if (decStatus.contentType == IVIDEO_INTERLACED) {        (*frameDonePtr) ^= 1;    }    switch (outArgs.decodedFrameType) {        case IVIDEO_I_FRAME:            stats->iFrames++;            break;        case IVIDEO_P_FRAME:            stats->pFrames++;            break;        case IVIDEO_B_FRAME:            stats->bFrames++;            break;        case IVIDEO_IDR_FRAME:            stats->idrFrames++;            break;    }    /* Did the decoder keep the frame? */    if (outArgs.displayBufs.bufs[0] == NULL) {        if ((outArgs.decodedFrameType != IVIDEO_B_FRAME) & *frameDonePtr) {            *outputIDPtr = BUFFER_KEPT_SEND_NEW_DST;        }        else {            *outputIDPtr = BUFFER_KEPT_RESUBMIT_DST;        }    }    else {        *outputIDPtr = outArgs.outputID;    }    return SUCCESS;}/****************************************************************************** * videoThrFxn ******************************************************************************/void *videoThrFxn(void *arg){    BufferElement      flush          = { DISPLAY_FLUSH };    FrameStats         frameStats     = { 0, 0, 0, 0, 0 };    Engine_Handle      hEngine        = NULL;    unsigned int       initMask       = 0;    int                numDisplayBufs = 0;    VideoEnv          *envp           = (VideoEnv *) arg;    void              *status         = THREAD_SUCCESS;    BufferElement      bufferElements[DISPLAY_BUFFERS];    struct sched_param schedParam;    pthread_t          displayThread;    pthread_attr_t     attr;    VIDDEC_Handle      hDecode;    DisplayEnv         displayEnv;    LoaderState        lState;    int                frameDone;    int                outputID;    char              *framePtr;    int                clipWidth;    int                clipHeight;    int                frameSize;    void              *ret;    BufferElement      e;    int                i;    /* Initialize loader state */    lState.loop = envp->loop;    lState.readBufSize = READBUFSIZE;    lState.doneMask = VIDEO_DONE;    /* Open the input video file */    lState.inputFd = open(envp->videoFile, O_RDONLY);    if (lState.inputFd == -1) {        ERR("Failed to open %s (%s)\n", envp->videoFile, strerror(errno));

⌨️ 快捷键说明

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