注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

斗天堂

douzsh还活着

 
 
 

日志

 
 

FFMPEG从视频中截取图片  

2007-11-07 10:58:49|  分类: 视频 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
typedef unsigned char  BYTE;
typedef unsigned short WORD;
typedef unsigned long  DWORD;
 
#pragma pack(1)
typedef struct tagBITMAPFILEHEADER{
     WORD bfType;                // the flag of bmp, value is "BM"
     DWORD    bfSize;                // size BMP file ,unit is bytes
     WORD    bfReserved1,bfReserved2;            // 0
     DWORD    bfOffBits;             // must be 54
}BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER{
     DWORD    biSize;                // must be 0x28
     DWORD    biWidth;           //
     DWORD    biHeight;          //
     WORD biPlanes;          // must be 1
     WORD biBitCount;            //
     DWORD    biCompression;         //
     DWORD    biSizeImage;       //
     DWORD    biXPelsPerMeter;   //
     DWORD    biYPelsPerMeter;   //
     DWORD    biClrUsed;             //
     DWORD    biClrImportant;        //
}BITMAPINFOHEADER;
typedef struct tagRGBQUAD{
     BYTE    rgbBlue;
     BYTE rgbGreen;
     BYTE rgbRed;
     BYTE rgbReserved;
}RGBQUAD;
typedef   struct   tagBITMAPINFO   {
         BITMAPINFOHEADER         bmiHeader;
         RGBQUAD                           bmiColors[1];
}BITMAPINFO;

long UpendBmp(unsigned char *lpdata,long width ,long height)
{
   
    long lBPL;
    long x,y,idx_src,idx_dest;
    unsigned char *tmpdata;
   
    if (0==((width*3)%4)) 
        lBPL = (width*3);
    else
        lBPL = (width*3+(4-((width*3)%4)));
   
    tmpdata= new unsigned char[lBPL * height];
   
    x =0;
    for (y=0 ; y<height ; y++)
    {
        idx_src =(height-1-y)*lBPL;
        idx_dest=y*lBPL;
        memcpy(&tmpdata[idx_dest],&lpdata[idx_src],lBPL);
    }
   
    memcpy(lpdata,tmpdata,lBPL * height);
    delete[] tmpdata;
   
    return 0;
}
static int av_create_bmp(char* filename,uint8_t *pRGBBuffer,int width,int height,int bpp)
{
    BITMAPFILEHEADER bmpheader;
    BITMAPINFO bmpinfo;
    FILE *fp;

    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;
}
bool GetPicFromVideo(const char* VideoName,double CutTimeFrame,char* PicName)
{   
    AVFormatContext *oc;
    int i,videoStream;
    AVCodecContext *pCodecCtx;
    AVCodec *pCodec;
    AVFrame *pFrame;
    AVFrame *pFrameRGB;
    int     numBytes;
    uint8_t *buffer;
    AVPacket packet;   
    int frameFinished;
    double frameNum=0;
    av_register_all();
    oc=av_alloc_format_context();
    if(av_open_input_file(&oc,VideoName,NULL,0,NULL)!=0)
        return 0;
    if(av_find_stream_info(oc)<0)
        return 0;
    {
//        dump_format(oc, 0, VideoName, false);
        videoStream=-1;
        for(i=0; i<oc->nb_streams; i++)
            if(oc->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)
            {
                videoStream=i;
                break;
            }
        if(videoStream==-1)
                return false; // Didn't find a video stream
        pCodecCtx = (oc->streams[videoStream]->codec);
        pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
        if (pCodec == NULL )
            return false;
//        if(pCodec->capabilities & CODEC_CAP_TRUNCATED)
//            pCodecCtx->flags|=CODEC_FLAG_TRUNCATED;
        if (avcodec_open(pCodecCtx, pCodec) < 0)
            return false;
        pFrame=avcodec_alloc_frame();
        pFrameRGB=avcodec_alloc_frame();
        if(pFrameRGB==NULL)
            return false;
        numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,
        pCodecCtx->height);
        buffer=new uint8_t[numBytes];
        avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
            pCodecCtx->width, pCodecCtx->height);
        if(CutTimeFrame<oc->duration/1000000)
            frameNum=oc->streams[videoStream]->r_frame_rate.num*CutTimeFrame;
        else
            frameNum=oc->streams[videoStream]->r_frame_rate.num*(CutTimeFrame-1);
        i=1;
        while(av_read_frame(oc, &packet)>=0)
        {
            if(packet.stream_index==videoStream)
            {
                avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,
                    packet.data, packet.size);
                if(frameFinished)
                {
                    i++;
                    if(pFrame->key_frame && i>frameNum)
                    {
                        img_convert((AVPicture *)pFrameRGB, PIX_FMT_BGR24,
                            (AVPicture*)pFrame, pCodecCtx->pix_fmt, pCodecCtx->width,
                            pCodecCtx->height);
                        UpendBmp(pFrameRGB->data[0],pCodecCtx->width,pCodecCtx->height);
                        av_create_bmp(PicName,(unsigned char*)pFrameRGB->data[0], pCodecCtx->width,
                            pCodecCtx->height,24);
                    }
                }
            }
            av_free_packet(&packet);
        }
        delete [] buffer;
        av_free(pFrameRGB);
        av_free(pFrame);
        avcodec_close(pCodecCtx);
       
    }
    av_close_input_file(oc);
    return true;
}
  评论这张
 
阅读(1038)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017