#include "ceewavideouseffmpeg.h"
#define SFM_REFRESH_EVENT (SDL_USEREVENT + 1)
#define SFM_END_EVENT (SDL_USEREVENT + 2)
int sdl_thread_exit=0;
int sdl_event_thread(void *opaque)
{
while (sdl_thread_exit==0)
{
SDL_Event event;
event.type = SFM_REFRESH_EVENT;
SDL_PushEvent(&event);
SDL_Delay(50);
}
return 0;
}
CeewaVideoUseFFmpeg::CeewaVideoUseFFmpeg(QWidget *showView,QObject *parent) :
QThread(parent)
{
m_showWidget = showView;
playMode = 1;
screen = NULL;
screen_w = showView->width();
screen_h = showView->height();
isNeedReCreateScreen = true;
renderer = NULL;
mainVideoState = 0;
myFirstDecoder = new CeewaVideoFFmpegDecoder("http://live.gslb.letv.com/gslb?stream_id=lb_movie_720p&tag=live&ext=m3u8&sign=live_tv&platid=10&splatid=1009&format=letv&expect=1",1);//http://live.gslb.letv.com/gslb?stream_id=lb_1080P_1080p3m&tag=live&ext=m3u8&sign=live_tv&platid=10&splatid=1009&format=letv&expect=1",this);
mySecondDecoder = new CeewaVideoFFmpegDecoder("http://live.gslb.letv.com/gslb?stream_id=lb_1080P_1080p3m&tag=live&ext=m3u8&sign=live_tv&platid=10&splatid=1009&format=letv&expect=1",1);//http://live.gslb.letv.com/gslb?stream_id=lb_movie_720p&tag=live&ext=m3u8&sign=live_tv&platid=10&splatid=1009&format=letv&expect=1",this);
connect(myFirstDecoder,SIGNAL(notifyDecodeFrame(AVFrame*,uint8_t* )),this,SLOT(onNotifyLightView(AVFrame*,uint8_t*)));
connect(mySecondDecoder,SIGNAL(notifyDecodeFrame(AVFrame*,uint8_t* )),this,SLOT(onNotifyHWView(AVFrame*,uint8_t*)));
myFirstDecoder->play();
mySecondDecoder->play();
smallSrc.x = 0;
smallSrc.y = 0;
smallSrc.w = 0;
smallSrc.h = 0;
smallDesc.x = m_showWidget->width() - 16*30;
smallDesc.y = m_showWidget->height() - 9*30;
smallDesc.w = 16*30;
smallDesc.h = 9*30;
bmp = NULL;
bmp_other = NULL;
isStop = false;
}
void CeewaVideoUseFFmpeg::onNotifyNormalPlay(QString url)
{
playMode = 1;
myFirstDecoder->play(url);
emit openRealTimeVideoResult(true);
}
void CeewaVideoUseFFmpeg::onNotifyDoublePlay(QString url, QString otherUrl)
{
playMode = 2;
myFirstDecoder->play(url);
mySecondDecoder->play(otherUrl);
emit openRealTimeVideoResult(true);
}
void CeewaVideoUseFFmpeg::onNotifyHWView(AVFrame* pFrameYUV,uint8_t* buffer)
{
m_bmp_other_lock.lockForWrite();
if(NULL == bmp_other)
{
bmp_other = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING,mySecondDecoder->showWidth,mySecondDecoder->showHeight);
}
SDL_UpdateTexture(bmp_other, NULL, pFrameYUV->data[0], pFrameYUV->linesize[0]);
m_bmp_other_lock.unlock();
av_free(pFrameYUV);
av_free(buffer);
}
void CeewaVideoUseFFmpeg::onNotifyLightView(AVFrame* pFrameYUV,uint8_t* buffer)
{
m_bmp_lock.lockForWrite();
if(NULL == bmp)
{
bmp = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING,myFirstDecoder->showWidth,myFirstDecoder->showHeight);
//return;
}
SDL_UpdateTexture(bmp, NULL, pFrameYUV->data[0], pFrameYUV->linesize[0]);
m_bmp_lock.unlock();
av_free(pFrameYUV);
av_free(buffer);
}
bool CeewaVideoUseFFmpeg::init()
{
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER))
{
return false;
}
// if(TTF_Init() == -1)
// {
// logger->error("Init TTF failed.");
// return false;
// }
}
void CeewaVideoUseFFmpeg::stop()
{
myFirstDecoder->stop();
mySecondDecoder->stop();
}
void CeewaVideoUseFFmpeg::reCreateScreen()
{
if(isNeedReCreateScreen)
{
screen = SDL_CreateWindowFrom(m_showWidget->winId());
isNeedReCreateScreen = false;
renderer = SDL_CreateRenderer(screen, -1, SDL_RENDERER_SOFTWARE);
}
}
void CeewaVideoUseFFmpeg::onShowWidgetResize()
{
smallDesc.x = m_showWidget->width() - 16*30;
smallDesc.y = m_showWidget->height() - 9*30;
smallDesc.w = 16*30;
smallDesc.h = 9*30;
}
void CeewaVideoUseFFmpeg::run()
{
event = new SDL_Event();
video_tid = SDL_CreateThread(sdl_event_thread,NULL,NULL);
//主线程做视频显示 使用SDL渲染
while(!isStop)
{
SDL_WaitEvent(event);
if(event->type==SFM_REFRESH_EVENT)
{
SDL_RenderClear(renderer);
//判断当前主屏幕为可见光还是红外
if(0 == mainVideoState)
{
if(NULL != bmp)
{
m_bmp_lock.lockForRead();
SDL_RenderCopy(renderer, bmp, NULL, NULL);
m_bmp_lock.unlock();
}
if(NULL != bmp_other)
{
m_bmp_other_lock.lockForRead();
SDL_RenderCopy(renderer, bmp_other, NULL, &smallDesc);
m_bmp_other_lock.unlock();
}
}else
{
if(NULL != bmp_other)
{
m_bmp_other_lock.lockForRead();
SDL_RenderCopy(renderer, bmp_other, NULL, NULL);
m_bmp_other_lock.unlock();
}
if(NULL != bmp)
{
m_bmp_lock.lockForRead();
SDL_RenderCopy(renderer, bmp, NULL, &smallDesc);
m_bmp_lock.unlock();
}
}
SDL_RenderPresent(renderer);
}else if(event->type==SFM_END_EVENT)
{
sdl_thread_exit=1;
break;
}else if (event->type == SDL_WINDOWEVENT)
{
SDL_GetWindowSize(screen, &screen_w, &screen_h);
}
else
{
continue;
}
}
//数据回收
if(bmp)
{
SDL_DestroyTexture(bmp);
}
if(bmp_other)
{
SDL_DestroyTexture(bmp_other);
}
if(renderer)
{
SDL_DestroyRenderer(renderer);
}
}
void CeewaVideoUseFFmpeg::showView()
{
if(0 == mainVideoState)
{
if(NULL != bmp)
{
m_bmp_lock.lockForRead();
SDL_RenderCopy(renderer, bmp, NULL, NULL);
m_bmp_lock.unlock();
}
if(NULL != bmp_other)
{
m_bmp_other_lock.lockForRead();
SDL_RenderCopy(renderer, bmp_other, NULL, &smallDesc);
m_bmp_other_lock.unlock();
}
}else
{
if(NULL != bmp_other)
{
m_bmp_other_lock.lockForRead();
SDL_RenderCopy(renderer, bmp_other, NULL, NULL);
m_bmp_other_lock.unlock();
}
if(NULL != bmp)
{
m_bmp_lock.lockForRead();
SDL_RenderCopy(renderer, bmp, NULL, &smallDesc);
m_bmp_lock.unlock();
}
}
SDL_RenderPresent(renderer);
}
void CeewaVideoUseFFmpeg::onNotifyChangeVideoState()
{
if(playMode == 1)
{
return;
}
if(0 == mainVideoState)
{
mainVideoState = 1;
}else
{
mainVideoState = 0;
}
}