我在哪里可以找到libav,FFMPEG等现代教程? [关闭](Where can I find

2019-08-08 14:35发布

我想要在C快速程序,将打开一个视频,保存每一帧作为一个PPM,并转储运动矢量。 所有我能找到的教程是从大约十年前,并呼吁取消或不存在的功能。

是否有良好的网上资源,网站,视频,或教科书是涵盖了现代的方式做这些类型的东西?

Answer 1:

我一直在努力的有关ffmpeg和libav了好几年,也没有发现任何像样的近期API级别的教程。 有时候,我只是潜入源弄清楚是怎么回事,以及如何使用它。 此外,读取的CLI程序(其使用底层库)源也可以是提供信息。

其实, ffmpeg的建议,你刚才读的源代码,无论是真正的OSS项目或他们的榜样。 Libav提供Doxygen文档,但没有一步一步的教程。 IMO这是典型的开源项目:源可能是好的,但文件往往缺乏。

退一步说,你可能会考虑OpenCV的 ,这是有据可查的( 书存在!),并有一个更简单的API。 最后,PPM就是这样一个简单的格式,你可能可以写一个50线功能,像素保存自己,我发现了一个运动提取程序在这里 。



Answer 2:

        #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <fstream>
    #include <math.h>

    #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; y<sheight; y++)
    {
      fwrite(sAVFrame->data[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; i<pAVFormatContext->nb_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 :"<<videoFPS;
    cout<<"\n\n width : "<<Vwidth;
    cout<<"\n\n height : "<<Vheight;
    cout<<"\n\n time base"<<videoBaseTime;
    //cout<<"\n\nduration (1): "<<duration_1;
    //cout<<"\n\nduration (2): "<<duration_2;

    CaptureScene( VideoStreamIndx , pAVFormatContext , pAVCodecContext , pAVCodec );

    avcodec_close(pAVCodecContext);
    avformat_close_input(&pAVFormatContext);

    return 0;
    }

这个C ++代码将帮助您从USB(UVC)基于摄像头获取的图像.ppm格式。 它保存在.ppm格式格式。 使用V4L2 Linux和用于dshow的窗户。 代替照相机进帧,视频也可作为一个输入。 这个代码用熟ffmpeg的最新库。

libavutil 55 24100/55 24100

libavcodec的57. 43.100 / 43.100 57.

了libavformat 57. 37.100 / 37.100 57.

libavdevice 57. 0.101 / 0.101 57

libavfilter 6. 46.100 / 6. 46.100

libswscale 4. 1.100 / 1.100 4.

libswresample 2. 0.101 / 0.101 2

libpostproc 54. 0.100 / 0.100 54



文章来源: Where can I find modern tutorials for libav, ffmpeg, etc? [closed]
标签: c ffmpeg libav