zoukankan      html  css  js  c++  java
  • ffmpeg示例一:源码


    本文解析见http://www.cnblogs.com/elesos/archive/2013/03/08/2949478.html

    // A small sample program that shows how to use libavformat and libavcodec to
    // read video from a file.
    // to write the first five frames from "myvideofile.mpg" to disk in PPM
    // format.

    //add#define inline __inline
    #include <libavcodec/avcodec.h>
    #include <libavformat/avformat.h>
    #include <libswscale/swscale.h>

    #include <stdio.h>

    void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame) {
        FILE *pFile;
        char szFilename[32];
        int  y;

        // Open file
        sprintf(szFilename, "frame%d.ppm", iFrame);
        pFile=fopen(szFilename, "wb");
        if(pFile==NULL)
            return;

        // Write header
        fprintf(pFile, "P6\n%d %d\n255\n", width, height);

        // Write pixel data
        for(y=0; y<height; y++)
            fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width*3, pFile);

        // Close file
        fclose(pFile);
    }

    int main(int argc, char *argv[]) 
    {
        AVFormatContext *pFormatCtx = NULL;
        int             i, videoStream;
        AVCodecContext  *pCodecCtx = NULL;
        AVCodec         *pCodec = NULL;
        AVFrame         *pFrame = NULL; 
        AVFrame         *pFrameRGB = NULL;
        AVPacket        packet;
        int             frameFinished;
        int             numBytes;
        uint8_t         *buffer = NULL;

        AVDictionary    *optionsDict = NULL;
        struct SwsContext      *sws_ctx = NULL;

        if(argc < 2) {
            printf("Please provide a movie file\n");
            return -1;
        }
        // Register all formats and codecs
        av_register_all();

        // Open video file
        if(avformat_open_input(&pFormatCtx, argv[1], 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, argv[1], 0);

        // Find the first video stream
        videoStream=-1;
        for(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
            pCodecCtx=pFormatCtx->streams[videoStream]->codec;

            // Find the decoder for the video stream
            pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
            if(pCodec==NULL) 
            {
                fprintf(stderr, "Unsupported codec!\n");
                return -1// Codec not found
            }
            // Open codec
            if(avcodec_open2(pCodecCtx, pCodec, &optionsDict)<0)
                return -1// Could not open codec

            
    // Allocate video frame
            pFrame=avcodec_alloc_frame();

            // Allocate an AVFrame structure
            pFrameRGB=avcodec_alloc_frame();
            if(pFrameRGB==NULL)
                return -1;

            // Determine required buffer size and allocate buffer
            numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
            buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));

            //Allocate and return an SwsContext. We need it to perform scaling/conversion operations using sws_scale().
            sws_ctx =
                sws_getContext
                (
                pCodecCtx->width,//the width of the source image
                pCodecCtx->height,
                pCodecCtx->pix_fmt,//the source image format
                pCodecCtx->width,
                pCodecCtx->height,
                PIX_FMT_RGB24,//the destination image format :AV_PIX_FMT_RGB24
                SWS_BILINEAR,//specify which algorithm and options to use for rescaling
                NULL,
                NULL,
                NULL
                );

            // Assign appropriate parts of buffer to image planes in pFrameRGB
            
    // Note that pFrameRGB is an AVFrame, but AVFrame is a superset
            
    // of AVPicture
            avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
                pCodecCtx->width, pCodecCtx->height);

            // Read frames and save first five frames to disk
            i=0;
            while(av_read_frame(pFormatCtx, &packet)>=0
            {
                // Is this a packet from the video stream?
                if(packet.stream_index==videoStream) 
                {
                    // Decode video frame
                    avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);      
                    // Did we get a video frame?
                    if(frameFinished) 
                    {
                        // Convert the image from its native format to RGB
                        sws_scale
                            (
                            sws_ctx,
                            (uint8_t const * const *)pFrame->data,
                            pFrame->linesize,
                            0,
                            pCodecCtx->height,
                            pFrameRGB->data,
                            pFrameRGB->linesize
                            );

                        // Save the frame to disk
                        if(++i<=5)
                            SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i);
                    }
                }

                // Free the packet that was allocated by av_read_frame
                av_free_packet(&packet);
            }

            // Free the RGB image
            av_free(buffer);
            av_free(pFrameRGB);

            // Free the YUV frame
            av_free(pFrame);

            // Close the codec
            avcodec_close(pCodecCtx);

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

            return 0;
    }

  • 相关阅读:
    2013.11.3
    计算机面试书籍
    SDPLR的安装过程(matlab)
    Semi-definite programming优化工具
    R-note1
    Ubuntu---2
    C#中DataTable转换为string
    MFC获取字符串长度的5中方法
    根据不同的操作系统(64/32),设置文件以64位运行。又可解决问题:“试图加载不正确的程序”。
    WinServer2008下通过powershell获取IIS等角色功能列表,保存至txt
  • 原文地址:https://www.cnblogs.com/elesos/p/2984570.html
Copyright © 2011-2022 走看看