学习雷博士的文章
最简单的基于FFMPEG+SDL的视频播放器 ver2 (采用SDL2.0)_flush decoder-CSDN博客
环境:Ubuntu 16.04.7
ffmpeg-6.1
SDL
SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux、Windows、Mac OS X等)的应用软件。目前SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用领域。
1、SDL源码下载
2、SDL编译
./configure --prefix=$PWD/../sdl_dir/
make install
3、SDL测试
用SDL库显示一张bmp
#include <stdio.h>
#include <SDL.h>
int main(int argc, char* argv[])
{
/* 启动SDL */
if(SDL_Init(SDL_INIT_VIDEO) != 0)
{
printf("SDL_Init Error.\n");
return 1;
}
/* 打开窗口 */
SDL_Window *win = SDL_CreateWindow("Hello World", 100, 100, 640, 480, SDL_WINDOW_SHOWN);
if(win == NULL)
{
printf("SDL_CreateWindow Error.\n");
SDL_Quit();
return 1;
}
/* 创建渲染器 */
SDL_Renderer *ren = SDL_CreateRenderer(win , -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if(ren == NULL)
{
SDL_DestroyWindow(win);
printf("SDL_CreateRenderer Error.\n");
return 1;
}
/* 加载位图图像 */
SDL_Surface *bmp = SDL_LoadBMP("test.bmp");
if(bmp == NULL)
{
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
printf("SDL_LoadBMP Error.\n");
SDL_Quit();
return 1;
}
SDL_Texture *tex = SDL_CreateTextureFromSurface(ren, bmp);
SDL_FreeSurface(bmp);
if (tex == NULL){
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
printf("SDL_CreateTextureFromSurface Error.\n");
SDL_Quit();
return 1;
}
//A sleepy rendering loop, wait for 3 seconds and render and present the screen each time
for (int i = 0; i < 3; ++i){
//First clear the renderer
SDL_RenderClear(ren);
//Draw the texture
SDL_RenderCopy(ren, tex, NULL, NULL);
//Update the screen
SDL_RenderPresent(ren);
//Take a quick break after all that hard work
SDL_Delay(1000);
}
SDL_DestroyTexture(tex);
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
SDL_Quit();
return 0;
}
编译测试代码sdltest.c
gcc sdltest.c -o test -I include/SDL2/ -L lib/ -lSDL2
运行 ./test
4、下载雷博士ffmpeg+SDL测试代码
git clone https://gitee.com/leixiaohua/simplest_ffmpeg_player.git
测试 simplest_ffmpeg_player_su/simplest_ffmpeg_player_su.cpp
笔者用的是ffmpeg-6.1,有些接口变化了
1)av_register_all 废弃了
2)
旧版本:
if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){
新版本:
if(pFormatCtx->streams[i]->codecpar->codec_type==AVMEDIA_TYPE_VIDEO){
3)
旧版本:
pCodecCtx=pFormatCtx->streams[videoindex]->codec;
新版本:
//初始化解码上下文
pCodecCtx = avcodec_alloc_context3(NULL);
if (pCodecCtx == NULL)
{
printf("Could not allocate AVCodecContext \n");
return -1;
}
//获取解码参数
avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[videoindex]->codecpar);
4)
旧版本:
ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
新版本:
ret = avcodec_send_packet(pCodecCtx, packet);
if(ret < 0){
av_packet_unref(packet);
printf("Decode Error.\n");
return -1;
}
//接收解码的帧
if(avcodec_receive_frame(pCodecCtx, pFrame) == 0){
5)
旧版本:
av_free_packet(packet);
新版本:
av_packet_unref(packet);
5、编译ffmpeg+SDL测试代码
gcc simplest_ffmpeg_player_su.cpp -o simplest_ffmpeg_player_su.out -I include/ -I ../ffmpeg_dir/include/ -L lib/ -L ../ffmpeg_dir/lib/ -L ../x264_dir/lib/ -lSDL2 -lavformat -lavcodec -lavutil -lswscale -lswresample -lx264
6、运行
export LD_LIBRARY_PATH=xx/ffmpeg_dir/lib:xx/x264_dir/lib:xx/sdl_dir/lib
./simplest_ffmpeg_player_su.out