SDL 小例子
阅读原文时间:2023年07月15日阅读:2

以下利用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 ;  

}

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章