简单播放器

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. eXosip的register注册

    转载于:http://blog.sina.com.cn/s/blog_4868f98601018ioh.html 这个测试程序是从eXosip原有的测试程序改造的.原程序是tools 目录下的 sip ...

  2. *#【Python】【基础知识】【模块】【random】【使用random创造一个随机数】

    Random介绍: 输出随机数. 快照: #!/usr/bin/python # -*- coding: UTF-8 -*- import random #生成 10 到 20 之间的随机数 prin ...

  3. ThreadLocal父子线程之间的数据传递问题

    一.问题的提出 在系统开发过程中常使用ThreadLocal进行传递日志的RequestId,由此来获取整条请求链路.然而当线程中开启了其他的线程,此时ThreadLocal里面的数据将会出现无法获取 ...

  4. 使用window.open 实现弹框和居中对齐

    // 打开页面方法 window.open(url, '_blank', centerStyle('600', '400')+',toolbar=no,menubar=no,resizeable=no ...

  5. [DEBUG] java中用Runtime调用python 简单程序输出null

    今天需要在java中调用python脚本,首先考虑的是java自带的Runtime 在ubuntu和win10下分别测试,发现win10报错 java源代码 @Test public void tes ...

  6. shell如果文件夹不存在则创建

    #!/bin/bash build_dir="build" if [ ! -d "$build_dir" ]; then mkdir $build_dir fi ...

  7. thinkphp5分页查询paginate()传递参数

    使用paginate()分页,我这里实现的是搜索后分页显示,翻页后传递搜索关键字 www.demo.com/home/search/?k=搜索关键字&page=2 搜索分页源码在: think ...

  8. 优化方法总结以及Adam存在的问题(SGD, Momentum, AdaDelta, Adam, AdamW,LazyAdam)

    优化方法总结以及Adam存在的问题(SGD, Momentum, AdaDelta, Adam, AdamW,LazyAdam) 2019年05月29日 01:07:50 糖葫芦君 阅读数 455更多 ...

  9. Idea加载项目扫描完毕后自动退出

    问题描述:Idea平时好好的,突然就打开后扫描完毕后自动退出.网上说修改idea.exe.vmoptions文件的Xmx,还是不行. 后来根据http://www.pianshen.com/artic ...

  10. KEIL仿真出现 EVALUATION MODE

    原因是KEIL MDK没有破解,重新破解即可