使用 FFMPEG 截图

#include <windows.h>   
#include <stdlib.h>   
#include <stdio.h>   
#include <string.h>   
#include <math.h>   
   
#include "libavcodec\avcodec.h"   
   
#include "libavformat\avformat.h"   
#include "libswscale\swscale.h"   
   
   
   
static int av_create_bmp(char* filename,uint8_t *pRGBBuffer,int width,int height,int bpp)   
{   
    BITMAPFILEHEADER bmpheader;   
    BITMAPINFO bmpinfo;   
    FILE *fp;   
    uint8_t *p;   
    uint8_t *q;   
    uint8_t *r;   
   
    fp = fopen(filename,"wb");   
    if(!fp)return -1;   
   
    bmpheader.bfType = ('M'<<8)|'B';   
    bmpheader.bfReserved1 = 0;   
    bmpheader.bfReserved2 = 0;   
    bmpheader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);   
    bmpheader.bfSize = bmpheader.bfOffBits + width*height*bpp/8;   
   
    bmpinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);   
    bmpinfo.bmiHeader.biWidth = width;   
    bmpinfo.bmiHeader.biHeight = -height;   
    bmpinfo.bmiHeader.biPlanes = 1;   
    bmpinfo.bmiHeader.biBitCount = bpp;   
    bmpinfo.bmiHeader.biCompression = BI_RGB;   
    bmpinfo.bmiHeader.biSizeImage = 0;   
    bmpinfo.bmiHeader.biXPelsPerMeter = 100;   
    bmpinfo.bmiHeader.biYPelsPerMeter = 100;   
    bmpinfo.bmiHeader.biClrUsed = 0;   
    bmpinfo.bmiHeader.biClrImportant = 0;   
   
    fwrite(&bmpheader,sizeof(BITMAPFILEHEADER),1,fp);   
    fwrite(&bmpinfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp);   
   
   
    fwrite(pRGBBuffer,width*height*bpp/8,1,fp);   
    fclose(fp);   
   
    return 0;   
}   
   
   
   
   
   
int main()   
{   
        SwsContext *pSWSCtx;   
        AVFormatContext *pFormatCtx;   
        const char *filename="sample.mpg";   
        int i,videoStream,y_size;   
        AVCodecContext *pCodecCtx;   
        AVFrame *pFrame;   
        AVFrame *pFrameRGB;   
        int     numBytes,frameFinished;   
        uint8_t *buffer;   
        static AVPacket packet;   
   
   
        av_register_all();   
   
        if(av_open_input_file(&pFormatCtx, filename, NULL, 0, NULL)!=0)   
                printf("error!\n");   
   
        if(av_find_stream_info(pFormatCtx)<0)   
                printf("error!\n");   
   
        dump_format(pFormatCtx, 0, filename, false);   
   
   
        videoStream=-1;   
   
        for(i=0; i<pFormatCtx->nb_streams; i++)   
                if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)   
                {   
                    videoStream=i;   
                    break;   
                }   
        if(videoStream==-1)   
                printf("error!\n");// Didn't find a video stream   
   
        // 得到视频流编码上下文的指针   
        pCodecCtx=pFormatCtx->streams[videoStream]->codec;   
        AVCodec *pCodec;   
   
        //  寻找视频流的解码器   
        pCodec=avcodec_find_decoder(pCodecCtx->codec_id);   
        if(pCodec==NULL)   
            printf("error!\n");// 找不到解码器   
   
        // 通知解码器我们能够处理截断的bit流--ie,   
        // bit流帧边界可以在包中   
   
   
        // 打开解码器   
        if(avcodec_open(pCodecCtx, pCodec)<0)   
            printf("error!\n"); // 打不开解码器   
        pFrame=avcodec_alloc_frame();   
   
   
        pFrameRGB = avcodec_alloc_frame();   
        numBytes=avpicture_get_size(PIX_FMT_BGR24, pCodecCtx->width,pCodecCtx->height);   
        buffer=new uint8_t[numBytes];   
        avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,pCodecCtx->width, pCodecCtx->height);   
        pSWSCtx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);   
   
   
   
        i=0;   
        while(av_read_frame(pFormatCtx,&packet)>=0)   
        {   
            if(packet.stream_index==videoStream)   
            {   
                avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,packet.data, packet.size);   
                if(frameFinished)   
                {   
                    if(pFrame->key_frame==1)   
                    {   
                        sws_scale(pSWSCtx, pFrame->data, pFrame->linesize,0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);   
                        // Save the frame to disk   
                        char pic[200];   
                        sprintf(pic,"pic%d.bmp",i);   
                        i++;   
                        av_create_bmp(pic,pFrameRGB->data[0],pCodecCtx->width,pCodecCtx->height,24);   
                    }   
                }   
            }   
        av_free_packet(&packet);   
        }   
   
   
        // 释放 RGB 图象   
        av_free(pFrameRGB);   
        // 释放YUV 帧   
        av_free(pFrame);   
   
        sws_freeContext(pSWSCtx);   
   
   
        // 关闭解码器(codec)   
        avcodec_close(pCodecCtx);   
   
        // 关闭视频文件   
        av_close_input_file(pFormatCtx);   
   
        return 0;   
   
}   


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值