简单播放器

MyQueue.h

#pragma once
#include <Windows.h>
#include <vector>
#include <SDL.h>
using namespace std; typedef struct T_Data
{
public:
T_Data()
{
m_pBuf = NULL;
m_iLen = ;
m_iBufLen = ;
}
char *m_pBuf;
int m_iLen;
int m_iBufLen;
}T_Data; class CMyQueue
{
public:
CMyQueue(void);
~CMyQueue(); bool PushData(char *pData, int iLen);
T_Data *PopData();
bool AddFreeDataToV(T_Data *);
void QueueExit();
int QueueSize();
void CleanBuf();
public:
vector<T_Data *> m_vData;
vector<T_Data *> m_vFree;
bool m_bLoop;
unsigned int m_iPacketNum;
SDL_mutex *m_mutex; //
SDL_cond *m_cond; // 条件变量
};

MyQueue.cpp

#include "MyQueue.h"

CMyQueue::CMyQueue(void)
{
m_mutex = SDL_CreateMutex();
m_cond = SDL_CreateCond();
m_bLoop = true;
m_iPacketNum = ;
} CMyQueue::~CMyQueue()
{
m_bLoop = false;
int iCoune = m_vFree.size();
while (iCoune > )
{
T_Data *pstData = m_vFree.at();
m_vFree.erase(m_vFree.begin());
if (pstData)
{
if (pstData->m_pBuf)
{
delete [] pstData->m_pBuf;
pstData->m_pBuf = NULL;
}
delete pstData;
pstData = NULL;
}
iCoune--;
} iCoune = m_vData.size();
while (iCoune > )
{
T_Data *pstData = m_vData.at();
m_vData.erase(m_vData.begin());
if (pstData)
{
if (pstData->m_pBuf)
{
delete [] pstData->m_pBuf;
pstData->m_pBuf = NULL;
}
delete pstData;
pstData = NULL;
}
iCoune--;
} SDL_DestroyMutex(m_mutex);
SDL_DestroyCond(m_cond);
} bool CMyQueue::PushData(char *pData, int iLen)
{
bool bRet = true;
if (NULL == pData || >= iLen || !m_bLoop)
{
return false;
}
SDL_LockMutex(m_mutex);
if (m_vFree.size() > )
{
T_Data *stTemp = m_vFree.at();
m_vFree.erase(m_vFree.begin());
if (stTemp->m_iBufLen >= iLen)
{
memcpy(stTemp->m_pBuf, pData, iLen);
stTemp->m_iLen = iLen;
}
else
{
delete [] stTemp->m_pBuf;
stTemp->m_iBufLen = stTemp->m_iLen = iLen;
stTemp->m_pBuf = new char[iLen];
memcpy(stTemp->m_pBuf, pData, iLen);
}
m_vData.push_back(stTemp);
}
else
{
T_Data *stTemp = new T_Data;
if (stTemp)
{
stTemp->m_iBufLen = stTemp->m_iLen = iLen;
stTemp->m_pBuf = new char[iLen];
memcpy(stTemp->m_pBuf, pData, iLen);
m_vData.push_back(stTemp);
}
else
{
bRet = false;
}
}
m_iPacketNum++;
SDL_CondSignal(m_cond);
SDL_UnlockMutex(m_mutex);
return bRet;
}
T_Data *CMyQueue::PopData()
{
T_Data *pstData = NULL;
SDL_LockMutex(m_mutex);
while (m_bLoop)
{
if (m_vData.size() > )
{
pstData = m_vData.at();
m_vData.erase(m_vData.begin());
m_iPacketNum--;
break;
}
else
{
SDL_CondWait(m_cond, m_mutex);
}
} SDL_UnlockMutex(m_mutex);
return pstData;
}
bool CMyQueue::AddFreeDataToV(T_Data * pFree)
{
SDL_LockMutex(m_mutex);
m_vFree.push_back(pFree);
SDL_UnlockMutex(m_mutex);
return true;
} void CMyQueue::QueueExit()
{
m_bLoop = false;
SDL_CondSignal(m_cond);
} int CMyQueue::QueueSize()
{
return m_iPacketNum;
} void CMyQueue::CleanBuf()
{
SDL_LockMutex(m_mutex);
while (m_vData.size() > )
{
T_Data *pstData = m_vData.at();
m_vData.erase(m_vData.begin());
m_vFree.push_back(pstData);
}
m_iPacketNum = ;
SDL_UnlockMutex(m_mutex);
}

cplayer.h

#ifndef CPLAYER_H
#define CPLAYER_H #include <QObject>
#include <QWidget>
#include <QThread>
#include "MyQueue.h"
#include "SDL.h" class CPlayer
{
public:
CPlayer();
~CPlayer(); void SetWinID(void*id){m_pWinID = id;}
void SetRect(int x, int y, int w, int h){m_rect.x = x; m_rect.y = y;
m_rect.w = w; m_rect.h = h;}
void PushVideo(char *pData, int iLen);
static DWORD WINAPI ThreadPlay(LPVOID p);
void PlayVideo();
void SDLInit();
void SDLUninit();
int CutBandYUV(char*pInBuf, int width, int height, char *pOutBuf,
int x, int y, int w, int h); public:
SDL_Rect m_rect;
SDL_Window *m_pWindow;
SDL_Texture* m_pTexture;
SDL_Renderer* m_pRenderer;
CMyQueue *m_pVideoQueue;
HANDLE m_hThread;
bool m_bLoop;
void* m_pWinID;
}; #endif // CPLAYER_H

cplayer.cpp

#include "cplayer.h"
extern int g_iWidth;
extern int g_iHeiht;
CPlayer::CPlayer()
{
m_pWinID = NULL;
m_pTexture = NULL;
m_pRenderer = NULL;
m_pVideoQueue = NULL;
m_pWindow = NULL;
m_hThread = NULL;
m_bLoop = false;
} CPlayer::~CPlayer()
{
SDLUninit();
} void CPlayer::SDLInit()
{
if (NULL == m_pVideoQueue)
{
m_pVideoQueue = new CMyQueue;
}
if(NULL == m_pWindow)
{
m_pWindow = SDL_CreateWindowFrom((void*)m_pWinID);
}
else
{
return;
} if (NULL == m_pRenderer)
{
m_pRenderer = SDL_CreateRenderer( m_pWindow, -, SDL_RENDERER_ACCELERATED);
}
if (NULL == m_pRenderer)
{
m_pRenderer = SDL_CreateRenderer( m_pWindow, -, SDL_RENDERER_SOFTWARE);
}
if (NULL == m_pRenderer)
{
return;
} if (NULL == m_pTexture)
{
int w, h;
SDL_GetWindowSize(m_pWindow, &w, &h);
m_pTexture = SDL_CreateTexture( m_pRenderer,SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING, g_iWidth, g_iHeiht );
}
else
{
return;
}
if(NULL == m_hThread)
{
m_bLoop = true;
m_hThread = CreateThread(NULL, , ThreadPlay, this, , NULL);
}
} void CPlayer::SDLUninit()
{
m_bLoop = false;
if (m_pVideoQueue)
{
m_pVideoQueue->QueueExit();
}
if (m_hThread)
{
WaitForSingleObject(m_hThread, INFINITE);
CloseHandle(m_hThread);
m_hThread = NULL;
} if (m_pVideoQueue)
{
delete m_pVideoQueue;
m_pVideoQueue = NULL;
} if (m_pTexture)
{
SDL_DestroyTexture(m_pTexture);
m_pTexture = NULL;
}
if (m_pRenderer)
{
SDL_DestroyRenderer(m_pRenderer);
m_pRenderer = NULL;
} if (m_pWindow)
{
//SDL_DestroyWindow(m_SDLScreen);
m_pWindow = NULL;
}
} void CPlayer::PushVideo(char *pData, int iLen)
{
if (NULL == m_hThread)
{
SDLInit();
}
if (m_pVideoQueue && m_pTexture)
{
m_pVideoQueue->PushData(pData, iLen);
}
} DWORD WINAPI CPlayer::ThreadPlay(LPVOID p)
{
CPlayer *pPlay = (CPlayer*)p;
if(pPlay)
{
pPlay->PlayVideo();
}
return ;
} void CPlayer::PlayVideo()
{
int w = , h = ;
if (m_pWindow)
{
SDL_GetWindowSize(m_pWindow, &w, &h);
}
int OutLen = w * h * / ;
char *outBuf = new char[OutLen];
while (m_bLoop)
{
T_Data *pstData = m_pVideoQueue->PopData();
if(NULL == pstData)
{
QThread::msleep();
continue;
}
char *pData = pstData->m_pBuf;
int iLen = pstData->m_iLen; //CutBandYUV(pData, g_iWidth, g_iHeiht, outBuf, m_rect.x, m_rect.y, m_rect.w, m_rect.h); if (m_pTexture)
{
SDL_UpdateTexture( m_pTexture, NULL, pData, g_iWidth);
SDL_RenderClear( m_pRenderer );
// SDL_RenderCopy( m_pRenderer, m_pTexture, &m_rect, NULL);//只显示m_rect范围的内容
SDL_RenderCopy( m_pRenderer, m_pTexture, NULL, NULL);//显示完整内容
SDL_RenderPresent( m_pRenderer );
}
m_pVideoQueue->AddFreeDataToV(pstData);
}
if(outBuf)
{
delete [] outBuf;
outBuf = NULL;
}
} int CPlayer::CutBandYUV(char*pInBuf, int width, int height, char *pOutBuf, int new_x, int new_y, int new_width, int new_height)
{
int x = ;
int y = ;
if (NULL == pInBuf || == width || == height)
return -; char *pUBuf = pOutBuf + new_width * new_height;
char *pVBuf = pOutBuf + new_width * new_height * / ;
for (x = ; x < new_width; x++)
{
for (y = ; y < new_height; y++) //每个循环写一列
{
*(pOutBuf + y * new_width + x) = *(pInBuf + (x + new_x) + width * (y + new_y)); //cope Y
int ret = (y + new_y) % ;
if ( == (x + new_x) % && == (y + new_y) % )
{
long pix = width * height + (width >> ) * ((y + new_y) >> ) + (((x + new_x)) >> );
*(pUBuf + (new_width / )*(y / ) + x / ) = *(pInBuf + pix); //cope U pix += width * height / ;
*(pVBuf + (new_width / )*(y / ) + x / ) = *(pInBuf + pix); //cope V
}
}
}
return ;
}

MyPlayer的更多相关文章

  1. 2016.8.14安装myplayer心得

    安装mplayer时,我有两个os是not found状态,我在其他地方找到后 which mplayer,找到mplayer的配置界面,找到not found的部分,并且从usr/lib中找到相应的 ...

  2. 《Note --- Unreal 4 --- Sample analyze --- StrategyGame(continue...)》

    ---------------------------------------------------------------------------------------------------- ...

  3. 前段播放 流媒体(RTMP,RTSP,HLS)

    前言 最近项目需要流媒体的播放,后端一共提供了 三种流数据(RTSP,RTMP,HLS),在不同的场景可能会使用到不同方式播放,就需要做到适配, 支持所有的流数据播放.花了一段时间研究,在这里和大家分 ...

  4. 一款开源免费跨浏览器的视频播放器--videojs使用介绍

    最近项目中的视频功能,需要做到浏览器全兼容,所以之前用html5实现的视频功能就需要进行改造了.在网上翻了个遍,试来试去,在所有的视频播放器中,就数它最实际了.首先我们来看看它的优点: 1.它是开源免 ...

  5. 一款全兼容的播放器 videojs

    [官网]http://www.videojs.com/ videojs就提供了这样一套解决方案,他是一个兼容HTML5的视频播放工具,早期版本兼容所有浏览器,方法是:提供三个后缀名的视频,并在不支持h ...

  6. video.js使用教程API

    videojs就提供了这样一套解决方案,他是一个兼容html5的视频播放工具,早期版本兼容所有浏览器,方法是:提供三个后缀名的视频,并在不支持html5的浏览器下生成一个flash的版本. 最新的3. ...

  7. Unity3d 制作物品平滑运动

    直接贴代码了 using UnityEngine; using System; using System.Collections; using System; using DataTable; pub ...

  8. The Parallel Challenge Ballgame[HDU1101]

    The Parallel Challenge Ballgame Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K ( ...

  9. QT开发编译问题备忘

    编译<Qt及Qt Quick开发实战精解> 的代码,编译出错,提示: Cannot find file: E:\学习资料\QT\<Qt及Qt Quick开发实战精解>代码\sr ...

随机推荐

  1. 三维空间建模方法之LOD模型算法

    什么是LOD LOD也称为层次细节模型,是一种实时三维计算机图形技术,最先由Clark于1976年提出,其工作原理是: 视点离物体近时,能观察到的模型细节丰富:视点远离模型时,观察到的细节逐渐模糊.系 ...

  2. [转帖]IBM 开源 POWER 指令集架构

    IBM 开源 POWER 指令集架构 https://www.solidot.org/story?sid=61791 新闻越短 事情越严重 IBM 破釜沉舟 OpenPOWER 联盟国产化披荆斩棘? ...

  3. 什么是DataV数据可视化

    DataV数据可视化是使用可视化大屏的方式来分析并展示庞杂数据的产品.DataV旨让更多的人看到数据可视化的魅力,帮助非专业的工程师通过图形化的界面轻松搭建专业水准的可视化应用,满足您会议展览.业务监 ...

  4. C/C++快读(快速读入)有多——安全AC

    在一些算法题目中中,有的程序会被卡常(数),就是说,程序虽然渐进复杂度,(通俗来讲:算法的时间复杂度)可以接受,但因为算法本身的时间常数过大,导致程序在一些算法竞赛中超时.这是,快读就显得尤为重要了. ...

  5. python+selenium+webdriver+BeautifulSoup实现自动登录

    from selenium import webdriverimport timefrom bs4 import BeautifulSoupfrom urllib import requestimpo ...

  6. Linux (x86) Exploit 开发系列教程之四(使用return-to-libc绕过NX bit)

    (1)原理: “NX Bit”的漏洞缓解:使某些内存区域不可执行,并使可执行区域不可写.示例:使数据,堆栈和堆段不可执行,而代码段不可写. 在NX bit打开的情况下,基于堆栈的缓冲区溢出的经典方法将 ...

  7. 贝叶斯优化 Bayesian Optimization

    贝叶斯优化 Bayesian Optimization 2018年07月02日 22:28:06 余生最年轻 阅读数 4821更多 分类专栏: 机器学习   版权声明:本文为博主原创文章,遵循CC 4 ...

  8. .Net C# RSA签名和验签

    帮助类 using System; using System.Text; using System.IO; using System.Security.Cryptography; namespace ...

  9. 怎样理解"不推荐不使用var的变量声明方式"这句话

    答: 因为不使用var声明的变量不会被预解析, 如下: console.log(a); console.log(b); var a = 1; b = 2;

  10. Unity 屏幕坐标到UGUI RectTransform本地坐标的转换

    public static bool ScreenPointToLocalPointInRectangle(RectTransform rect, Vector2 screenPoint, Camer ...