简单播放器

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. Python实现二叉树的非递归中序遍历

    思路: 1. 使用一个栈保存结点(列表实现): 2. 如果结点存在,入栈,然后将当前指针指向左子树,直到为空: 3. 当前结点不存在,则出栈栈顶元素,并把当前指针指向栈顶元素的右子树: 4. 栈不为空 ...

  2. (六)Java秒杀项目之接口优化

    一.Redis预减库存减少数据库访问 思路:减少数据库访问 1.系统初始化,把商品库存数量加载到Redis 2.收到请求,Redis预减库存,库存不足,直接返回,否则进入3 3.请求入队,立即返回排队 ...

  3. java日志框架系列(2):logback框架详解

    1.logback介绍 1.什么是logback Logback 为取代 log4j 而生. Logback 由 log4j 的创立者 Ceki Gülcü设计.以十多年设计工业级记录系统的经验为基础 ...

  4. Scala 孤立对象和单例对象方法体的用法和例子

    [学习笔记] 1  以object关键字修饰一个类名,这种语法叫做孤立对象,这个对象是单例的. 相当于将单例类和单例对象同时定义.相当于java中的单例,即在内存中只会存在一个Test3实例.创建一个 ...

  5. javaSE 笔记一

    java 环境变量配置 步骤:   右键[计算机]图标 –>[属性]–>[高级系统设置]–>[环境变量]   在"系统变量"里找到"Path" ...

  6. 下载HTMLTestRunner 地址

    通过pip安装 HTMLTestRunne失败 则需要通过手动下载.  下载地址: http://tungwaiyip.info/software/HTMLTestRunner.html 下载后,把H ...

  7. python3 虚拟环境的创建

    创建虚拟环境的方法有很多种,我来分享一下我最常用的虚拟环境的创建方法和一些命令的使用, 什么是虚拟环境? 知道的可以略过,不知道的可以听我简单的说下.虚拟环境这四个字,一听你就明白什么意思了,首先理解 ...

  8. CSS实现单选按钮

    import React from 'react' import PropTypes from 'prop-types' import CX from 'classnames' import _ fr ...

  9. react的状态管理

    近两年前端技术的发展如火如荼,大量的前端项目都在使用或转向 Vue 和 React 的阵营, 由前端渲染页面的单页应用占比也越来越高,这就代表前端工作的复杂度也在直线上升,前端页面上展示的信息越来越多 ...

  10. .net工作流引擎ccflow集成并增加自定义功能

    一.为什么需要自定义扩展 1.第三方类库已满足大部分需求,剩下的根据具体业务需求抽象成公共功能进行扩展 2.第三方呈现的web页面与原类库耦合度较高,希望在原页面上扩展而不影响原来的功能 3.在完全不 ...