FFMPEG3.2+SDL2.0 +Qt5.5

1Qt pro 配置

TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt

SOURCES += main.cpp


include(deployment.pri)
qtcAddDeployment()


INCLUDEPATH += $$_PRO_FILE_PWD_/Sdl/include

INCLUDEPATH += $$_PRO_FILE_PWD_/FFmpeg/include

LIBS += -L$$_PRO_FILE_PWD_/Sdl/lib/x86 -lSDL2 \
                    -lSDL2main \
                    -lSDL2test

LIBS += -L $$_PRO_FILE_PWD_/FFmpeg/lib \
                     -lavformat \
                     -lavdevice \
                     -lavcodec \
                     -lavutil \
                     -lavfilter \
                     -lpostproc \
                     -lswscale

2代码示例如下

#include <iostream>
#include "Sdl/include/SDL.h"
#undef main
using namespace std;

extern "C"{
#include "FFmpeg/include/libavcodec/avcodec.h"
#include "FFmpeg/include/libswscale/swscale.h"
#include "FFmpeg/include/libavformat/avformat.h"
}

int main()
{

#if 1
    //============================ffmpeg init =================================
    av_register_all();
    avformat_network_init();
    avcodec_register_all();

    AVFormatContext *pFmtCtx = NULL;

//    char * url = "D:/QtProject/ffmpegSdl/ffmpegwithSdl1th/aa.wmv";

//    char * url = "rtmp://live.hkstv.hk.lxdns.com/live/hks";
//    char * url = "rtmp://127.0.0.1:1935/live/001 live=1";

    AVInputFormat  *pIfmt = NULL;
    AVDictionary   *pDic  = NULL;

    if (avformat_open_input(&pFmtCtx,url,pIfmt,&pDic) !=0)
    {
        cout<<"avformat_open_input error"<<endl;
        return -1;
    }

    if (avformat_find_stream_info(pFmtCtx,NULL)<0)
    {
        cout<<"avformat_find_stream_info error"<<endl;
        return -1;
    }

    av_dump_format(pFmtCtx,0,url,0);
    int videoStreamidx = -1;

    for(int i=0; i<pFmtCtx->nb_streams; i++)
    {
        if(pFmtCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
        {
            videoStreamidx = i;
            break;
        }
    }

    if(videoStreamidx  == -1)
    {
        cout<<" find vedio error"<<endl;
        return -1;
    }
    AVCodecContext * pCodecCtx = pFmtCtx->streams[videoStreamidx]->codec;

    AVCodec        *pCodec;

    pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
    if(pCodecCtx == NULL)
    {
        cout<<"avcodec_find_decoder"<<endl;
        return -1;
    }

    if (avcodec_open2(pCodecCtx,pCodec,&pDic) <0)
    {
        cout<<"avcodec_open2 erro"<<endl;
        return -1;
    }

    AVFrame * pFrame = av_frame_alloc();
    if(pFrame == NULL)
    {
        cout<<"av_frame_alloc "<<endl;
        return -1;
    }
    AVFrame * pYuvFrame = av_frame_alloc();
    if(pYuvFrame == NULL)
    {
        cout<<"av_frame_alloc"<<endl;
    }
    AVPacket packet;
    //============================ffmpeg init end=================================

#endif

#if 1
    //============================SDL init =======================================


    SDL_Init(SDL_INIT_VIDEO);

    SDL_Window * window = SDL_CreateWindow("vedio",
                                           SDL_WINDOWPOS_CENTERED,
                                           SDL_WINDOWPOS_CENTERED,
                                           pCodecCtx->width,
                                           pCodecCtx->height,
                                           SDL_WINDOW_RESIZABLE);
    if(window == NULL)
    {
        cout<<"SDL_CreateWindow error"<<endl;
        return -1;
    }

    SDL_Renderer  *render = SDL_CreateRenderer(window,-1,0);
    if(render == NULL)
    {
        cout<<"SDL_CreateRenderer"<<endl;
        return -1;
    }

    SDL_Texture * texture = SDL_CreateTexture(render,
                                              SDL_PIXELFORMAT_IYUV,
                                              SDL_TEXTUREACCESS_STREAMING,
                                              pCodecCtx->width,
                                              pCodecCtx->height
                                              );
    if(texture == NULL)
    {
        cout<<"SDL_CreateTexture"<<endl;
        return -1;
    }

    SDL_Rect rect;
    rect.x = 0;
    rect.y = 0;
    rect.w = pCodecCtx->width;
    rect.h = pCodecCtx->height;


    //============================SDL init end ======================================
#endif


#if 1

    SwsContext*  pSwsCtx;
    pSwsCtx = sws_getContext(pCodecCtx->width,pCodecCtx->height,pCodecCtx->pix_fmt,
                             pCodecCtx->width,pCodecCtx->height,AV_PIX_FMT_YUV420P,
                             SWS_BICUBIC,
                             NULL,NULL,NULL
                             );
    if(pSwsCtx == NULL)
    {
        cout<<"sws_getContext error"<<endl;
        return -1;
    }

    int numBytes = avpicture_get_size(AV_PIX_FMT_YUV420P,pCodecCtx->width,pCodecCtx->height);

    uint8_t *buffer = (uint8_t*)av_malloc(numBytes * sizeof(uint8_t));

    avpicture_fill((AVPicture*)pYuvFrame,
                   buffer,
                   AV_PIX_FMT_YUV420P,
                   pCodecCtx->width,
                   pCodecCtx->height);


    int gotPicture,ret;

    SDL_Event event;


    while(av_read_frame(pFmtCtx,&packet) >= 0)
    {
        if (packet.stream_index == videoStreamidx)
        {
            ret = avcodec_decode_video2(pCodecCtx,pFrame,&gotPicture,&packet);
            if(ret < 0)
            {
                cout<<"decode error"<<endl;
                return -1;
            }

            if(gotPicture)
            {
                sws_scale(pSwsCtx,
                          pFrame->data,
                          pFrame->linesize,
                          0,
                          pCodecCtx->height,
                          pYuvFrame->data,
                          pYuvFrame->linesize);



                SDL_UpdateYUVTexture(texture, &rect,
                                     pYuvFrame->data[0],
                        pYuvFrame->linesize[0],
                        pYuvFrame->data[1],
                        pYuvFrame->linesize[1],
                        pYuvFrame->data[2],
                        pYuvFrame->linesize[2]);

//                SDL_RenderClear(render);
                SDL_RenderCopy(render,texture,NULL,&rect);
                SDL_RenderPresent(render);
                SDL_Delay(20);
            }
        }
        av_free_packet(&packet);


        SDL_PollEvent(&event);

        switch(event.type)
        {
            case SDL_QUIT:
                SDL_Quit();
                return 0;
        }
    }

#endif
}

3播放效果

这里写图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

developer_wgl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值