参考链接:《基于 FFmpeg + SDL 的视频播放器的制作》课程的视频_雷霄骅(leixiaohua1020)的专栏-CSDN博客_雷霄骅ffmpeg视频教程

雷神的基于 FFmpeg + SDL 的视频播放器的制作到这里快进入尾声,下面还有一节添加图形界面的课程,不得不说,雷神的录播课讲的非常详细,令人钦佩。

关于雷神的基于 FFmpeg + SDL 的视频播放器的制作的源代码,我发现在他在界面.h265,h.264的文件时,视频的播放速度还算是正常,但是在播放flv,mp4等封装格式的文件时,速度会比较慢,不是正常的速度,这个他在视频中有讲过修改方法,不过在课件的源代码中给出的不是修改过后的,这里给出正确的修改代码(具体修改方式,雷神在http://www.iqiyi.com/w_19rruoxurx.html视频教程中有所提及)

#include "stdafx.h"extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"//SDL
#include "sdl/SDL.h"
#include "sdl/SDL_thread.h"};//Refresh Event
#define SFM_REFRESH_EVENT  (SDL_USEREVENT + 1)int thread_exit = 0;  //定义一个线程结束标志int sfp_refresh_thread(void* opaque)
{while (thread_exit == 0) {SDL_Event event;event.type = SFM_REFRESH_EVENT;SDL_PushEvent(&event);SDL_Delay(40);}return 0;
}int _tmain(int argc, _TCHAR* argv[])
{AVFormatContext* pFormatCtx;int                i, videoindex;AVCodecContext* pCodecCtx;   //保存了视频(音频)编解码相关信息。AVCodec* pCodec;char filepath[] = "屌丝男士.mov";int frame_cnt = 0;//注册组件+初始化av_register_all(); avformat_network_init();//函数用来申请AVFormatContext类型变量并初始化默认参数,分配内存空间pFormatCtx = avformat_alloc_context();//打开视频流文件if (avformat_open_input(&pFormatCtx, filepath, NULL, NULL) != 0) {printf("Couldn't open input stream.(无法打开输入流)\n");return -1;}//获取视频文件信息if (av_find_stream_info(pFormatCtx) < 0){printf("Couldn't find stream information.(无法获取流信息)\n");return -1;}//设置一个视频帧索引videoindex = -1;for (i = 0; i < pFormatCtx->nb_streams; i++)  //nb_streams:输入视频的AVStream 个数if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)  //streams:输入视频的AVStream []数组{videoindex = i; //判断文件是视频流还是音频流,把其中的视频流获取出来break;}if (videoindex == -1){printf("Didn't find a video stream.(没有找到视频流)\n");return -1;}pCodecCtx = pFormatCtx->streams[videoindex]->codec; //codec:该流对应的AVCodecContextpCodec = avcodec_find_decoder(pCodecCtx->codec_id); //avcodec_find_decoder():查找解码器;  pCodecCtx->codec_id 编解码器IDif (pCodec == NULL){printf("Codec not found.(没有找到解码器)\n");return -1;}//打开解码器,参数为AVCodecContext和对应的解码器IDif (avcodec_open2(pCodecCtx, pCodec, NULL) < 0){printf("Could not open codec.(无法打开解码器)\n");return -1;}AVFrame* pFrame, * pFrameYUV; //存储一帧解码后像素(采样)数据pFrame = avcodec_alloc_frame(); //为解码帧分配内存pFrameYUV = avcodec_alloc_frame();//av_malloc()内存分配,uint8_t = unsigned char无符号字符型//avpicture_get_size()计算这个格式的图片,需要多少字节来存储uint8_t* out_buffer = (uint8_t*)av_malloc(avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height));/*pFrameYUV和out_buffer都是已经申请到的一段内存, 但是pFrameYUV只是申请了一段结构体内存, 结构体里面的值是空的, 我们需要使用avpicture_fill()函数来使得pFrameYUV和out_buffer关联起来,pFrameYUV里面使用的是out_buffer所指向的内存空间.*/avpicture_fill((AVPicture*)pFrameYUV, out_buffer, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);//------------SDL----------------//初始化if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {printf("Could not initialize SDL - %s\n", SDL_GetError());return -1;}int screen_w = 0, screen_h = 0;SDL_Window* screen;//SDL 2.0 Support for multiple windowsscreen_w = pCodecCtx->width;screen_h = pCodecCtx->height;//创建一个窗口screen = SDL_CreateWindow("Simplest ffmpeg player's Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,screen_w, screen_h,SDL_WINDOW_OPENGL);if (!screen) {printf("SDL: could not create window - exiting:%s\n", SDL_GetError());return -1;}//创建一个渲染器SDL_Renderer* sdlRenderer = SDL_CreateRenderer(screen, -1, 0);//IYUV: Y + U + V  (3 planes)//YV12: Y + V + U  (3 planes)SDL_Texture* sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING, pCodecCtx->width, pCodecCtx->height);SDL_Rect sdlRect; //创建一个矩形结构体,分别给左上角的坐标以及矩形框的宽和高sdlRect.x = 0;sdlRect.y = 0;sdlRect.w = screen_w;sdlRect.h = screen_h;int ret, got_picture;//分配一帧压缩编码数据的内存AVPacket* packet = (AVPacket*)av_malloc(sizeof(AVPacket));//Output Info-----------------------------printf("File Information(文件信息)---------------------\n");//av_dump_format()打印关于输入或输出格式的详细信息av_dump_format(pFormatCtx, 0, filepath, 0);printf("-------------------------------------------------\n");//详解:https://blog.csdn.net/MACMACip/article/details/105450185struct SwsContext* img_convert_ctx; img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);//--------------//创建一个线程SDL_Thread* video_tid = SDL_CreateThread(sfp_refresh_thread, NULL, NULL);////Event LoopSDL_Event event;for (;;) {//WaitSDL_WaitEvent(&event);if (event.type == SFM_REFRESH_EVENT) {//------------------------------//在这里判断是不是视频帧,如果是就直接跳出循环while (1) {if (av_read_frame(pFormatCtx, packet) < 0) {thread_exit = 1;}if (packet->stream_index == videoindex) {break;}}//解码一帧压缩数据ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);if (ret < 0) {printf("Decode Error.(解码错误)\n");return -1;}if (got_picture) {sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);//printf("Decoded frame index: %d\n", frame_cnt);//frame_cnt++;//SDL---------------------------SDL_UpdateTexture(sdlTexture, &sdlRect, pFrameYUV->data[0], pFrameYUV->linesize[0]);SDL_RenderClear(sdlRenderer);SDL_RenderCopy(sdlRenderer, sdlTexture, &sdlRect, &sdlRect);SDL_RenderPresent(sdlRenderer);//SDL End-----------------------//av_free_packet(packet);}av_free_packet(packet); //释放}}sws_freeContext(img_convert_ctx); SDL_Quit(); //退出线程//--------------av_free(out_buffer);av_free(pFrameYUV);avcodec_close(pCodecCtx);avformat_close_input(&pFormatCtx);return 0;
}

FFmpeg+SDL 视频播放器相关推荐

  1. FFmpeg+SDL视频播放器

    本博客是摘自雷霄骅大神的课程<基于 FFmpeg + SDL 的视频播放器的制作>课程 里的内容,非常适合音视频小白入门,在这里感谢雷神的指导! 目录 FFmpeg和SDL的整合实现视频播 ...

  2. QT软件开发-基于FFMPEG设计视频播放器-软解图像(一)

    QT软件开发-基于FFMPEG设计视频播放器-CPU软解视频(一) https://xiaolong.blog.csdn.net/article/details/126832537 QT软件开发-基于 ...

  3. QT软件开发-基于FFMPEG设计视频播放器-解码音频(三)

    QT软件开发-基于FFMPEG设计视频播放器-CPU软解视频(一) https://xiaolong.blog.csdn.net/article/details/126832537 QT软件开发-基于 ...

  4. QT软件开发-基于FFMPEG设计视频播放器-GPU硬解、OpenGL渲染、解码音频完整例子(六)

    QT软件开发-基于FFMPEG设计视频播放器-CPU软解视频(一) https://xiaolong.blog.csdn.net/article/details/126832537 QT软件开发-基于 ...

  5. QT软件开发-基于FFMPEG设计视频播放器-GPU硬解、OpenGL渲染(四)

    QT软件开发-基于FFMPEG设计视频播放器-CPU软解视频(一) https://xiaolong.blog.csdn.net/article/details/126832537 QT软件开发-基于 ...

  6. 基于FFmpeg开发视频播放器, 基本流程(一)

    刚开始学习FFmpeg,用几篇文章记录下,使用ffmpeg开发一个简单的视频播放器,大概的过程.这里只讨论核心代码,如解封装,音频的解码播放,视频的解码播放,音视频同步,不涉及UI布局. 基于FFmp ...

  7. 基于FFmpeg的视频播放器之一:开篇

    FFmpeg的研究几乎都是从ffplay开始的,ffplay是FFmpeg自带播放器,它的源码虽然只有一个文件,但是麻雀虽小五脏俱全,播放器的基本功能都有了.初看ffplay的源码,会感觉特别绕,跳转 ...

  8. Qt FFmpeg 音视频播放器

    使用FFmpeg库实现 本地和rtp 音视频播放器,使用qt绘制视频. 本demo环境为 qt5.12 vs2019-32位 .pro的qt工程 FFmpeg版本位3.4.8 vs2092-32位 本 ...

  9. FFmpeg音视频播放器系列(第三篇:seek实现播放进度控制)

    文章目录 如何实现播放进度控制 av_seek_frame seek操作要点 按视频流seek 按音频流seek 代码实现 上一篇基本实现了音视频的播放同步,简单的按键控制暂停.恢复.退出操作,这一篇 ...

最新文章

  1. 关于UIWebView与js交互的问题
  2. PHP几个快速读取大文件例子
  3. 数据结构 | 如何一文搞定链表问题?(附20本书获奖名单)
  4. 布法罗博士计算机专业回国人员,四名UW学生参加爱达荷州国家实验室的实习计划...
  5. linux终端cd未找到命令,为什么`which`命令不能用于`cd`?我也找不到`cd`的可执行文件!...
  6. 高数学习笔记:利用矩阵设置密码
  7. 【UML】活动图Activity diagram(转)
  8. Linux sh/bash[精华]
  9. Github Star 4.6K,3.5M超超轻量中英文OCR模型开源,火了!
  10. 波士顿房价数据集——随机森林
  11. 用代码实现windows10下的虚拟桌面创建功能
  12. PC微信多开,超简单
  13. matlab程序是什么格式,科学网—Matlab中的P代码文件 - 杨笔锋的博文
  14. java date iso,使用DateTimeFormat.ISO.DATE配置Jackson而不是工作
  15. c++ 的vector、array和数组的比较
  16. 机器学习(十一) 迁移学习
  17. 使用ExcelPackage生成Excel2007电子表格
  18. Revit二次开发2、RevitAPI、RevitAPIUI及Revit开发三大利器
  19. Flutter 圆形(头像)图片的 4种实现
  20. React Native加载动画,lottie-web 将json解析成动画

热门文章

  1. 微博修改域名的服务器,新浪微博个性域名是什么 新浪微博如何修改个性域名...
  2. Python小炼(1):初识Python
  3. 论文分哪几个级别(二)
  4. 流氓软件插件中介商自述黑色淘金路(转)
  5. 升级合作伙伴计划,实现全面赋能
  6. 小车加速减速的c语言,c2控制速度技巧
  7. 随机宏基因组测序数据质量控制和去宿主的分析流程和常见问题
  8. iOS 开发商品详情页中的banner中点击查看图片
  9. 什么是 Kubernetes HPA
  10. 小米商城热销模块样式