199 lines
4.7 KiB
C++
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
|