linux 用sdl2播放一个视频
时间: 2023-06-27 16:02:09 浏览: 55
使用SDL2在Linux上播放视频,需要先安装SDL2库和FFmpeg库。接下来,需要用FFmpeg将视频解码成yuv像素数据,再使用SDL2将像素数据渲染到屏幕上。
以下是基本的步骤:
1. 引入SDL2和FFmpeg库,定义相关变量和函数。
```c
#include <SDL2/SDL.h>
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
AVCodecContext *codec_ctx;
AVFormatContext *format_ctx;
AVCodec *codec;
SDL_Renderer* renderer;
SDL_Texture* texture;
SDL_Window *window;
SDL_Rect rect;
unsigned char *output_buffer;
int pitch;
struct SwsContext *sws_ctx;
```
2. 初始化SDL2和FFmpeg库。
```c
if(SDL_Init(SDL_INIT_VIDEO) != 0)
{
printf("SDL_Init Error: %s", SDL_GetError());
return -1;
}
av_register_all();
avformat_network_init();
format_ctx = avformat_alloc_context();
if(avformat_open_input(&format_ctx, file_path, NULL, NULL) != 0)
{
return -1;
}
if(avformat_find_stream_info(format_ctx, NULL) < 0)
{
return -1;
}
int video_stream_index = -1;
for(int i=0; i < format_ctx->nb_streams; i++)
{
if(format_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
{
video_stream_index = i;
break;
}
}
if(video_stream_index == -1)
{
return -1;
}
codec_ctx = format_ctx->streams[video_stream_index]->codec;
codec = avcodec_find_decoder(codec_ctx->codec_id);
if(codec == NULL)
{
return -1;
}
if(avcodec_open2(codec_ctx, codec, NULL) < 0)
{
return -1;
}
```
3. 配置SDL2窗口、渲染器和纹理。
```c
window = SDL_CreateWindow("Video Player", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, codec_ctx->width, codec_ctx->height, SDL_WINDOW_OPENGL);
renderer = SDL_CreateRenderer(window, -1, 0);
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING, codec_ctx->width, codec_ctx->height);
rect.w = codec_ctx->width;
rect.h = codec_ctx->height;
```
4. 读取视频流、解码和渲染。
```c
AVPacket packet;
int frame_finished;
AVFrame* frame = av_frame_alloc();
while(av_read_frame(format_ctx, &packet) >= 0)
{
if(packet.stream_index == video_stream_index)
{
if(avcodec_send_packet(codec_ctx, &packet) == 0)
{
while(avcodec_receive_frame(codec_ctx, frame) == 0)
{
sws_ctx = sws_getContext(codec_ctx->width, codec_ctx->height, codec_ctx->pix_fmt, codec_ctx->width, codec_ctx->height, AV_PIX_FMT_YUV420P, SWS_BILINEAR, NULL, NULL, NULL);
sws_scale(sws_ctx, (const uint8_t * const*)frame->data, frame->linesize, 0, codec_ctx->height, (uint8_t * const *)output_buffer, &pitch);
SDL_UpdateYUVTexture(texture, NULL, output_buffer, codec_ctx->width, output_buffer+codec_ctx->width*codec_ctx->height, codec_ctx->width/2, output_buffer+codec_ctx->width*codec_ctx->height*5/4, codec_ctx->width/2);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
sws_freeContext(sws_ctx);
}
}
}
av_packet_unref(&packet);
}
```
5. 释放资源。
```c
avformat_close_input(&format_ctx);
avcodec_free_context(&codec_ctx);
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
```
总体上来说,使用SDL2播放视频需要对FFmpeg库有一定的了解,掌握基本的视频解码、像素转换和纹理渲染等技巧。对于初学者来说,需要仔细研究相关文档和示例程序,并多做实践。