以下利用SDL播放网络流,需要自己配置运行环境,包括SDL和FFmpeg
// ConsoleApplication2.cpp : 定义控制台应用程序的入口点。
//
/*
#include "stdafx.h"
#include
#define SDL_MAIN_HANDLED
#include "SDL.h"
int main()
{
if (SDL_Init(SDL_INIT_VIDEO) != 0)
{
std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
return 1;
}
SDL_Quit();
system("pause");
return 0;
}
*/
#include "stdafx.h"
#ifdef __cplusplus
extern "C" {
#endif
#include
#include
#include
#include
#include
#include
#include "SDL.h"
#include
#include
#include
#include
#ifdef __cplusplus
}
#endif
int ffplayer()
{
AVFormatContext *pFormatCtx;
int i, videoindex;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
//char filepath[]="F:\\Work\\ffmpegdemo\\Debug\\Wildlife.wmv";
char rtspUrl[] = "rtmp://58.200.131.2:1935/livetv/cctv1";
//char rtspUrl\[\] = "rtmp://192.168.1.253/live/41";
av\_register\_all();//注册组件
avformat\_network\_init();//支持网络流
pFormatCtx = avformat\_alloc\_context();//初始化AVFormatContext
if (avformat\_open\_input(&pFormatCtx,/\*filepath\*/rtspUrl, NULL, NULL) != ) {//打开文件或网络流
printf("无法打开文件\\n");
return -;
}
if (avformat\_find\_stream\_info(pFormatCtx, NULL)<)//查找流信息
{
printf("Couldn't find stream information.\\n");
return -;
}
videoindex = -;
for (i = ; i<pFormatCtx->nb\_streams; i++) //获取视频流ID
if (pFormatCtx->streams\[i\]->codec->codec\_type == AVMEDIA\_TYPE\_VIDEO)
{
videoindex = i;
break;
}
if (videoindex == -)
{
printf("Didn't find a video stream.\\n");
return -;
}
pCodecCtx = pFormatCtx->streams\[videoindex\]->codec;
pCodec = avcodec\_find\_decoder(pCodecCtx->codec\_id);//查找解码器
if (pCodec == NULL)
{
printf("Codec not found.\\n");
return -;
}
if (avcodec\_open2(pCodecCtx, pCodec, NULL)<)//打开解码器
{
printf("Could not open codec.\\n");
return -;
}
AVFrame \*pFrame, \*pFrameYUV;
pFrame = av\_frame\_alloc();//存储解码后AVFrame
pFrameYUV = av\_frame\_alloc();//存储转换后AVFrame
uint8\_t \*out\_buffer;
out\_buffer = new uint8\_t\[avpicture\_get\_size(AV\_PIX\_FMT\_YUV420P, pCodecCtx->width, pCodecCtx->height)\];//分配AVFrame所需内存
avpicture\_fill((AVPicture \*)pFrameYUV, out\_buffer, AV\_PIX\_FMT\_YUV420P, pCodecCtx->width, pCodecCtx->height);//填充AVFrame
//------------SDL初始化--------
if (SDL\_Init(SDL\_INIT\_VIDEO | SDL\_INIT\_AUDIO | SDL\_INIT\_TIMER)) {
printf("Could not initialize SDL - %s\\n", SDL\_GetError());
return -;
}
SDL\_Window \*screen = SDL\_CreateWindow("RTSP Client Demo",
SDL\_WINDOWPOS\_UNDEFINED,
SDL\_WINDOWPOS\_UNDEFINED,
, ,
SDL\_WINDOW\_RESIZABLE/\* SDL\_WINDOW\_HIDDEN\*/ | SDL\_WINDOW\_OPENGL);
if (!screen) {
printf("SDL: could not set video mode - exiting\\n");
return -;
}
SDL\_Renderer\* sdlRenderer = SDL\_CreateRenderer(screen, -, );
SDL\_Texture\* sdlTexture = SDL\_CreateTexture(
sdlRenderer,
SDL\_PIXELFORMAT\_YV12,
SDL\_TEXTUREACCESS\_STREAMING,
pCodecCtx->width,
pCodecCtx->height);
SDL\_Rect rect;
SDL\_Rect dstRect;
dstRect.x = ;
dstRect.y = ;
dstRect.w = ;
dstRect.h = ;
//-----------------------------
int ret, got\_picture;
static struct SwsContext \*img\_convert\_ctx = NULL;
int y\_size = pCodecCtx->width \* pCodecCtx->height;
SDL\_Event event;
AVPacket \*packet = (AVPacket \*)malloc(sizeof(AVPacket));//存储解码前数据包AVPacket
av\_new\_packet(packet, y\_size);
//输出一下信息-----------------------------
printf("文件信息-----------------------------------------\\n");
//av\_dump\_format(pFormatCtx,0,filepath,0);
printf("-------------------------------------------------\\n");
//------------------------------
while ()//循环获取压缩数据包AVPacket
{
if (av\_read\_frame(pFormatCtx, packet) >= )
{
if (packet->stream\_index == videoindex)
{
ret = avcodec\_decode\_video2(pCodecCtx, pFrame, &got\_picture, packet);//解码。输入为AVPacket,输出为AVFrame
if (ret < )
{
printf("解码错误\\n");
return -;
}
if (got\_picture)
{
//像素格式转换。pFrame转换为pFrameYUV。
//if(img\_convert\_ctx == NULL)
img\_convert\_ctx = sws\_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix\_fmt, pCodecCtx->width, pCodecCtx->height, AV\_PIX\_FMT\_YUV420P, SWS\_BICUBIC, NULL, NULL, NULL);
sws\_scale(img\_convert\_ctx, (const uint8\_t\* const\*)pFrame->data, pFrame->linesize, , pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);
sws\_freeContext(img\_convert\_ctx);
//------------SDL显示--------
rect.x = ;
rect.y = ;
rect.w = pCodecCtx->width;
rect.h = pCodecCtx->height;
SDL\_UpdateTexture(sdlTexture, &rect, pFrameYUV->data\[\], pFrameYUV->linesize\[\]);
SDL\_RenderClear(sdlRenderer);
SDL\_RenderCopy(sdlRenderer, sdlTexture, &rect, &dstRect);
SDL\_RenderPresent(sdlRenderer);
//延时20ms
SDL\_Delay();
//------------SDL-----------
}
}
}
av\_free\_packet(packet);
SDL\_PollEvent(&event);
switch (event.type) {
case SDL\_QUIT:
SDL\_Quit();
exit();
break;
default:
break;
}
}
//sws\_freeContext(img\_convert\_ctx);
SDL\_DestroyTexture(sdlTexture);
delete\[\] out\_buffer;
av\_free(pFrameYUV);
avcodec\_close(pCodecCtx);
avformat\_close\_input(&pFormatCtx);
return ;
}
int _tmain(int argc, _TCHAR* argv[])
{
printf("hello\n");
ffplayer();
system("pause");
return ;
}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章