JD2022-TU1/main/extern/Camcam/LIBS/H264 - lib/H264_Decoder.cpp

199 lines
4.7 KiB
C++

#include <windows.h>
#include "TRACK.h"
#include "CODEC.h"
#include "avcodec.h"
#include "avformat.h"
#ifdef CODEC_H264
extern "C"
{
int mov_init(void);
CRITICAL_SECTION g_csStaticDataLock;
};
#define DECODE_HeaderDataFile "h264header.264"
typedef struct X264_tdst_Decode_
{
AVFrame *pFrameRGB;
AVFrame *pFrame;
uint8_t *buffer;
AVCodecContext *pCodecCtx;
int videoStream;
int i_FrameDecoded;
int i_FrameFound;
int i_FrameSkipped;
int i_FrameDisplayed;
int i_FrameError;
int i_DataRead;
int i_FrameAbove1000;
int i_FrameAbove1000Data;
char *mpc_Raw;
} X264_tdst_Decode;
/*
=======================================================================================================================
=======================================================================================================================
*/
#define tkhd_fourcc (('t' << 24) | ('k' << 16) | ('h' << 8) | 'd')
/**/
int DecodeInit( X264_tdst_Decode *D, int W, int H )
{
AVCodec *codec;
int frame, size, got_picture, len;
FILE *f;
AVFrame *picture;
avcodec_init();
avcodec_register_all();
/* find the mpeg1 video decoder */
codec = avcodec_find_decoder(CODEC_ID_H264);
D->pCodecCtx= avcodec_alloc_context();
picture= avcodec_alloc_frame();
if(codec->capabilities&CODEC_CAP_TRUNCATED)
D->pCodecCtx->flags|= CODEC_FLAG_TRUNCATED; /* we dont send complete frames */
/* open it */
if (avcodec_open(D->pCodecCtx, codec) < 0)
{
return -1;
}
D->pFrame = avcodec_alloc_frame();
// Allocate an AVFrame structure
D->pFrameRGB = avcodec_alloc_frame();
if(D->pFrameRGB == NULL) return -1;
D->pCodecCtx->width = W;
D->pCodecCtx->height = H;
// Determine required buffer size and allocate buffer
u32 numBytes = avpicture_get_size(PIX_FMT_RGBA32, D->pCodecCtx->width, D->pCodecCtx->height);
D->buffer = new uint8_t[numBytes];
// Assign appropriate parts of buffer to image planes in D->pFrameRGB
avpicture_fill((AVPicture *) D->pFrameRGB, D->buffer, PIX_FMT_RGBA32, D->pCodecCtx->width, D->pCodecCtx->height);
return 0;
}
/*
=======================================================================================================================
=======================================================================================================================
*/
void DecodeClose(X264_tdst_Decode *D)
{
// Free the RGB image
delete[] D->buffer;
av_free(D->pFrameRGB);
// Free the YUV frame
av_free(D->pFrame);
// Close the codec
avcodec_close(D->pCodecCtx);
// Close the video file
av_free_static();
}
/*
=======================================================================================================================
=======================================================================================================================
*/
void DecodeResetStats(X264_tdst_Decode *D)
{
D->i_FrameFound = 0;
D->i_FrameSkipped = 0;
D->i_FrameDisplayed = 0;
D->i_DataRead = 0;
D->i_FrameAbove1000 = 0;
D->i_FrameAbove1000Data = 0;
D->i_FrameError = 0;
}
void *H264_Decode_INIT(MAP *PPicture)
{
X264_tdst_Decode *Dec;
Dec = (X264_tdst_Decode *)CC_malloc(sizeof(X264_tdst_Decode));
memset(Dec,0,sizeof(Dec));
DecodeInit( Dec, PPicture->SX, PPicture->SY);
return (void *)Dec;
}
extern "C" { int H264_decode_frame(AVCodecContext *avctx,void *data, int *data_size,uint8_t *buf, int buf_size); }
u32 H264_Decode_FRAME(void *H,MAP *PPicture,char *Buffer,u32 BufferSize)
{
int res, res2;
int bytesDecoded;
int frameFinished;
int begin, end, val, mark;
X264_tdst_Decode *Dec;
Dec = (X264_tdst_Decode *)H;
Dec->i_FrameFound++;
frameFinished = 0;
bytesDecoded = H264_decode_frame(Dec->pCodecCtx, Dec->pFrame , &frameFinished, (uint8_t *) Buffer, BufferSize);
if(frameFinished && (bytesDecoded ==BufferSize) )
{
/*~~~~~~~~~~~~~~*/
int y, x;
char *p, *psrc;
/*~~~~~~~~~~~~~~*/
img_convert
(
(AVPicture *) Dec->pFrameRGB,
PIX_FMT_RGBA32,
(AVPicture *) Dec->pFrame,
Dec->pCodecCtx->pix_fmt,
Dec->pCodecCtx->width,
Dec->pCodecCtx->height
);
p = (char*)PPicture->BASE/*Dec->mpc_Raw*/;
for(y = 0; y < Dec->pCodecCtx->height; y++)
{
psrc = (char *) (Dec->pFrameRGB->data[0] + y * Dec->pFrameRGB->linesize[0]);
memcpy(p,psrc,Dec->pCodecCtx->width*4);
p += PPicture->PITCH * 4;
}
return true;
}
return 0;
}
void H264_Decode_CLOSE(void *H)
{
DecodeClose((X264_tdst_Decode *)H);
return ;
}
void *Decode_INIT(MAP *PPicture)
{
return H264_Decode_INIT(PPicture);
}
u32 Decode_FRAME(void *H, MAP *PPicture, char *Buffer, u32 FROMSCRATCH)
{
return H264_Decode_FRAME(H, PPicture, Buffer, FROMSCRATCH);
}
void Decode_CLOSE(void *H)
{
H264_Decode_CLOSE(H);
}
#endif