MyPlayer
简单播放器
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的更多相关文章
- 2016.8.14安装myplayer心得
安装mplayer时,我有两个os是not found状态,我在其他地方找到后 which mplayer,找到mplayer的配置界面,找到not found的部分,并且从usr/lib中找到相应的 ...
- 《Note --- Unreal 4 --- Sample analyze --- StrategyGame(continue...)》
---------------------------------------------------------------------------------------------------- ...
- 前段播放 流媒体(RTMP,RTSP,HLS)
前言 最近项目需要流媒体的播放,后端一共提供了 三种流数据(RTSP,RTMP,HLS),在不同的场景可能会使用到不同方式播放,就需要做到适配, 支持所有的流数据播放.花了一段时间研究,在这里和大家分 ...
- 一款开源免费跨浏览器的视频播放器--videojs使用介绍
最近项目中的视频功能,需要做到浏览器全兼容,所以之前用html5实现的视频功能就需要进行改造了.在网上翻了个遍,试来试去,在所有的视频播放器中,就数它最实际了.首先我们来看看它的优点: 1.它是开源免 ...
- 一款全兼容的播放器 videojs
[官网]http://www.videojs.com/ videojs就提供了这样一套解决方案,他是一个兼容HTML5的视频播放工具,早期版本兼容所有浏览器,方法是:提供三个后缀名的视频,并在不支持h ...
- video.js使用教程API
videojs就提供了这样一套解决方案,他是一个兼容html5的视频播放工具,早期版本兼容所有浏览器,方法是:提供三个后缀名的视频,并在不支持html5的浏览器下生成一个flash的版本. 最新的3. ...
- Unity3d 制作物品平滑运动
直接贴代码了 using UnityEngine; using System; using System.Collections; using System; using DataTable; pub ...
- The Parallel Challenge Ballgame[HDU1101]
The Parallel Challenge Ballgame Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K ( ...
- QT开发编译问题备忘
编译<Qt及Qt Quick开发实战精解> 的代码,编译出错,提示: Cannot find file: E:\学习资料\QT\<Qt及Qt Quick开发实战精解>代码\sr ...
随机推荐
- Hadoop之HDFS客户端操作
1. HDFS 客户端环境准备 1.1 windows 平台搭建 hadoop 2.8.5 2. 创建Maven工程 # pom.xml <dependencies> <depend ...
- TensorFlow 官方文档 Programmer's Guide 中文翻译 —— 引言
TensorFlow Programmer's Guide (Introduction) TensorFlow 编程手册 (引言) #(本项目对tensorflow官网上给出的指导手册(TF1.3版本 ...
- Feign 接口上传文件
1)Encoder 配置注入容器 2) public class SpringFormEncoderExtension extends FormEncoder { /** * 使用默认的feign编码 ...
- Apache + PHP Yii框架跨域访问API
其实不用在Yii框架中设置任何东西,直接用Ajax调用不同域名的API即可 但是Apache中要这么设置: 首先编辑httpd.conf 去掉这一句的注释:LoadModule headers_ ...
- javaSE 笔记一
java 环境变量配置 步骤: 右键[计算机]图标 –>[属性]–>[高级系统设置]–>[环境变量] 在"系统变量"里找到"Path" ...
- LeetCode 2——两数相加(JAVA)
给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字. 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和 ...
- golang之工厂模式
说明: golang的结构体没有构造函数,通常可以使用工厂模式来解决这个问题 如果包里面的结构体变量首字母小写,引入后,不能直接使用,可以工厂模式解决: ch1.go package ch1 type ...
- 【第一季】CH06_FPGA设计Verilog基础(三)
[第一季]CH06_FPGA设计Verilog基础(三) 一个完整的设计,除了好的功能描述代码,对于程序的仿真验证是必不可少的.学会如何去验证自己所写的程序,即如何调试自己的程序是一件非常重要的事情. ...
- memcached基本操作指令
item执行命令: 第一行:Key Flags ExpirationTime BytesKey:Key 用于查找缓存值Flags:一个32位的标志值,客户机使用它存储关于键值对的额外信息Expirat ...
- MQTT协议探究(二)
1 回顾与本次目标 1.1 回顾 MQTT控制报文的基本格式 WireShark进行抓包分析了报文 报文分析: CONNECT--连接服务器 CONNACK--确认连接请求 PINGREQ--心跳请求 ...