QT ffmpeg 播放器
来源:互联网 发布:java httpclient 详解 编辑:程序博客网 时间:2024/05/21 11:24
1.下载sdl2,ffmpeg dev
2.qt的配置
win32: LIBS += -L$$PWD/libffmpeg/lib/ -lavcodec -lavdevice -lavfilter -lavformat -lavutil -lpostproc -lswscalewin32: LIBS += -L$$PWD/libSDL/lib/x86/ -lSDL2 -lSDL2mainINCLUDEPATH += $$PWD/libffmpeg/includeDEPENDPATH += $$PWD/libffmpeg/includeINCLUDEPATH += $$PWD/libSDL/includeDEPENDPATH += $$PWD/libSDL/include
3.类接口源码(参考了雷博士的源码)
#ifndef VIDEOPLAYER_H#define VIDEOPLAYER_H#ifdef _WIN32//Windowsextern "C"{#include "libavcodec/avcodec.h"#include "libavformat/avformat.h"#include "libswscale/swscale.h"#include "SDL.h"};#else//Linux...#ifdef __cplusplusextern "C"{#endif#include <libavcodec/avcodec.h>#include <libavformat/avformat.h>#include <libswscale/swscale.h>#include <SDL2/SDL.h>#ifdef __cplusplus};#endif#endifclass VideoPlayer{public: VideoPlayer(void* hwnd); ~VideoPlayer(); //init ffmpeg SDL static int StaticInit(); //crate videoplayer static VideoPlayer * CreateNew(void *hwnd); // int OpenVideo(const char * videopath); // int Play(); // int Stop(); // int Pause(); // int Continue(); void test();public: static bool IsStaticInit; AVFormatContext*pFormatCtx; AVCodecContext*pCodecCtx; int videoindex; //--------------SDL--------- SDL_Texture* sdlTexture; SDL_Renderer* sdlRenderer; bool fPause; bool fEndThread;private: uint8_t *out_buffer; //AVPacket *packet; //------------SDL---------------- int screen_w, screen_h; SDL_Window *screen; SDL_Rect sdlRect; SDL_Thread *video_tid; SDL_Event event; char fVideoPath[512]; void * fHwnd;};#endif // VIDEOPLAYER_H
#include "videoplayer.h"#include <QDebug>bool VideoPlayer::IsStaticInit = false;int video_refresh_thread(void *opaque){ VideoPlayer *vplayer = (VideoPlayer*)opaque; if(vplayer == NULL){ return 0; } AVPacket * packet = (AVPacket *)av_malloc(sizeof(AVPacket)); AVFrame*pFrame, *pFrameYUV; int ret, got_picture; struct SwsContext *img_convert_ctx; uint8_t *out_buffer; pFrame = av_frame_alloc(); pFrameYUV = av_frame_alloc(); out_buffer = (uint8_t *)av_malloc(avpicture_get_size(AV_PIX_FMT_YUV420P, vplayer->pCodecCtx->width, vplayer->pCodecCtx->height)); avpicture_fill((AVPicture *)pFrameYUV, out_buffer, AV_PIX_FMT_YUV420P, vplayer->pCodecCtx->width, vplayer->pCodecCtx->height); img_convert_ctx = sws_getContext(vplayer->pCodecCtx->width, vplayer->pCodecCtx->height, vplayer->pCodecCtx->pix_fmt, vplayer->pCodecCtx->width,vplayer-> pCodecCtx->height, AV_PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL); while(!vplayer->fEndThread){ if(!vplayer->fPause){ if (av_read_frame(vplayer->pFormatCtx, packet) >= 0) { if (packet->stream_index == vplayer->videoindex) { ret = avcodec_decode_video2(vplayer->pCodecCtx, pFrame, &got_picture, packet); if (ret < 0) { printf("Decode Error.\n"); break; } if (got_picture) { sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, vplayer->pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize); //SDL--------------------------- SDL_UpdateTexture(vplayer->sdlTexture, NULL, pFrameYUV->data[0], pFrameYUV->linesize[0]); SDL_RenderClear(vplayer->sdlRenderer); //SDL_RenderCopy( sdlRenderer, sdlTexture, &sdlRect, &sdlRect ); SDL_RenderCopy(vplayer->sdlRenderer, vplayer->sdlTexture, NULL, NULL); SDL_RenderPresent(vplayer->sdlRenderer); //SDL End----------------------- } } av_free_packet(packet); }else{ break; } } SDL_Delay(40); } if(vplayer->sdlRenderer) SDL_RenderClear(vplayer->sdlRenderer); sws_freeContext(img_convert_ctx); av_frame_free(&pFrameYUV); av_frame_free(&pFrame); vplayer->fEndThread = false; vplayer->fPause = false; return 0;}VideoPlayer::VideoPlayer(void *hwnd): fHwnd(hwnd),pFormatCtx(NULL),pCodecCtx(NULL),sdlRenderer(NULL), sdlTexture(NULL),video_tid(NULL),fPause(false),fEndThread(false){ //03.申请context内存 pFormatCtx = avformat_alloc_context();}VideoPlayer::~VideoPlayer(){ SDL_Quit(); Stop();}int VideoPlayer::StaticInit(){ if(IsStaticInit){ return 0; } IsStaticInit = true; //00.初始化SDL 视频、音频、定时器 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) { printf("Could not initialize SDL - %s\n", SDL_GetError()); return -1; } //01.ffpeg初始化 av_register_all(); //02.网络初始化 return avformat_network_init();}int VideoPlayer::OpenVideo(const char *videopath){ strcpy(fVideoPath, videopath); return 0;}int VideoPlayer::Play(){ //04.打开视频 if (avformat_open_input(&pFormatCtx, fVideoPath, NULL, NULL) != 0) { printf("Couldn't open input stream.\n"); return -1; } //05.获取视频信息 if (avformat_find_stream_info(pFormatCtx, NULL) < 0) { printf("Couldn't find stream information.\n"); return -1; } //06.获取视频流的序号 videoindex = -1; for (unsigned int i = 0; i < pFormatCtx->nb_streams; i++) if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { videoindex = i; break; } //07.是否存在视频流 if (videoindex == -1) { printf("Didn't find a video stream.\n"); return -1; } //08.视频编码方式 pCodecCtx = pFormatCtx->streams[videoindex]->codec; AVCodec*pCodec; pCodec = avcodec_find_decoder(pCodecCtx->codec_id); if (pCodec == NULL) { printf("Codec not found.\n"); return -1; } if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) { printf("Could not open codec.\n"); return -1; } //09.创建渲染器和纹理 sdlRenderer = SDL_CreateRenderer(screen, -1, 0); sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING, pCodecCtx->width, pCodecCtx->height); video_tid = SDL_CreateThread(video_refresh_thread, NULL, (void*)this); return 0;}int VideoPlayer::Stop(){ if(video_tid){ fEndThread = true; SDL_WaitThread(video_tid, NULL); video_tid = NULL; fEndThread = false; } if(sdlTexture){ SDL_DestroyTexture(sdlTexture); sdlTexture = NULL; } if(sdlRenderer){ SDL_RenderClear(sdlRenderer); SDL_DestroyRenderer(sdlRenderer); sdlRenderer = NULL; } if(pCodecCtx){ avcodec_close(pCodecCtx); pCodecCtx = NULL; } if(pFormatCtx){ avformat_close_input(&pFormatCtx); pFormatCtx = NULL; } return 0;}int VideoPlayer::Pause(){ fPause = true; return 0;}int VideoPlayer::Continue(){ fPause = false; return 0;}void VideoPlayer::test(){ SDL_Surface *sur = SDL_GetWindowSurface(screen); ; SDL_BlitSurface( SDL_LoadBMP("d:/123.bmp") , NULL ,sur ,NULL); SDL_UpdateWindowSurface(screen);//更新显示copy the window surface to the screen}VideoPlayer *VideoPlayer::CreateNew(void * hwnd){ SDL_Window *screen = SDL_CreateWindowFrom(hwnd); if(screen){ VideoPlayer *vplayer = new VideoPlayer(hwnd); vplayer->screen = screen; return vplayer; }else{ qDebug()<<SDL_GetError(); return NULL; }}
0 0
- Qt + ffmpeg播放器
- QT ffmpeg 播放器
- 不用 SDL 的QT+FFMPEG 播放器
- QT+ffmpeg视频播放器学习知识点
- FFMPEG Qt视频播放器之播放控制
- 某牛的QT+ffmpeg 播放器 的readme
- 基于FFmpeg和Qt的播放器 QtAV库
- QT+FFMPEG播放器——github代码
- QT+ffmpeg打造跨平台多功能播放器
- 一个基于ffmpeg+QT的视频播放器
- FFMPEG Qt视频播放器之显示图像
- FFMPEG Qt视频播放器之SDL的使用
- FFMPEG Qt视频播放器之音视频同步
- FFMPEG Qt视频播放器之同步进阶篇
- FFMPEG Qt视频播放器之美化界面
- ffmpeg系列:基于QT的播放器界面绘制
- 从零开始学习音视频编程技术(十) FFMPEG Qt视频播放器之播放控制
- 从零开始学习音视频编程技术(十) FFMPEG Qt视频播放器之播放控制
- 题目1133:学分绩点
- Android Studio设置自动导包及删除无用包
- swustoj求最小生成树(Prim算法)(1075)
- 谷歌页面排序算法
- FourInOne初识
- QT ffmpeg 播放器
- 走刀式分板机的正确操作及常见故障
- Field injection is not recommended
- SSL 2647_线段树练习四_线段树
- npm 模块笔记(二):xls-to-json
- 用微软接口调系统的虚拟键盘
- Datapatch:数据库 12c 补丁后期 SQL 自动化 (文档 ID 2101974.1)
- Ubuntu16.04.1如何安装TensorFlow1.1.0(GPU版)
- setsockopt 设置 SO_LINGER 选项