应用FFMPEG和SDL,播放视频文件
2013-06-08 16:21
489 查看
使用FFMPEG库进行视频编解码,使用SDL播放视频,代码参考dranger大神的代码。
extern "C" { #include "libavformat/avformat.h" #include "libswscale/swscale.h" } #include <stdlib.h> #include <stdio.h> #include <string.h> #include <math.h> #include <SDL/SDL.h> #ifdef main #undef main #endif #define SDL_AUDIO_BUFFER_SIZE 1024 static int sws_flags = SWS_BICUBIC; int main(int argc, char *argv[]) { ***FormatContext *pFormatCtx; int i, videoStream(-1); ***CodecContext *pCodecCtx; ***Codec *pCodec; ***Frame *pFrame; ***Packet packet; int frameFinished; float aspect_ratio; ***CodecContext *aCodecCtx; SDL_Overlay *bmp; SDL_Surface *screen; SDL_Rect rect; SDL_Event event; if(argc < 2) { fprintf(stderr, "Usage: test \n"); exit(1); } av_register_all(); pFormatCtx = av_alloc_format_context(); if (!pFormatCtx) { fprintf(stderr, "Memory error\n"); exit(1); } if(av_open_input_file(&pFormatCtx, argv[1], NULL, 0, NULL)!=0) return -1; // Couldn't open file if(av_find_stream_info(pFormatCtx)<0) return -1; // Couldn't find stream information // Dump information about file onto standard error dump_format(pFormatCtx, 0, argv[1], 0); // Find the first video stream for(i=0; i<pFormatCtx->nb_streams; i++) { if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO && videoStream<0) { videoStream=i; } } 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; pCodec=avcodec_find_decoder(pCodecCtx->codec_id); if(pCodec==NULL) { fprintf(stderr, "Unsupported codec!\n"); return -1; // Codec not found } // Open codec if(avcodec_open(pCodecCtx, pCodec)<0) return -1; // Could not open codec // Allocate video frame pFrame=avcodec_alloc_frame(); uint8_t *buffer; int numBytes; // Determine required buffer size and allocate buffer numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height); buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t)); printf("the size of picture is %d\n",numBytes); if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) { fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError()); exit(1); } #ifndef __DARWIN__ screen = SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->height, 0, 0); #else screen = SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->height, 24, 0); #endif if(!screen) { fprintf(stderr, "SDL: could not set video mode - exiting\n"); exit(1); } bmp = SDL_CreateYUVOverlay(pCodecCtx->width, pCodecCtx->height, SDL_YV12_OVERLAY, screen); static struct SwsContext *img_convert_ctx; if (img_convert_ctx == NULL) { img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P, sws_flags, NULL, NULL, NULL); if (img_convert_ctx == NULL) { fprintf(stderr, "Cannot initialize the conversion context\n"); exit(1); } } 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_video(pCodecCtx, pFrame, &frameFinished, packet.data, packet.size); // Did we get a video frame? if(frameFinished) { // Convert the image from its native format to RGB // Save the frame to disk SDL_LockYUVOverlay(bmp); ***Picture pict; pict.data[0] = bmp->pixels[0]; pict.data[1] = bmp->pixels[2]; pict.data[2] = bmp->pixels[1]; pict.linesize[0] = bmp->pitches[0]; pict.linesize[1] = bmp->pitches[2]; pict.linesize[2] = bmp->pitches[1]; // Convert the image into YUV format that SDL uses sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pict.data, pict.linesize); SDL_UnlockYUVOverlay(bmp); rect.x = 0; rect.y = 0; rect.w = pCodecCtx->width; rect.h = pCodecCtx->height; SDL_DisplayYUVOverlay(bmp, &rect); //Sleep(60); } } // Free the packet that was allocated by av_read_frame av_free_packet(&packet); SDL_PollEvent(&event); switch(event.type) { case SDL_QUIT: SDL_Quit(); exit(0); break; default: break; } }; // Free the RGB image av_free(buffer); //av_free(pFrameRGB); // Free the YUV frame av_free(pFrame); // Close the codec avcodec_close(pCodecCtx); // Close the video file av_close_input_file(pFormatCtx); return 0; }
相关文章推荐
- 播放android应用工作中的视频文件
- FFmpeg+SDL视频播放(1)
- FFmpeg+SDL视频播放(4)
- Ubuntu11.04下编译ffmpeg,利用SDL1.2播放视频
- ffmpeg+SDL能同时播放多路视频么?
- ffmpeg和opencv 播放视频文件和显示器
- Android平台上使用SDL官方demo播放视频(使用ffmpeg最新版解码)
- FFMPEG小白-day08(sdl项目播放视频流程及结构体关系图)
- FFmpeg+SDL视频播放(3)
- 【FFMpeg视频开发与应用基础】五、调用FFMpeg SDK封装音频和视频为视频文件
- 【FFMpeg视频开发与应用基础】六、调用FFMpeg SDK实现视频文件的转封装
- 应用ffmpeg进行视频文件格式转换
- MFC 播放视频 FFMPEG SDL
- Android平台上使用SDL官方demo播放视频(使用ffmpeg最新版解码)
- iOS编译ffmpeg1.2.1,使用kxmovie播放视频文件
- ffmpeg SDL播放视频
- ffmpeg和SDL实现的视频播放程序
- Android平台上使用SDL官方demo播放视频(使用ffmpeg最新版解码)
- MFC中如何利用ffmpeg和SDL2.0多线程多窗口播放摄像头的视频
- FFMpeg+SDL2.0 播放本地AVI文件练手示例程序