Tutorial 02: Outputting to the Screen
来源:互联网 发布:视频播放cms 编辑:程序博客网 时间:2024/05/25 19:55
这个例子主要是播放视频的,和tutorial01有很多相似的地方。
这里就不一一叙述了。
// tutorial02.c// A pedagogical video player that will stream through every video frame as fast as it can.//// This tutorial was written by Stephen Dranger (dranger@gmail.com).//// Code based on FFplay, Copyright (c) 2003 Fabrice Bellard, // and a tutorial by Martin Bohme (boehme@inb.uni-luebeckREMOVETHIS.de)// Tested on Gentoo, CVS version 5/01/07 compiled with GCC 4.1.1//// Use the Makefile to build all examples.//// Run using// tutorial02 myvideofile.mpg//// to play the video stream on your screen.extern "C"{#include "libavutil/avstring.h"#include "libavutil/mathematics.h"#include "libavutil/pixdesc.h"#include "libavutil/imgutils.h"#include "libavutil/dict.h"#include "libavutil/parseutils.h"#include "libavutil/samplefmt.h"#include "libavutil/avassert.h"#include "libavutil/time.h"#include "libavformat/avformat.h"#include "libavdevice/avdevice.h"#include "libswscale/swscale.h"#include "libavutil/opt.h"#include "libavcodec/avfft.h"#include "libswresample/swresample.h"#include "SDL1.2/SDL.h"#include "SDL1.2/SDL_thread.h"}#pragma comment(lib, "avcodec.lib")#pragma comment(lib, "avformat.lib")#pragma comment(lib, "avutil.lib")#pragma comment(lib, "avdevice.lib")#pragma comment(lib, "avfilter.lib")#pragma comment(lib, "postproc.lib")#pragma comment(lib, "swresample.lib")#pragma comment(lib, "swscale.lib")#pragma comment(lib, "SDL.lib")#ifdef __MINGW32__#undef main /* Prevents SDL from overriding main() */#endif#include <stdio.h>int _tmain() { AVFormatContext *pFormatCtx = NULL; int i, videoStream; AVCodecContext *pCodecCtx = NULL; AVCodec *pCodec = NULL; AVFrame *pFrame = NULL; AVPacket packet; int frameFinished; //float aspect_ratio; AVDictionary *optionsDict = NULL; struct SwsContext *sws_ctx = NULL; SDL_Overlay *bmp = NULL; SDL_Surface *screen = NULL; SDL_Rect rect; SDL_Event event; char szFile[] = "song.flv"; av_register_all(); if( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) ) { fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError()); exit(1); } // Open video file if( avformat_open_input(&pFormatCtx, szFile, 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, szFile, 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, &optionsDict) < 0 ) { return -1; // Could not open codec } // Allocate video frame pFrame = av_frame_alloc(); // Make a screen to put our video#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); } // Allocate a place to put our YUV image on that screen bmp = SDL_CreateYUVOverlay(pCodecCtx->width, pCodecCtx->height, SDL_YV12_OVERLAY, screen);
// 将解码得到的视频格式转化为YUV420格式. sws_ctx = sws_getContext ( pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P, SWS_BILINEAR, NULL, NULL, NULL ); // 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_LockYUVOverlay(bmp); AVPicture 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 ( sws_ctx, (uint8_t const * const *)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); SDL_Delay(40); } } // 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 YUV frame av_free(pFrame); // Close the codec avcodec_close(pCodecCtx); // Close the video file avformat_close_input(&pFormatCtx); return 0;}
只是把有区别的地方说一下。
因为SDL能播放的是YUV420格式,所以需要将解码后得到的视频转码为YUV420格式。
另外每解码,播放一帧,需要暂停40ms,因为若不暂停,那么播放速度是等于解码速度的,视频会迅速播放完。
0 0
- Tutorial 02: Outputting to the Screen
- Tutorial 02: Outputting to the Screen
- Tutorial 02: Outputting to the Screen输出到屏幕
- ffmpeg学习---3.Outputting to the Screen
- FFmpeg和SDL教程之二(Outputting to the Screen)
- Android tutorial: How to make a basic splash screen
- Use ImageMagick to Capture the screen
- Tap anywhere on the screen to continue
- print 'welcome to masm!' in the center of the screen.
- Umbraco(4)-Outputting the Document Type Properties
- 如何分屏幕(How to split the Screen)
- [转]如何分屏幕(How to split the Screen)
- How to use the Journal Import Correction Screen - from Metalink
- Four Ways to Deal With the Longer iPhone 5 screen
- wiki: How to grab the desktop (screen) with FFmpeg
- Thransform the vertex from model space to screen space. opengl.
- 如何修改Screen背景?How to - Change the background color of a screen
- Welcome to the ASP.NET 2.0 QuickStart Tutorial
- 剑指offer 算法 (发散思维能力)
- java将pdf文件转String
- 二叉树中和为某一值的路径
- 在线支付so easy
- 分享:office2010的一些有用的小技巧
- Tutorial 02: Outputting to the Screen
- Android学习之路
- 图片放大插件Zoom
- 如何让cmd窗口执行上一条命令后暂停会继续执行下一条命令
- Java 数组合并问题
- Layout动画:在android布局发生变化时添加动画效果
- 操作系统基本内容
- Android PhotoView 支持图片缩放的使用
- Building a RESTful Web Service