Linux ffmpeg
博客专区 > MtrS 的博客 > 博客详情
Linux ffmpeg
MtrS 发表于1年前
Linux ffmpeg
  • 发表于 1年前
  • 阅读 3
  • 收藏 0
  • 点赞 0
  • 评论 0

标题:腾讯云 新注册用户域名抢购1元起>>>   

#define __STDC_CONSTANT_MACROS

extern "C" {
#include <attributes.h>
#include <avcodec.h>
#include <avformat.h>
#include <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[]) {
        static AVFormatContext *pFormatCtx;
        int i, videoStream;
        AVCodecContext *pCodecCtx;
        AVCodec *pCodec;
        AVFrame *pFrame;
        AVFrame *pFrameRGB;
        AVPacket packet;
        int frameFinished;
        int numBytes;
        uint8_t *buffer;
        AVDictionary * options;
        // 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], false);

        // Find the first video stream
        videoStream=-1;
        for(i=0; i<pFormatCtx->nb_streams; i++)
            if(pFormatCtx->streams[i]->codecpar->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)
            return -1; // Codec not found

        // Open codec
        if(avcodec_open2(pCodecCtx, pCodec,NULL)<0)
            return -1; // Could not open codec

        // Hack to correct wrong frame rates that seem to be generated by some
        // codecs
        // if(pCodecCtx->frame_rate>1000 && pCodecCtx->frame_rate_base==1)
        // pCodecCtx->frame_rate_base=1000;

        // Allocate video frame
        // pFrame = avcodec_alloc_frame();
        pFrame = av_frame_alloc(); 

        // Allocate an AVFrame structure
        // pFrameRGB = avcodec_alloc_frame();
        pFrameRGB = av_frame_alloc();

        if(pFrameRGB==NULL)
            return -1;

        // Determine required buffer size and allocate buffer
        numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
        buffer=new uint8_t[numBytes];

        // Assign appropriate parts of buffer to image planes in pFrameRGB
        avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
            pCodecCtx->width, pCodecCtx->height);

        // Read frames and save first five frames to disk
        i = 0;
        struct SwsContext *img_convert_ctx = NULL;
        img_convert_ctx = sws_getContext(pCodecCtx->width,pCodecCtx->height,
                pFormatCtx->streams[videoStream]->codecpar->format , 
                pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, SWS_BICUBIC, 
                NULL, NULL, NULL);

        while(av_read_frame(pFormatCtx, &packet)>=0)
        {
            // Is this a packet from the video stream?
            if(packet.stream_index==videoStream)
            {
                // Decode video frame
                frameFinished = 0;
                int ret = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
                if(ret < 0)
                {
                    av_log(NULL, AV_LOG_ERROR, "Error decoding video\n");
                    break;
                }
                if(frameFinished)
                {
                    sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
                    if(++i<=1000)
                        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
        delete [] 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;
}

共有 人打赏支持
粉丝 29
博文 468
码字总数 351660
×
MtrS
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: