我在哪里可以找到libav,ffmpeg等的现代教程?

我想在C中制作一个快速程序,它将打开一个video,将每个帧保存为ppm,并转储运动矢量。 我能找到的所有教程都是差不多十年前的,并且调用了已弃用或不存在的函数。

是否有任何良好的在线资源,网站,video或教科书涵盖了做这类事情的现代方法?

我已经使用ffmpeg和libav好几年了,也发现没有像样的最新API级教程。 有时我只需要深入了解源代码以了解发生了什么以及如何使用它。 此外,阅读CLI程序(使用底层库)的源代码也可以提供信息。

事实上, ffmpeg建议您只阅读源代码,无论是对于真实的OSS项目还是他们的示例。 Libav提供Doxygen文档,但没有逐步的教程。 IMO这是典型的开源项目:源代码可能很好,但通常缺乏文档。

退一步,你可能会考虑OpenCV ,它有很好的文档记录( 书籍存在!)并且有一个更简单的API。 最后,ppm是一种简单的格式,您可以编写50行函数来自己保存像素,我在这里找到了一个运动提取程序。

#include  #include  #include  #include  #include  #define __STDC_CONSTANT_MACROS //FFMPEG LIBRARIES extern "C" { #include "libavcodec/avcodec.h" #include "libswscale/swscale.h" #include "libavutil/opt.h" #include "libavutil/common.h" #include "libavutil/channel_layout.h" #include "libavutil/imgutils.h" #include "libavutil/mathematics.h" #include "libavutil/samplefmt.h" #include "libavutil/time.h" #include "libavformat/avformat.h" #include "libavformat/avio.h" #include "libavfilter/avfilter.h" #include "libavdevice/avdevice.h" #include "libavfilter/avfiltergraph.h" #include "libavfilter/buffersink.h" } using namespace std; void SaveMyFrame(AVFrame *sAVFrame , int swidth, int sheight, int iFrame) { FILE *pfile; char szFilename[32]; int y; sprintf(szFilename , "frame%d.ppm" , iFrame); pfile = fopen(szFilename , "wb"); if(pfile == NULL) { cout<<"\n\ncould'nt open file"; return; } fprintf(pfile , "P6\n%d %d\n255\n" , swidth , sheight ); for( y=0; ydata[0]+y*sAVFrame->linesize[0] , 1 , swidth*3 , pfile ); } fclose(pfile); } int CaptureScene(int VideoStreamIndx , AVFormatContext *bAVFormatContext , AVCodecContext *bAVCodecContext, AVCodec *bAVCodec ) { AVPacket bAVPacket; AVFrame *bAVFrame = NULL; bAVFrame = av_frame_alloc(); AVFrame *bAVFrameRGB = NULL; bAVFrameRGB = av_frame_alloc(); if(bAVFrame == NULL) { cout<<"\n\nframe alloc failed"; } if(bAVFrameRGB == NULL) { cout<<"\n\nframe alloc RGB failed"; } int numBytes; uint8_t *buffer = NULL; numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGB24 , bAVCodecContext->width,bAVCodecContext->height, 32); // avpicture_get_size deprecated buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t)); avpicture_fill((AVPicture *)bAVFrameRGB , buffer , AV_PIX_FMT_RGB24 , bAVCodecContext->width , bAVCodecContext->height); int framefinish; struct SwsContext *sws_ctx = NULL; sws_ctx = sws_getContext( bAVCodecContext->width, bAVCodecContext->height, bAVCodecContext->pix_fmt, bAVCodecContext->width, bAVCodecContext->height, AV_PIX_FMT_RGB24, SWS_BILINEAR, NULL,NULL,NULL); int i =0; while(av_read_frame(bAVFormatContext,&bAVPacket) >=0) { if(bAVPacket.stream_index == VideoStreamIndx) { avcodec_decode_video2(bAVCodecContext , bAVFrame , &framefinish , &bAVPacket); if(framefinish) { // convert image from native format to RGB sws_scale(sws_ctx , (uint8_t const* const *)bAVFrame->data , bAVFrame->linesize , 0, bAVCodecContext->height, bAVFrameRGB->data , bAVFrameRGB->linesize); // save frame to disk if(++i <= 100)SaveMyFrame(bAVFrameRGB , bAVCodecContext->width , bAVCodecContext->height , i ); } } } av_free(bAVFrame); av_free(bAVFrameRGB); } int main() { avdevice_register_all(); avcodec_register_all(); av_register_all(); char *dev_name = "/dev/video0"; int VideoStreamIndx = -1; AVCodecContext *pAVCodecContext = NULL; AVCodec *pAVCodec = NULL; AVInputFormat *inputFormat =av_find_input_format("v4l2"); AVDictionary *options = NULL; av_dict_set(&options, "framerate", "20", 0); AVFormatContext *pAVFormatContext = NULL; if(avformat_open_input(&pAVFormatContext, dev_name, inputFormat, NULL) != 0) { cout<<"\nError : could'nt open video source\n\n"; return -1; } if( avformat_find_stream_info( pAVFormatContext , NULL) < 0) { cout<<"Error : streams not found"; return -1; } av_dump_format(pAVFormatContext , 0 , "/dev/video1" , 0 ); for(int i=0; inb_streams ;i++ ) { if( pAVFormatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO ) // if video stream found then get the index. { VideoStreamIndx = i; break; } } if((VideoStreamIndx) == -1) { cout<<"Error : video streams not found"; return -1; } pAVCodecContext = pAVFormatContext->streams[VideoStreamIndx]->codec; pAVCodec = avcodec_find_decoder( pAVCodecContext->codec_id ); if(pAVCodec == NULL) { fprintf(stderr,"Unsupported codec !"); return -1; } int value = avcodec_open2(pAVCodecContext , pAVCodec , NULL); if( value < 0) { cout<<"Error : Could not open codec"; return -1; } int Vwidth , Vheight , videoFPS , videoBaseTime , duration_2 ; int sframe , length , Fheight; /* To fetch/display some media information programatically */ //int64_t duration_1 = pAVFormatContext->duration; videoFPS = av_q2d(pAVFormatContext->streams[VideoStreamIndx]->r_frame_rate); videoBaseTime = av_q2d(pAVFormatContext->streams[VideoStreamIndx]->time_base); Vwidth = pAVFormatContext->streams[VideoStreamIndx]->codec->width; Vheight = pAVFormatContext->streams[VideoStreamIndx]->codec->height; //duration_2 = (unsigned long)pAVFormatContext->streams[VideoStreamIndx]->duration*(videoFPS*videoBaseTime); cout<<"Video FPS :"< 

这个C ++代码将帮助您从基于USB(UVC)的相机获得.ppm图像。 它以.ppm格式保存。 使用v4l2 for linux和dshow for windows。 而不是相机帧馈送,video也可以作为输入。 这段代码用最新的ffmpeg库编写。

libavutil 55. 24.100 / 55. 24.100

libavcodec 57. 43.100 / 57. 43.100

libavformat 57. 37.100 / 57. 37.100

libavdevice 57. 0.101 / 57. 0.101

libavfilter 6. 46.100 / 6. 46.100

libswscale 4. 1.100 / 4. 1.100

libswresample 2. 0.101 / 2. 0.101

libpostproc 54. 0.100 / 54. 0.100