标签:
// ffmpegDemo1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <string>
#include <windows.h>
#include <processthreadsapi.h>
#define __STDC_CONSTANT_MACROS
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <sdl/SDL.h>
};
typedef int (*PLAYERTHREAD)();
int PlayerVideo()
{
AVFormatContext *avFormatContext = NULL;
std::string filename = "sintel.h264";
std::string format = "";
struct SwsContext *img_convert_ctx = NULL;
av_register_all();
avformat_network_init();
avformat_alloc_output_context2(&avFormatContext,NULL,NULL,NULL);
if (avformat_open_input(&avFormatContext,filename.c_str(),NULL,NULL) != 0)
{
printf("couldn‘t open input stream.\n");
return 0;
}
if (avformat_find_stream_info(avFormatContext,NULL) < 0)
{
printf("couldn‘t find stram information.\n");
return 0;
}
int videoIndex = -1;
for (int i = 0; i < avFormatContext->nb_streams;i++)
{
if (avFormatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
{
videoIndex = i;
break;
}
}
if (videoIndex == -1)
{
printf("couldn‘t find a video stream.");
return -1;
}
AVCodecContext *PCodecCtx = NULL;
AVCodec *pCodec = NULL;
PCodecCtx = avFormatContext->streams[videoIndex]->codec;
pCodec = avcodec_find_decoder(PCodecCtx->codec_id);
if (pCodec == NULL)
{
return -1;
}
if (avcodec_open2(PCodecCtx,pCodec,NULL) != 0)
{
return -1;
}
AVFrame *pFrame = NULL;
AVFrame *pFrameYUV = NULL;
pFrame = av_frame_alloc();
pFrameYUV = av_frame_alloc();
uint8_t *pBuf = NULL;
pBuf = (uint8_t *)av_malloc(avpicture_get_size(PIX_FMT_YUV420P, PCodecCtx->width, PCodecCtx->height));
avpicture_fill((AVPicture *)pFrameYUV, pBuf, PIX_FMT_YUV420P, PCodecCtx->width, PCodecCtx->height);
AVPacket *packet = NULL;
packet=(AVPacket *)av_malloc(sizeof(AVPacket));
av_dump_format(avFormatContext,0,filename.c_str(),0);
img_convert_ctx = sws_getContext(PCodecCtx->width, PCodecCtx->height, PCodecCtx->pix_fmt,
PCodecCtx->width, PCodecCtx->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
printf( "Could not initialize SDL - %s\n", SDL_GetError());
return -1;
}
int screen_w = PCodecCtx->width;
int screen_h = PCodecCtx->height;
SDL_Window *screen = SDL_CreateWindow("Simplest ffmpeg player‘s Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
screen_w, screen_h,
SDL_WINDOW_OPENGL);
if(!screen) {
printf("SDL: could not create window - exiting:%s\n",SDL_GetError());
return -1;
}
//创建一个渲染器
SDL_Renderer * sdlRenderer = SDL_CreateRenderer(screen, -1, 0);
//IYUV: Y + U + V (3 planes)
//YV12: Y + V + U (3 planes)
//创建一个纹理
SDL_Texture * sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING,PCodecCtx->width,PCodecCtx->height);
SDL_Rect sdlRect;
int got_picture,ret;
sdlRect.x=0;
sdlRect.y=0;
sdlRect.w=screen_w;
sdlRect.h=screen_h;
//SDL End---------读取一帧-------------
while(av_read_frame(avFormatContext, packet)>=0)
{
if(packet->stream_index==videoIndex)
{
ret = avcodec_decode_video2(PCodecCtx, pFrame, &got_picture, packet);
if(ret < 0){
printf("Decode Error.\n");
return -1;
}
if(got_picture)
{
//图像格式转换
sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, PCodecCtx->height,
pFrameYUV->data, pFrameYUV->linesize);
//SDL---------------------------
//更新纹理
SDL_UpdateYUVTexture(sdlTexture, &sdlRect,
pFrameYUV->data[0], pFrameYUV->linesize[0],
pFrameYUV->data[1], pFrameYUV->linesize[1],
pFrameYUV->data[2], pFrameYUV->linesize[2]);
//清空渲染器
SDL_RenderClear( sdlRenderer );
//复制渲染器
SDL_RenderCopy( sdlRenderer, sdlTexture, NULL, &sdlRect);
//显示
SDL_RenderPresent( sdlRenderer );
//SDL End-----------------------
//Delay 40ms
SDL_Delay(40);
}
}
av_free_packet(packet);
}
while (1)
{
ret = avcodec_decode_video2(PCodecCtx, pFrame, &got_picture, packet);
if (ret < 0)
break;
if (!got_picture)
break;
sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, PCodecCtx->height,
pFrameYUV->data, pFrameYUV->linesize);
SDL_UpdateTexture( sdlTexture, &sdlRect, pFrameYUV->data[0], pFrameYUV->linesize[0] );
SDL_RenderClear( sdlRenderer );
SDL_RenderCopy( sdlRenderer, sdlTexture, NULL, &sdlRect);
SDL_RenderPresent( sdlRenderer );
SDL_Delay(40);
}
sws_freeContext(img_convert_ctx);
SDL_Quit();
av_frame_free(&pFrameYUV);
av_frame_free(&pFrame);
avcodec_close(PCodecCtx);
avformat_close_input(&avFormatContext);
}
static unsigned __stdcall Playerthread(void *pa)
{
PLAYERTHREAD player = (PLAYERTHREAD)pa;
player();
_endthreadex(1);
return 1;
}
int _tmain(int argc, _TCHAR* argv[])
{
unsigned int id= 1;
HANDLE h = (HANDLE)_beginthreadex(NULL,0,Playerthread,(void*)PlayerVideo,0,&id);
WaitForSingleObject(h,INFINITE);
return 0;
}
标签:
原文地址:http://www.cnblogs.com/ouyangyuxi/p/5667163.html