可以运行的版本,32位库匹配好了
parent
a5e4ba8acb
commit
587a642bbb
|
@ -1,328 +0,0 @@
|
|||
#include "SdlPlayer.h"
|
||||
#include "Debuger.h"
|
||||
|
||||
uint32_t FfmpegPixFormatToSdl(AVPixelFormat av) {
|
||||
switch (av) {
|
||||
case AV_PIX_FMT_YUYV422:
|
||||
return SDL_PIXELFORMAT_YUY2;
|
||||
}
|
||||
}
|
||||
|
||||
SDLPlayser::SDLPlayser(HWND hwnd,int width,int height, AVPixelFormat fmt):
|
||||
mScreen(nullptr),
|
||||
mRender(nullptr)
|
||||
{
|
||||
if (nullptr == hwnd) {
|
||||
}
|
||||
// SDL part
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
|
||||
printf("Could not initialize SDL - %s\n", SDL_GetError());
|
||||
}
|
||||
this->mInWidth = width;
|
||||
this->mInHeight = height;
|
||||
screen_w = 640;
|
||||
screen_h = 480;
|
||||
//SDL 2.0 Support for multiple windows
|
||||
/*
|
||||
screen = SDL_CreateWindow("Simplest ffmpeg player's Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||
screen_w, screen_h,
|
||||
SDL_WINDOW_OPENGL);*/
|
||||
if (nullptr == mScreen) {
|
||||
mScreen = SDL_CreateWindowFrom((void *)hwnd);
|
||||
printf("SDL: could not create window - exiting:%s\n", SDL_GetError());
|
||||
}
|
||||
mRender = SDL_CreateRenderer(mScreen, -1, 0);
|
||||
SDL_GetWindowSize(mScreen, &screen_w, &screen_h);
|
||||
Debuger::Debug(L"pix width %d height %d\r\n",screen_w,screen_h);
|
||||
//IYUV: Y + U + V (3 planes)
|
||||
//YV12: Y + V + U (3 planes)
|
||||
mTexture = SDL_CreateTexture(mRender, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING,
|
||||
screen_w, screen_h);
|
||||
this->mFormat = fmt;
|
||||
}
|
||||
|
||||
SDLPlayser::~SDLPlayser()
|
||||
|
||||
{
|
||||
SDL_DestroyWindow(mScreen);
|
||||
SDL_DestroyRenderer(mRender);
|
||||
}
|
||||
|
||||
// 强制把其他个数的数据转换成libav可以认得到的数据
|
||||
int forceYUV420PBuffer(uint8_t * src, int size,int inWidth,int inHeight,
|
||||
AVPixelFormat format, uint8_t **dst[4], int *len,int mWidth,int mHeight)
|
||||
{
|
||||
uint8_t *src_data[4];
|
||||
int src_linesize[4];
|
||||
uint8_t *dst_data[4];
|
||||
int dst_linesize[4];
|
||||
struct SwsContext *img_convert_ctx;
|
||||
int ret = 0;
|
||||
|
||||
if (nullptr == dst || nullptr == len) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
int src_bpp = av_get_bits_per_pixel(av_pix_fmt_desc_get(format));
|
||||
AVPixelFormat dst_pixfmt = AV_PIX_FMT_YUV420P;
|
||||
int dst_bpp = av_get_bits_per_pixel(av_pix_fmt_desc_get(dst_pixfmt));
|
||||
|
||||
ret = av_image_alloc(src_data, src_linesize, inWidth, inHeight, format, 1);
|
||||
if (ret< 0) {
|
||||
Debuger::Debug(L"Could not allocate source image\n");
|
||||
return -1;
|
||||
}
|
||||
ret = av_image_alloc(dst_data, dst_linesize, mWidth, mHeight, AV_PIX_FMT_YUV420P, 1);
|
||||
if (ret< 0) {
|
||||
Debuger::Debug(L"Could not allocate destination image\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
img_convert_ctx = sws_alloc_context();
|
||||
//Show AVOption
|
||||
//av_opt_show2(img_convert_ctx, stdout, AV_OPT_FLAG_VIDEO_PARAM, 0);
|
||||
//Set Value
|
||||
av_opt_set_int(img_convert_ctx, "sws_flags", SWS_BICUBIC | SWS_PRINT_INFO, 0);
|
||||
av_opt_set_int(img_convert_ctx, "srcw", inWidth, 0);
|
||||
av_opt_set_int(img_convert_ctx, "srch", inHeight, 0);
|
||||
av_opt_set_int(img_convert_ctx, "src_format", format, 0);
|
||||
//'0' for MPEG (Y:0-235);'1' for JPEG (Y:0-255)
|
||||
av_opt_set_int(img_convert_ctx, "src_range", 1, 0);
|
||||
av_opt_set_int(img_convert_ctx, "dstw", mWidth, 0);
|
||||
av_opt_set_int(img_convert_ctx, "dsth", mHeight, 0);
|
||||
av_opt_set_int(img_convert_ctx, "dst_format", dst_pixfmt, 0);
|
||||
av_opt_set_int(img_convert_ctx, "dst_range", 1, 0);
|
||||
sws_init_context(img_convert_ctx, NULL, NULL);
|
||||
|
||||
// 设置输入
|
||||
switch (format) {
|
||||
case AV_PIX_FMT_GRAY8: {
|
||||
memcpy(src_data[0], src, inWidth*inHeight);
|
||||
break;
|
||||
}
|
||||
case AV_PIX_FMT_YUV420P: {
|
||||
memcpy(src_data[0], src, inWidth*inHeight); //Y
|
||||
memcpy(src_data[1], src + inWidth*inHeight, inWidth*inHeight / 4); //U
|
||||
memcpy(src_data[2], src + inWidth*inHeight * 5 / 4, inWidth*inHeight / 4); //V
|
||||
break;
|
||||
}
|
||||
case AV_PIX_FMT_YUV422P: {
|
||||
memcpy(src_data[0], src, inWidth*inHeight); //Y
|
||||
memcpy(src_data[1], src + inWidth*inHeight, inWidth*inHeight / 2); //U
|
||||
memcpy(src_data[2], src + inWidth*inHeight * 3 / 2, inWidth*inHeight / 2); //V
|
||||
break;
|
||||
}
|
||||
case AV_PIX_FMT_YUV444P: {
|
||||
memcpy(src_data[0], src, inWidth*inHeight); //Y
|
||||
memcpy(src_data[1], src + inWidth*inHeight, inWidth*inHeight); //U
|
||||
memcpy(src_data[2], src + inWidth*inHeight * 2, inWidth*inHeight); //V
|
||||
break;
|
||||
}
|
||||
case AV_PIX_FMT_YUYV422: {
|
||||
memcpy(src_data[0], src, inWidth*inHeight * 2); //Packed
|
||||
break;
|
||||
}
|
||||
case AV_PIX_FMT_RGB24: {
|
||||
memcpy(src_data[0], src, inWidth*inHeight * 3); //Packed
|
||||
break;
|
||||
}
|
||||
case AV_PIX_FMT_RGB32: {
|
||||
memcpy(src_data[0], src, inWidth*inHeight * 4); //Packed
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
Debuger::Debug(L"Not Support Input Pixel Format.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (FALSE)
|
||||
{
|
||||
src_linesize[0] = -inHeight;
|
||||
src_data[0] += inWidth*(src_linesize[0] - 1);
|
||||
// 转换数据
|
||||
ret = sws_scale(img_convert_ctx, src_data, src_linesize,
|
||||
0, inHeight, dst_data, dst_linesize);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
else{
|
||||
ret = sws_scale(img_convert_ctx, src_data, src_linesize,
|
||||
0, inHeight, dst_data, dst_linesize);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
memcpy(dst[0], dst_data[0], mWidth*mHeight);
|
||||
memcpy(dst[1], dst_data[1], mWidth*mHeight / 4);
|
||||
memcpy(dst[2], dst_data[2], mWidth*mHeight / 4);
|
||||
|
||||
*len = mWidth*mHeight + mWidth*mHeight / 2;
|
||||
// source此时就不需要了,但是dst要在外面free
|
||||
av_freep(&src_data[0]);
|
||||
av_freep(&dst_data[0]);
|
||||
|
||||
sws_freeContext(img_convert_ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDLPlayser::RenderYuv(void * pBuf, uint32_t size, AVPixelFormat pix)
|
||||
{
|
||||
uint8_t *pFrame[4];
|
||||
int iFramesize;
|
||||
int lineSize[4];
|
||||
static FILE *pFile = nullptr;
|
||||
|
||||
if (nullptr == pFile) {
|
||||
pFile = fopen("test.yuv", "wb");
|
||||
}
|
||||
int ret = av_image_alloc(pFrame, lineSize, 640, 480, AV_PIX_FMT_YUV420P, 1);
|
||||
if (ret< 0) {
|
||||
Debuger::Debug(L"Could not allocate destination image\n");
|
||||
}
|
||||
forceYUV420PBuffer((uint8_t *)pBuf, size,this->mInWidth,this->mInHeight, this->mFormat
|
||||
,(uint8_t ***)&pFrame, &iFramesize, 640, 480);
|
||||
SDL_UpdateYUVTexture(mTexture, &sdlRect,
|
||||
pFrame[0], lineSize[0],
|
||||
pFrame[1], lineSize[1],
|
||||
pFrame[2], lineSize[2]);
|
||||
//SDL_UpdateTexture(sdlTexture, NULL, picture->data[0], 1280);
|
||||
/*
|
||||
SDL_UpdateYUVTexture(sdlTexture, &sdlRect,
|
||||
picture->data[0], picture->linesize[0],
|
||||
picture->data[1], picture->linesize[1],
|
||||
picture->data[2], picture->linesize[2]);
|
||||
*/
|
||||
SDL_RenderClear(mRender);
|
||||
sdlRect.x = 0;
|
||||
sdlRect.y = 0;
|
||||
sdlRect.w = screen_w;
|
||||
sdlRect.h = screen_h;
|
||||
//fwrite(pFrame[0], lineSize[0]*480,1 ,pFile);
|
||||
//fwrite(pFrame[1], lineSize[1] * 480 ,1, pFile);
|
||||
//fwrite(pFrame[2], lineSize[2] * 480 ,1, pFile);
|
||||
|
||||
fflush(pFile);
|
||||
|
||||
SDL_RenderCopy(mRender, mTexture, nullptr, &sdlRect);
|
||||
SDL_RenderPresent(mRender);
|
||||
|
||||
av_freep(&pFrame[0]);
|
||||
free(pFrame[0]);
|
||||
//Debuger::Debug(L"local screen size is %d %d\r\n", screen_w, screen_h);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int forceYUV420P(AVFrame * picture,uint8_t **dst[4], int *len,int width,int height)
|
||||
{
|
||||
uint8_t *dst_data[4];
|
||||
int dst_linesize[4];
|
||||
|
||||
struct SwsContext *img_convert_ctx;
|
||||
int ret = 0;
|
||||
if (nullptr == dst || nullptr == len) {
|
||||
return -2;
|
||||
}
|
||||
AVPixelFormat dst_pixfmt = AV_PIX_FMT_YUV420P;
|
||||
int dst_bpp = av_get_bits_per_pixel(av_pix_fmt_desc_get(dst_pixfmt));
|
||||
|
||||
|
||||
ret = av_image_alloc(dst_data, dst_linesize, width, height, AV_PIX_FMT_YUV420P, 1);
|
||||
if (ret< 0) {
|
||||
Debuger::Debug(L"Could not allocate destination image\n");
|
||||
return -1;
|
||||
}
|
||||
img_convert_ctx = sws_alloc_context();
|
||||
//Show AVOption
|
||||
//av_opt_show2(img_convert_ctx, stdout, AV_OPT_FLAG_VIDEO_PARAM, 0);
|
||||
//Set Value
|
||||
av_opt_set_int(img_convert_ctx, "sws_flags", SWS_BICUBIC | SWS_PRINT_INFO, 0);
|
||||
av_opt_set_int(img_convert_ctx, "srcw", picture->width, 0);
|
||||
av_opt_set_int(img_convert_ctx, "srch", picture->height, 0);
|
||||
av_opt_set_int(img_convert_ctx, "src_format", dst_pixfmt, 0);
|
||||
//'0' for MPEG (Y:0-235);'1' for JPEG (Y:0-255)
|
||||
av_opt_set_int(img_convert_ctx, "src_range", 1, 0);
|
||||
av_opt_set_int(img_convert_ctx, "dstw", width, 0);
|
||||
av_opt_set_int(img_convert_ctx, "dsth", height, 0);
|
||||
av_opt_set_int(img_convert_ctx, "dst_format", dst_pixfmt, 0);
|
||||
av_opt_set_int(img_convert_ctx, "dst_range", 1, 0);
|
||||
sws_init_context(img_convert_ctx, NULL, NULL);
|
||||
|
||||
// 转换数据
|
||||
ret = sws_scale(img_convert_ctx, picture->data, picture->linesize, 0, picture->height,
|
||||
dst_data, dst_linesize);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
memcpy(dst[0], dst_data[0], width*height);
|
||||
memcpy(dst[1], dst_data[1], width*height / 4);
|
||||
memcpy(dst[2], dst_data[2], width*height / 4);
|
||||
|
||||
// source此时就不需要了,但是dst要在外面free
|
||||
av_freep(&dst_data[0]);
|
||||
|
||||
sws_freeContext(img_convert_ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 输入参数一定YUV 420P的情况
|
||||
int SDLPlayser::OnRecieveData(AVFrame * picture)
|
||||
{
|
||||
|
||||
uint8_t *pFrame[4];
|
||||
int iFramesize;
|
||||
int lineSize[4];
|
||||
|
||||
int ret = av_image_alloc(pFrame, lineSize, 640, 480, AV_PIX_FMT_YUV420P, 1);
|
||||
if (ret< 0) {
|
||||
Debuger::Debug(L"Could not allocate destination image\n");
|
||||
}
|
||||
forceYUV420P(picture, (uint8_t ***)&pFrame, &iFramesize, 640, 480);
|
||||
|
||||
uint32_t pitchY = picture->linesize[0];
|
||||
uint32_t pitchU = picture->linesize[1];
|
||||
uint32_t pitchV = picture->linesize[2];
|
||||
|
||||
uint8_t *avY = picture->data[0];
|
||||
uint8_t *avU = picture->data[1];
|
||||
uint8_t *avV = picture->data[2];
|
||||
|
||||
SDL_UpdateYUVTexture(mTexture, &sdlRect,
|
||||
pFrame[0], lineSize[0],
|
||||
pFrame[1], lineSize[1],
|
||||
pFrame[2], lineSize[2]);
|
||||
//SDL_UpdateTexture(sdlTexture, NULL, picture->data[0], 1280);
|
||||
/*
|
||||
SDL_UpdateYUVTexture(sdlTexture, &sdlRect,
|
||||
picture->data[0], picture->linesize[0],
|
||||
picture->data[1], picture->linesize[1],
|
||||
picture->data[2], picture->linesize[2]);
|
||||
*/
|
||||
SDL_RenderClear(mRender);
|
||||
sdlRect.x = 0;
|
||||
sdlRect.y = 0;
|
||||
sdlRect.w = screen_w;
|
||||
sdlRect.h = screen_h;
|
||||
|
||||
|
||||
SDL_RenderCopy(mRender, mTexture, nullptr, &sdlRect);
|
||||
SDL_RenderPresent(mRender);
|
||||
|
||||
av_freep(&pFrame[0]);
|
||||
free(pFrame[0]);
|
||||
//Debuger::Debug(L"remote screen size is %d %d\r\n", screen_w, screen_h);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDLPlayser::OnBuffer(double dblSampleTime, BYTE * pBuffer, long lBufferSize)
|
||||
{
|
||||
this->RenderYuv(pBuffer, lBufferSize, this->mFormat);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDLPlayser::OnCameraData(uint8_t * dat, uint32_t size)
|
||||
{
|
||||
this->RenderYuv(dat, size, AV_PIX_FMT_YUYV422);
|
||||
return 0;
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
QT += core gui
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
QT += network
|
||||
|
||||
TARGET = yuvgl
|
||||
TEMPLATE = app
|
||||
|
@ -29,15 +30,6 @@ SOURCES += \
|
|||
mainwindow.cpp \
|
||||
cplaywidget.cpp \
|
||||
media/AACAudioCoder.cpp \
|
||||
media/AACDecoder.cpp \
|
||||
media/AudioCapture.cpp \
|
||||
media/AudioPlayer.cpp \
|
||||
media/CameraCapture.cpp \
|
||||
media/H264Docoder.cpp \
|
||||
media/ImageUtil.cpp \
|
||||
media/SdlPlayer.cpp \
|
||||
media/VideoCoder.cpp \
|
||||
media/sps_decode.cpp \
|
||||
utils/Base64.cpp \
|
||||
utils/Debuger.cpp \
|
||||
utils/utils.cpp
|
||||
|
@ -54,35 +46,10 @@ FORMS += \
|
|||
INCLUDEPATH += media/ third/ffmpeg/include/ inc/ third/
|
||||
message($$PWD/third/libs/)
|
||||
LIBS += -L$$PWD/third/libs/
|
||||
LIBS += -lws2_32
|
||||
LIBS += -lm
|
||||
LIBS += -lgcc
|
||||
win32: LIBS += -llibavcodec
|
||||
win32: LIBS += -llibrtmp
|
||||
win32: LIBS += -llibswscale
|
||||
win32: LIBS += -llibswresample
|
||||
win32: LIBS += -llibavresample
|
||||
win32: LIBS += -llibavformat
|
||||
win32: LIBS += -llibavdevice
|
||||
win32: LIBS += -llibavfilter
|
||||
win32: LIBS += -llibavutil
|
||||
win32: LIBS += -llibpostproc
|
||||
LIBS += -lavformat -lavdevice -lavcodec -lavutil -lswresample -lpthread -lbz2 -lm -lfdk-aac -lx264 -lOle32 -lbcrypt -liconv -lucrtbase
|
||||
|
||||
win32: LIBS += -lSecur32
|
||||
win32: LIBS += -lSDL2
|
||||
win32: LIBS += -lSDL2main
|
||||
win32: LIBS += -lportaudio_x86
|
||||
win32: LIBS += -llibx264
|
||||
win32: LIBS += -lOle32
|
||||
win32: LIBS += -lstrmiids
|
||||
win32: LIBS += -lquartz
|
||||
win32: LIBS += -lSDL2
|
||||
win32: LIBS += -lSDL2main
|
||||
win32: LIBS += -lOleAut32
|
||||
win32: LIBS += $$PWD/third/libs/chkstk.obj
|
||||
win32: LIBS += -lbufferoverflowU
|
||||
win32: LIBS += -lbufferoverflow
|
||||
win32: LIBS += -lmsvcrt
|
||||
win32: LIBS += -llibfdk-aac
|
||||
|
||||
# Default rules for deployment.
|
||||
qnx: target.path = /tmp/$${TARGET}/bin
|
||||
|
|
Loading…
Reference in New Issue