ffmpeg学习笔记

// 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;
}

 

posted @ 2016-07-13 15:48  雨曦  阅读(464)  评论(0编辑  收藏  举报