ffmpeg(2):ffmpeg结合SDL2.0解码视频流

看了http://blog.csdn.net/leixiaohua1020/article/details/8652605后,想学习在windows下面使用ffmpeg库播放视频。

100行代码实现最简单的基于FFMPEG+SDL的视频播放器》:

该文章里面是使用ffmpeg结合SDL1.2解码视频的。其中用到了SDL_CreateYUVOverlay,SDL_Overlay等函数在SDL2.0已经不存在了。

因此需要想新的办法。

这里需要给自己先补点知识:

SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux、Windows、Mac OS X等)的应用软件。目前SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用领域。


经过多方的查询,参考了N多资料。解决了。

参考资料:

1. http://blog.csdn.net/ashqal/article/details/17640179
2. http://stackoverflow.com/questions/17579286/sdl2-0-alternative-for-sdl-overlay
3. http://wiki.libsdl.org/MigrationGuide
4. http://blog.csdn.net/leixiaohua1020/article/details/12747899
5. http://blog.csdn.net/leixiaohua1020/article/details/8652605
6. https://github.com/chelyaev/ffmpeg-tutorial

下面的代码,是我自己根据上面帖子里面代码修改的。

#include <stdio.h>
#include <tchar.h>
#include <io.h>
#include <direct.h>
extern "C"
{
    // ffmpeg
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
    // SDL
#include "sdl/SDL.h"
#include "sdl/SDL_thread.h"
};

#pragma comment(lib,"avutil.lib")
#pragma comment(lib,"avcodec.lib")
#pragma comment(lib,"avformat.lib")
#pragma comment(lib,"swscale.lib")
#pragma comment(lib,"sdl2.lib")

int _tmain(int argc, char *argv[])
{
    ///
    // ffmpeg
    // Register all formats and codecs
    av_register_all();

    // Open video file
    AVFormatContext *pFormatCtx = NULL;
    const char* filename = "cuc_ieschool.flv";
    if( avformat_open_input(&pFormatCtx, filename, NULL, NULL) != 0 ) {
        return -1; // Couldn't open file
    }

    // Retrieve stream information
    if( avformat_find_stream_info(pFormatCtx, NULL) < 0 ) {
        return -1; // Couldn't find stream information
    }

    // Dump information about file onto standard error
    av_dump_format(pFormatCtx, 0, filename, 0);

    // Find the first video stream
    int videoStream = -1;
    for(int i=0; i < pFormatCtx->nb_streams; i++) {
        if( pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO ) {
            videoStream = i;
            break;
        }
    }
    if( videoStream == -1) {
        return -1; // Didn't find a video stream
    }

    // Get a pointer to the codec context for the video stream
    AVCodecContext * pCodecCtx = pFormatCtx->streams[videoStream]->codec;

    // Find the decoder for the video stream
    AVCodec* pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
    if( pCodec == NULL ) {
        fprintf(stderr, "Unsupported codec!\n");
        return -1; // Codec not found
    }

    // Open codec
    AVDictionary* optionsDict = NULL;
    if( avcodec_open2(pCodecCtx, pCodec, &optionsDict) < 0 ) {
        return -1; // Could not open codec
    }

    // Allocate video frame
    AVFrame* pFrame = av_frame_alloc();
    AVFrame* pFrameYUV = av_frame_alloc();
    if( pFrameYUV == NULL ) {
        return -1;
    }

    struct SwsContext* sws_ctx = sws_getContext(
        pCodecCtx->width,
        pCodecCtx->height,
        pCodecCtx->pix_fmt,
        pCodecCtx->width,
        pCodecCtx->height,
        PIX_FMT_YUV420P,
        SWS_BILINEAR,
        NULL,
        NULL,
        NULL);

    int numBytes = avpicture_get_size(
        PIX_FMT_YUV420P,
        pCodecCtx->width,
        pCodecCtx->height);
    uint8_t* buffer = (uint8_t *)av_malloc( numBytes*sizeof(uint8_t) );

    avpicture_fill((AVPicture *)pFrameYUV, buffer, PIX_FMT_YUV420P,
        pCodecCtx->width, pCodecCtx->height);

    // Read frames and save first five frames to disk
    SDL_Rect sdlRect;
    sdlRect.x = 0;
    sdlRect.y = 0;
    sdlRect.w = pCodecCtx->width;
    sdlRect.h = pCodecCtx->height;

    //
    // SDL
    if( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER )) {
        fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
        exit(1);
    }

    SDL_Window* sdlWindow = SDL_CreateWindow("My Game Window",
        SDL_WINDOWPOS_UNDEFINED,
        SDL_WINDOWPOS_UNDEFINED,
        pCodecCtx->width,  pCodecCtx->height,
        0);
    if( !sdlWindow ) {
        fprintf(stderr, "SDL: could not set video mode - exiting\n");
        exit(1);
    }

    SDL_Renderer* sdlRenderer = SDL_CreateRenderer(sdlWindow, -1, 0);
    SDL_Texture* sdlTexture = SDL_CreateTexture(
        sdlRenderer,
        SDL_PIXELFORMAT_YV12,
        SDL_TEXTUREACCESS_STREAMING,
        pCodecCtx->width,
        pCodecCtx->height);

    AVPacket packet;
    SDL_Event event;
    while( av_read_frame(pFormatCtx, &packet) >= 0 ) {
        // Is this a packet from the video stream?
        if( packet.stream_index == videoStream ) {
            // Decode video frame
            int frameFinished;
            avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);

            // Did we get a video frame?
            if( frameFinished ) {
                sws_scale(
                    sws_ctx,
                    (uint8_t const * 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, &sdlRect, &sdlRect );
                SDL_RenderPresent( sdlRenderer );
            }
            SDL_Delay(50);
        }

        // Free the packet that was allocated by av_read_frame
        av_free_packet(&packet);
        SDL_PollEvent(&event);
        switch( event.type ) {
            case SDL_QUIT:
                SDL_Quit();
                exit(0);
                break;
            default:
                break;
        }

    }

    SDL_DestroyTexture(sdlTexture);

    // Free the YUV frame
    av_free(pFrame);
    av_free(pFrameYUV);

    // Close the codec
    avcodec_close(pCodecCtx);

    // Close the video file
    avformat_close_input(&pFormatCtx);

    return 0;
}


大家可以在这里下载《ffmpeg结合SDL2.0最简单的工程》,根据上面几个帖子,相信大家可以成功的。

PS: 由于写这篇文章的时候,CSDN上传资源有问题,待可以上传的时候,我再上传。

步骤:

1.下载SDL2.0 地址:http://www.libsdl.org/

2.下载ffmpeg在Windows下的SDK 地址:http://ffmpeg.zeranoe.com/builds/

3.下载MinGW // 可以在CSDN下载绿色版 地址:http://download.csdn.net/detail/piano7heart/3651248


下面打算学习如何使用ffmpeg解码音频流。。。

相关推荐
<p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; color: #e36c09; font-size: 20px;"><strong style="margin: 0px; padding: 0px;">我将带领大家一起来学习SDL2.0的编程知识,包括SDL2.0的编程框架、原理流程分析,几个核心对象、事件机制、扩展库的使用。</strong></span></p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 20px; color: #000000;"><strong style="margin: 0px; padding: 0px;">具体内容包括:</strong></span></p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 20px; color: #00b0f0;"><strong style="margin: 0px; padding: 0px;">1.搭建开发环境:VS2015或Qt5.9,共两套环境。</strong></span></p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 20px; color: #00b0f0;"><strong style="margin: 0px; padding: 0px;">2.核心对象编程:窗口、表面、渲染器、纹理、事件。</strong></span></p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 20px; color: #00b0f0;"><strong style="margin: 0px; padding: 0px;">3.扩展库的应用:SDL2_image,SDL2_mixer,SDL2_ttf(图像、音频、字库)</strong></span></p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"><span style="margin: 0px; padding: 0px; font-size: 20px; color: #00b0f0;"><strong style="margin: 0px; padding: 0px;">4.官方案例实战:亲手练习官方推荐的几个案例,认真分析总结。</strong></span></p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"> </p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"> </p> <p style="box-sizing: border-box; margin: 0px; padding: 0px; font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; color: #313d54; font-size: 16px; background-color: #ffffff;"><span style="box-sizing: border-box; margin: 0px; padding: 0px; font-family: 'PingFang SC', 'Hiragino Sans GB', Arial, 'Microsoft YaHei', Verdana, Roboto, Noto, 'Helvetica Neue', sans-serif; color: #424242;">梅老师<span style="box-sizing: border-box; margin: 0px; padding: 0px;">从事音视频与流媒体行业18年</span>;曾在</span><span style="box-sizing: border-box; margin: 0px; padding: 0px; font-family: 'PingFang SC', 'Hiragino Sans GB', Arial, 'Microsoft YaHei', Verdana, Roboto, Noto, 'Helvetica Neue', sans-serif; color: #974806;">永新视博、中科大洋、百度、美国Harris广播事业部</span><span style="box-sizing: border-box; margin: 0px; padding: 0px; font-family: 'PingFang SC', 'Hiragino Sans GB', Arial, 'Microsoft YaHei', Verdana, Roboto, Noto, 'Helvetica Neue', sans-serif; color: #424242;">等公司就职,经验丰富;曾亲手主导广电直播全套项目,精通h.264/h.265/aac,曾亲自参与百度app上的网页播放器等实战产品。</span></p> <p style="box-sizing: border-box; margin: 0px; padding: 0px; font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; color: #313d54; font-size: 16px; background-color: #ffffff;"> </p> <p style="font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; margin: 0px; padding: 0px; color: #313d54; font-size: 16px; background-color: #ffffff;"> </p> <p style="box-sizing: border-box; margin: 0px; padding: 0px; font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', Arial, sans-serif; color: #313d54; font-size: 16px; background-color: #ffffff;"><span style="box-sizing: border-box; margin: 0px; padding: 0px; font-family: 'PingFang SC', 'Hiragino Sans GB', Arial, 'Microsoft YaHei', Verdana, Roboto, Noto, 'Helvetica Neue', sans-serif; color: #424242;">目前全身心自主创业,主要<span style="box-sizing: border-box; margin: 0px; padding: 0px;"><span style="box-sizing: border-box; margin: 0px; padding: 0px;">聚焦音视频+流媒体行业</span></span>,<span style="box-sizing: border-box; margin: 0px; padding: 0px;"><span style="box-sizing: border-box; margin: 0px; padding: 0px;">精通音视频加密、流媒体在线转码快编等热门产品</span></span>。</span></p>
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页