📄 decode.c
字号:
/*
* 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 <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <sched.h>
#include <pthread.h>
#include <asm/types.h>
#include <linux/videodev2.h>
#include <linux/fb.h>
#include <media/davinci_vpfe.h>
/* Application header file */
#include "encodedecode.h"
#include "global.h"
/* Custom Davinci FBDEV defines (should be in device driver header) */
#define VID0_INDEX 0
#define VID1_INDEX 1
#define ZOOM_1X 0
#define ZOOM_2X 1
#define ZOOM_4X 2
struct Zoom_Params
{
u_int32_t WindowID;
u_int32_t Zoom_H;
u_int32_t Zoom_V;
};
#define FBIO_SETZOOM _IOW('F', 0x24, struct Zoom_Params)
#define FBIO_WAITFORVSYNC _IOW('F', 0x20, u_int32_t)
#define FBIO_GETSTD _IOR('F', 0x25, u_int32_t)
/* Macro for clearing structures */
#define CLEAR(x) memset (&(x), 0, sizeof (x))
/* Bits per pixel for video window */
#define SCREEN_BPP 16
/* D1 screen dimensions */
#define D1_WIDTH 720
#define D1_HEIGHT YSCALE(480)
#define D1_LINE_WIDTH (D1_WIDTH * SCREEN_BPP / 8)
#define D1_FRAME_SIZE (D1_LINE_WIDTH * D1_HEIGHT)
/* CIF screen dimensions */
#define CIF_WIDTH 352
#define CIF_HEIGHT YSCALE(240)
#define CIF_LINE_WIDTH (CIF_WIDTH * SCREEN_BPP / 8)
#define CIF_FRAME_SIZE (CIF_LINE_WIDTH * CIF_HEIGHT)
/* Position of CIF image */
#define CIF_XPOS 364
#define CIF_YPOS 240
#define UYVY_BLACK 0x10801080
/* Double buffered for both capture and display drivers */
#define NUM_BUFS 2
/* Describes a capture frame buffer */
typedef struct VideoBuffer {
void *start;
size_t length;
} VideoBuffer;
enum InitLevels {
DISPLAYDEVICEINITIALIZED = 1,
CAPTUREDEVICEINITIALIZED,
ENGINEOPENED,
VIDEOENCODERCREATED,
VIDEODECODERCREATED,
ENCODEDBUFFERALLOCATED,
CIFBUFFERALLOCATED
};
/* Local function prototypes */
static int videoDecodeAlgCreate(Engine_Handle hEngine,
VIDDEC_Handle *hDecodePtr, int *encBufSizePtr,
int width, int height);
static int videoEncodeAlgCreate(Engine_Handle hEngine,
VIDENC_Handle *hEncodePtr,
int width, int height);
static int encodeVideoBuffer(VIDENC_Handle hEncode, char *inBuf, int inBufSize,
char *outBuf, int *outBufSize);
static int decodeVideoBuffer(VIDDEC_Handle hDecode, char *inBuf,
int inBufSize, char *outBuf,
int outBufSize, int *framesDroppedPtr);
static int flipDisplayBuffers(int fd, int displayIdx);
static int initCaptureDevice(enum Resolution resolution,
VideoBuffer **vidBufsPtr, int *numVidBufsPtr,
int *captureWidth, int *captureHeight);
static void cleanupCaptureDevice(int fd, VideoBuffer *vidBufs, int numVidBufs);
static int initDisplayDevice(enum Resolution resolution, char *displays[]);
static void cleanupDisplayDevice(int fd, char *displays[]);
static inline int waitForFrame(int fd);
/******************************************************************************
* videoDecodeAlgCreate
******************************************************************************/
static int videoDecodeAlgCreate(Engine_Handle hEngine,
VIDDEC_Handle *hDecodePtr, int *encBufSizePtr,
int width, int height)
{
VIDDEC_Params params;
VIDDEC_Status decStatus;
XDAS_Int32 status;
VIDDEC_DynamicParams dynamicParams;
VIDDEC_Handle hDecode;
/* Create H.264 decoder instance */
params.size = sizeof(VIDDEC_Params);
params.maxFrameRate = 30000;
params.maxBitRate = 1000000;
params.dataEndianness = XDM_BYTE;
params.forceChromaFormat = XDM_YUV_422ILE;
params.maxHeight = height;
params.maxWidth = width;
hDecode = VIDDEC_create(hEngine, "h264dec", ¶ms);
if (hDecode == NULL) {
ERR("Can't open decode algorithm: %s\n", "h264");
return FAILURE;
}
status = VIDDEC_control(hDecode, XDM_GETBUFINFO, &dynamicParams,
&decStatus);
if (status != VIDDEC_EOK) {
ERR("XDM_GETBUFINFO failed, status=%ld\n", status);
return FAILURE;
}
*encBufSizePtr = decStatus.bufInfo.minInBufSize[0];
*hDecodePtr = hDecode;
return SUCCESS;
}
/******************************************************************************
* videoEncodeAlgCreate
******************************************************************************/
static int videoEncodeAlgCreate(Engine_Handle hEngine,
VIDENC_Handle *hEncodePtr,
int width, int height)
{
VIDENC_Params params;
VIDENC_Handle hEncode;
params.size = sizeof(VIDENC_Params);
params.encodingPreset = XDM_DEFAULT;
params.rateControlPreset = 1;
params.maxFrameRate = 30000;
params.maxBitRate = 4000000;
params.dataEndianness = XDM_BYTE;
params.maxInterFrameInterval = 0;
params.inputChromaFormat = XDM_YUV_422ILE;
params.inputContentType = IVIDEO_PROGRESSIVE;
params.maxHeight = height;
params.maxWidth = width;
/* Create H.264 encoder instance */
hEncode = VIDENC_create(hEngine, "h264enc", ¶ms);
if (hEncode == NULL) {
ERR("Can't open encode algorithm: %s\n", "h264");
return FAILURE;
}
*hEncodePtr = hEncode;
return SUCCESS;
}
/******************************************************************************
* encodeVideoBuffer
******************************************************************************/
static int encodeVideoBuffer(VIDENC_Handle hEncode, char *inBuf, int inBufSize,
char *outBuf, int *outBufSize)
{
VIDENC_DynamicParams dynamicParams;
XDAS_Int32 inBufSizeArray[1];
XDAS_Int32 outBufSizeArray[1];
XDAS_Int32 status;
XDM_BufDesc inBufDesc;
XDM_BufDesc outBufDesc;
VIDENC_InArgs inArgs;
VIDENC_OutArgs outArgs;
VIDENC_Status encStatus;
inBufSizeArray[0] = inBufSize;
outBufSizeArray[0] = *outBufSize;
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);
status = VIDENC_process(hEncode, &inBufDesc, &outBufDesc,
&inArgs, &outArgs);
if (status != VIDENC_EOK) {
status = VIDENC_control(hEncode, XDM_GETSTATUS, &dynamicParams,
&encStatus);
if (status != VIDENC_EOK) {
ERR("XDM_GETSTATUS failed, status=%ld\n", status);
return FAILURE;
}
ERR("Extended error %ld\n", encStatus.extendedError);
return FAILURE;
}
*outBufSize = outArgs.bytesGenerated;
return SUCCESS;
}
/******************************************************************************
* decodeVideoBuffer
******************************************************************************/
static int decodeVideoBuffer(VIDDEC_Handle hDecode, char *inBuf,
int inBufSize, char *outBuf,
int outBufSize, int *framesDroppedPtr)
{
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] = outBufSize;
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(VIDDEC_InArgs);
inArgs.numBytes = inBufSize;
inArgs.inputID = 0;
outArgs.size = sizeof(VIDDEC_OutArgs);
status = VIDDEC_process(hDecode, &inBufDesc, &outBufDesc,
&inArgs, &outArgs);
if (status != VIDDEC_EOK) {
status = VIDDEC_control(hDecode, XDM_GETSTATUS, &dynamicParams,
&decStatus);
if (status != VIDDEC_EOK) {
ERR("XDM_GETSTATUS failed, status=%ld\n", status);
return FAILURE;
}
if (status == VIDDEC_ERUNTIME ||
XDM_ISFATALERROR(decStatus.extendedError)) {
ERR("VIDDEC_process() failed with a fatal error (%ld ext: %#lx\n",
status, decStatus.extendedError);
return FAILURE;
}
else {
*framesDroppedPtr++;
return SUCCESS;
}
}
if (status != VIDDEC_EOK) {
ERR("VIDDEC_process() failed, status=%ld\n", status);
return FAILURE;
}
return SUCCESS;
}
/******************************************************************************
* flipDisplayBuffers
******************************************************************************/
static int flipDisplayBuffers(int fd, int displayIdx)
{
struct fb_var_screeninfo vInfo;
if (ioctl(fd, FBIOGET_VSCREENINFO, &vInfo) == -1) {
ERR("Failed FBIOGET_VSCREENINFO (%s)\n", strerror(errno));
return FAILURE;
}
vInfo.yoffset = vInfo.yres * displayIdx;
/* Swap the working buffer for the displayed buffer */
if (ioctl(fd, FBIOPAN_DISPLAY, &vInfo) == -1) {
ERR("Failed FBIOPAN_DISPLAY (%s)\n", strerror(errno));
return FAILURE;
}
return SUCCESS;
}
/******************************************************************************
* initCaptureDevice
******************************************************************************/
static int initCaptureDevice(enum Resolution resolution,
VideoBuffer **vidBufsPtr, int *numVidBufsPtr,
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;
v4l2_std_id std;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -