当前位置:   article > 正文

ffmpeg 获取视频关键帧

ffmpeg 获取视频关键帧
  1. av_register_all();
  2. if(av_open_input_file(&pFormatCtx, filename, NULL, 0, NULL)!=0)
  3. printf("error!\n");
  4. if(av_find_stream_info(pFormatCtx)<0)
  5. printf("error!\n");
  6. videoStream=-1;
  7. for(i=0; i<pFormatCtx->nb_streams; i++)
  8. if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)
  9. {
  10. videoStream=i;
  11. break;
  12. }
  13. if(videoStream==-1)
  14. printf("error!\n");// Didn't find a video stream
  15. // 得到视频流编码上下文的指针
  16. pCodecCtx=pFormatCtx->streams[videoStream]->codec;


 

用两种方式,一是利用ffmpeg提供的可执行文件进行提取,另外就是用ffmpeg的sdk,进行开发。我下面说一下如何使用ffmpeg sdk进行提取(假设把提取的关键帧保存成bmp,源文件名是sample.mpg):

首先获取文件中的视频流:

 

然后选择解码器进行解码:

  1. AVCodec *pCodec;
  2. // 寻找视频流的解码器
  3. pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
  4. if(pCodec==NULL)
  5. printf("error!\n");// 找不到解码器
  6. // 打开解码器
  7. if(avcodec_open(pCodecCtx, pCodec)<0)
  8. printf("error!\n"); // 打不开解码器


现在开始,进入解码和提取关键帧的过程:

  1. pFrame=avcodec_alloc_frame();
  2. pFrameRGB = avcodec_alloc_frame();
  3. numBytes=avpicture_get_size(PIX_FMT_BGR24, pCodecCtx->width,pCodecCtx->height);
  4. buffer=new uint8_t[numBytes];
  5. avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,pCodecCtx->width, pCodecCtx->height);
  6. pSWSCtx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
  7. i=0;
  8. while(av_read_frame(pFormatCtx,&packet)>=0)
  9. {
  10. if(packet.stream_index==videoStream)
  11. {
  12. avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,packet.data, packet.size);
  13. if(frameFinished)
  14. {
  15. if(pFrame->key_frame==1) // 这就是关键帧
  16. {
  17. sws_scale(pSWSCtx, pFrame->data, pFrame->linesize,0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
  18. // 保存到磁盘
  19. char pic[200];
  20. sprintf(pic,"pic%d.bmp",i);
  21. i++;
  22. av_create_bmp(pic,pFrameRGB->data[0],pCodecCtx->width,pCodecCtx->height,24);
  23. }
  24. }
  25. }
  26. av_free_packet(&packet);
  27. }


最后,释放资源和句柄

  1. // 释放 RGB 图象
  2. av_free(pFrameRGB);
  3. // 释放YUV 帧
  4. av_free(pFrame);
  5. sws_freeContext(pSWSCtx);
  6. // 关闭解码器(codec)
  7. avcodec_close(pCodecCtx);
  8. // 关闭视频文件
  9. av_close_input_file(pFormatCtx);

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/272166
推荐阅读
相关标签
  

闽ICP备14008679号