写一个较新版本的ffmpeg采集视频数据后通过SDL渲染的代码例程
时间: 2023-03-13 07:19:51 浏览: 123
我可以为你提供一段基于最新版本ffmpeg采集视频数据并通过SDL渲染的代码例程:#include <stdio.h>
#include <SDL2/SDL.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>int main (int argc, char *argv[]) {
AVFormatContext *pFormatCtx = NULL;
int i, videoStream;
AVCodecContext *pCodecCtx = NULL;
AVCodec *pCodec = NULL;
AVFrame *pFrame = NULL;
AVPacket packet;
int frameFinished;
float aspect_ratio;
SDL_Window *screen;
SDL_Renderer *renderer;
SDL_Texture *texture;
SDL_Rect rect;
// Register all formats and codecs
av_register_all();
// Open video file
if(avformat_open_input(&pFormatCtx, argv[1], NULL, NULL)!=0)
return -1; // Couldn't open file
// Retrieve stream information
if(avformat_find_stream_info(pFormatCtx, NULL)<0)
return -1; // Couldn't find stream information
// Dump information about file onto standard error
av_dump_format(pFormatCtx, 0, argv[1], 0);
// Find the first video stream
videoStream=-1;
for(i=0; i<pFormatCtx->nb_streams; i++)
if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) {
videoStream=i;
break;
}
if(videoStream==-1)
return -1; // Didn't find a video stream
// Get a pointer to the codec context for the video stream
pCodecCtx=pFormatCtx->streams[videoStream]->codec;
// Find the decoder for the video stream
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL) {
fprintf(stderr, "Unsupported codec!\n");
return -1; // Codec not found
}
// Open codec
if(avcodec_open2(pCodecCtx, pCodec, NULL)<0)
return -1; // Could not open codec
// Allocate video frame
pFrame=av_frame_alloc();
// Make a screen to put our video
screen = SDL_CreateWindow("My Game Window",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
pCodecCtx->width,
pCodecCtx->height,
0);
if(!screen) {
fprintf(stderr, "SDL: could not create window - exiting\n");
exit(1);
}
renderer = SDL_CreateRenderer(screen, -1, 0);
if(!renderer) {
fprintf(stderr, "SDL: could not create renderer - exiting\n");
exit(1);
}
// Allocate a place to put our YUV image on that screen
texture = SDL_CreateTexture(
renderer,
SDL_PIXELFORMAT_YV12,
SDL_TEXTUREACCESS_STREAMING,
pCodecCtx->width,
pCodecCtx->height
);
if(!texture) {
fprintf(stderr, "SDL: could not create texture - exiting\n");
exit(1);
}
// Read frames and save first five frames to disk
i=0;
while(av_read_frame(pFormatCtx, &packet)>=0) {
// Is this a packet from the video stream?
if(packet.stream_index==videoStream) {
// Decode video frame
avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
// Did we get a video frame?
if(frameFinished) {
SDL_UpdateYUVTexture(
texture,
NULL,
pFrame->data[0],
pFrame->linesize[0],
pFrame->data[1],
pFrame->linesize[1],
pFrame->data[2],
pFrame->linesize[2]
);
// set rendering size
rect.x = 0;
rect.y = 0;
rect.w = pCodecCtx->width;
rect.h = pCodecCtx->height;
// Render to screen
SDL_RenderCopy(renderer, texture, NULL, &rect);
SDL_RenderPresent(renderer);
}
}
// Free the packet that was allocated by av_read_frame
av_free_packet(&packet);
}
// Free the YUV frame
av_frame_free(&pFrame);
// Close the codec
avcodec_close(pCodecCtx);
// Close the video file
avformat_close_input(&pFormatCtx);
return 0;
}
阅读全文