【发布时间】:2015-10-04 01:01:34
【问题描述】:
提前致谢。 我正在尝试播放德州仪器 (Texas Instrument) 制作的 beaglebone black (BBB) 视频。 由于有很多关于使用 ffmpeg 和 SDL 的好教程,我决定使用它。 获取有关视频和编解码器的信息,使用 ffmpeg 解码帧。 显示解码帧以使用 SDL 进行监控。
我正在使用 SDL2,它使用渲染器、纹理将图像显示到屏幕。 根据 SDL wiki,渲染器使用 GPU 加速。 但这里有个问题。视频播放太慢...大约 0.5fps?
所以我转向使用软件渲染的 SDL1.2。 它通过 CPU RAM 显示 yuv 覆盖。
我认为 BBB 可能不支持 GPU 加速并用谷歌搜索但无法得到答案。请问有什么帮助吗? 这是我使用 SDL2 的代码。
#include <libavutil/frame.h>
#include <libavutil/avutil.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_thread.h>
#ifdef __MINGW32__
#undef main /* Prevents SDL from overriding main() */
#endif
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <errno.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;
SDL_Window *window=NULL;
SDL_Renderer *renderer=NULL;
SDL_Texture *bmp=NULL;
SDL_Event event;
int fbfd, ret;
struct fb_var_screeninfo fbvar;
if(argc < 2) {
fprintf(stderr, "Usage: test <file>\n");
exit(1);
}
// Register all formats and codecs
av_register_all();
if(SDL_Init(SDL_INIT_VIDEO)) {
fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
exit(1);
}
// 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();
int ctxW= pCodecCtx->width;
int ctxH= pCodecCtx->height;
window =
SDL_CreateWindow("test",
SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED, 0, 0,
SDL_WINDOW_BORDERLESS SDL_WINDOW_FULLSCREEN_DESKTOP);
renderer = SDL_CreateRenderer(window, -1, 0);
// Allocate a place to put our YUV image on that screen
bmp = SDL_CreateTexture(renderer,
SDL_PIXELFORMAT_YV12, SDL_TEXTUREACCESS_STREAMING,
pCodecCtx->width, pCodecCtx->height);
av_init_packet(&packet);
// Read frames and save first five frames to disk
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(bmp, NULL, pFrame->data[0], pFrame->linesize[0],
pFrame->data[1], pFrame->linesize[1],
pFrame->data[2], pFrame->linesize[2]);
}
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, bmp, NULL, NULL);
SDL_RenderPresent(renderer);
}
SDL_Delay(15);
SDL_PollEvent(&event);
switch(event.type) {
case SDL_QUIT:
SDL_Quit();
exit(0);
break;
default:
break;
}
}
// 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;
}
【问题讨论】:
标签: video sdl-2 beagleboneblack hardware-acceleration