简单播放器

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. js函数(3)

    8.5 作为命名空间的函数 即定义一个函数用做临时的命名空间,在这个命名空间内定义的变量都不会污染到全局命名空间. 将一段代码封装在函数内部,然后调用这个函数.这样全局变量就变成了函数内部的局部变量: ...

  2. [Agc028A]Two Abbreviations_数学

    Two Abbreviations 题目链接:https://atcoder.jp/contests/agc028/tasks/agc028_a 数据范围:略. 题解: 题目中的位置非常不利于思考,我 ...

  3. 1、Ubuntu linux下同步windows火狐foxfire 浏览器收藏夹问题

    最近在ubuntu系统中使用自带的firefox浏览器,发现有一些问题,比如登陆后,书签,历史记录等,原本在windows下同步的数据无法同步,添加书签的功能也无法使用. 经过查询资料后得知,unbu ...

  4. 小菜鸟之crond

    前一天学习了 at 命令是针对仅运行一次的任务,循环运行的例行性计划任务,linux系统则是由 cron (crond) 这个系统服务来控制的.Linux 系统上面原本就有非常多的计划性工作,因此这个 ...

  5. indows Eclipse Scala编写WordCount程序

    Windows Eclipse Scala编写WordCount程序: 1)无需启动hadoop,因为我们用的是本地文件.先像原来一样,做一个普通的scala项目和Scala Object. 但这里一 ...

  6. fiddler笔记:状态面板

    Capturing 指示Fiddler是否开启抓包. Process-based Filter 显示Fiddler当前正在捕获的流量进程类型点击面板可以显示进程类型的过滤选项菜单 Automatic ...

  7. DevExpress WPF控件记录

    以下是博主用到DevExpress WPF控件时的一些记录笔记: 1.Canvas控件:Canvas控件的背景色一定要设置(background="Transparent"),不然 ...

  8. Django Rest Framework 安装

    1. 环境要求 Python (3.5, 3.6, 3.7): 查看 python版本:python -V Django (1.11, 2.0, 2.1, 2.2) 查看django版本:pip li ...

  9. Sql语句知识大全

    1.经典SQL语句大全(绝对的经典) 2. 3. 4.一.基础 1.1.说明:创建数据库 2.CREATE DATABASE database-name 3.2.说明:删除数据库 4.drop dat ...

  10. Abp 聚合测试

    Abp 官网开始的教程例子,是IRpositoty<entity> 直接出现在应用层.但是如果是一个聚合根也会这样吗?  那么聚合根是访问仓储的最小单元,要通过聚合根来操作业务,就是实体, ...