Advertisement
Guest User

Untitled

a guest
Mar 7th, 2018
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.85 KB | None | 0 0
  1. #include <cstdlib>
  2. #include <iostream>
  3.  
  4. extern "C"
  5. {
  6.     #include <libavcodec/avcodec.h>
  7.     #include <libavutil/opt.h>
  8.     #include <libavutil/imgutils.h>    
  9.     #include <libavutil/common.h>
  10.     #include <stdint.h>
  11.     #include <inttypes.h>
  12.     #include <libswscale/swscale.h>
  13.     #include <libavformat/avformat.h>
  14. }
  15.  
  16. int main()
  17. {
  18.     avcodec_register_all();
  19.     av_register_all();
  20.     avformat_network_init();
  21.    
  22.  
  23.     AVCodec *m_av_codec;
  24.     AVCodecContext *m_av_codec_context;
  25.    
  26.     AVFrame *m_av_frame;
  27.     AVPacket *m_av_packet;
  28.    
  29.     uint8_t m_end_code[4];
  30.    
  31.     size_t m_pts;
  32.    
  33.     SwsContext *m_sws_context;
  34.    
  35.     AVOutputFormat *m_av_output_format;
  36.     AVFormatContext *m_av_format_context;
  37.     AVStream *m_av_stream;
  38.     AVIOContext *m_av_io_context;
  39.  
  40.     m_end_code[0] = m_end_code[1] = 0; m_end_code[2] = 1; m_end_code[3] = 0xb7;
  41.    
  42.     std::string filename = "/tmp/test.avi";
  43.    
  44.     m_av_output_format = av_guess_format(0, filename.c_str(), 0);
  45.     if (!m_av_output_format)
  46.     {
  47.         throw std::runtime_error("No matching format found");
  48.     }
  49.        
  50.     std::cout << "Allocating format context..." << std::endl;
  51.     m_av_format_context = avformat_alloc_context();
  52.     if (!m_av_format_context)
  53.     {
  54.         throw std::runtime_error("Failed to allocate format context");
  55.     }
  56.    
  57.     m_av_format_context->oformat = m_av_output_format;
  58.    
  59.     std::string m_codec_name = "libx264";
  60.    
  61.     std::cout << "Finding codec by name: " << m_codec_name << std::endl;
  62.     m_av_codec = avcodec_find_encoder_by_name(m_codec_name.c_str());
  63.     if (!m_av_codec)
  64.     {
  65.         throw std::runtime_error("Failed to find codec by name: " + m_codec_name);
  66.     }
  67.    
  68.     m_av_output_format->video_codec = m_av_codec->id;
  69.    
  70.     std::cout << "Allocating codec context..." << std::endl;
  71.     m_av_codec_context = avcodec_alloc_context3(m_av_codec);
  72.     if(!m_av_codec_context)
  73.     {
  74.         throw std::runtime_error("Failed to allocate codec context");
  75.     }
  76.  
  77.     int quality = 25;
  78.     int width = 640;
  79.     int height = 480;
  80.     int frames_per_second = 20;
  81.    
  82.     std::cout << "Setting codec context parameters..." << std::endl;
  83.     // m_av_codec_context->bit_rate = 400000;
  84.     m_av_codec_context->qmin = quality;
  85.     m_av_codec_context->qmax = quality + 1;
  86.     m_av_codec_context->width = width;
  87.     m_av_codec_context->height = height;
  88.     //m_av_codec_context->time_base = m_av_stream->time_base;
  89.     m_av_codec_context->time_base.num = 1;
  90.     m_av_codec_context->time_base.den = frames_per_second;
  91.     m_av_codec_context->framerate.num = frames_per_second;
  92.     m_av_codec_context->framerate.den = 1;
  93.    
  94.     m_av_codec_context->gop_size = 10;
  95.     m_av_codec_context->max_b_frames = 1;
  96.     m_av_codec_context->pix_fmt = AV_PIX_FMT_YUV420P;
  97.    
  98.     if (m_av_format_context->oformat->flags & AVFMT_GLOBALHEADER)
  99.     {
  100.         m_av_codec_context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
  101.     }
  102.  
  103.  
  104.     // weirdly this has to be done after setting up some stuff
  105.     // in the codec_context (see above.) If this is called
  106.     // before the setting up of codec parameters then we get an
  107.     // error "The encoder timebase is not set"
  108.     std::cout << "Initializing codec context..." << std::endl;
  109.     int ret = avcodec_open2(m_av_codec_context, m_av_codec, NULL);
  110.     //int ret = avcodec_open2(m_av_codec_context, NULL, NULL);
  111.     if (ret < 0)
  112.     {
  113.         throw std::runtime_error("Could not initialize codec context");
  114.     }
  115.  
  116. #if 0
  117.     if (m_av_codec->id == AV_CODEC_ID_H264)
  118.     {
  119.             av_opt_set(m_av_codec_context->priv_data, "preset", "medium", 0);
  120.     }
  121. #endif
  122.    
  123.     std::cout << "Creating new stream..." << std::endl;
  124.     m_av_stream = avformat_new_stream(m_av_format_context, m_av_codec);
  125.     if (!m_av_stream)
  126.     {
  127.         throw std::runtime_error("Failed to create stream");
  128.     }
  129.    
  130.     // m_av_codec_context = m_av_stream->codec;
  131.     // m_av_codec_context = m_av_codec_context;
  132.    
  133.     m_av_stream->time_base.num = 1;
  134.     m_av_stream->time_base.den = frames_per_second;
  135.    
  136.     m_av_stream->codecpar->width = width;
  137.     m_av_stream->codecpar->height = height;
  138.  
  139.  
  140.    
  141.     std::cout << "Allocating packet..." << std::endl;
  142.     m_av_packet = av_packet_alloc();
  143.     if (!m_av_packet)
  144.     {
  145.         throw std::runtime_error("Failed to allocate packet");
  146.     }
  147.    
  148.     if (!(m_av_output_format->flags & AVFMT_NOFILE))
  149.     {
  150.         std::cout << "Opening format context..." << std::endl;
  151.         if (avio_open(&m_av_format_context->pb, filename.c_str(), AVIO_FLAG_READ_WRITE) < 0)
  152.         {
  153.             throw std::runtime_error("Could not open stream");
  154.         }
  155.     }
  156.  
  157.     std::cout << "Writing header..." << std::endl;
  158.     if (avformat_write_header(m_av_format_context, 0) < 0)
  159.     {
  160.         throw std::runtime_error("Failed to write stream header");
  161.     }        
  162.    
  163.     std::cout << "Allocating frame..." << std::endl;
  164.     m_av_frame = av_frame_alloc();
  165.     if (!m_av_frame)
  166.     {
  167.         throw std::runtime_error("Failed to allocate frame");
  168.     }
  169.    
  170.     m_av_frame->format = m_av_codec_context->pix_fmt;
  171.     m_av_frame->width = m_av_codec_context->width;
  172.     m_av_frame->height = m_av_codec_context->height;
  173.    
  174.     ret = av_frame_get_buffer(m_av_frame, 32);
  175.     if (ret < 0)
  176.     {
  177.         throw std::runtime_error("Failed to get buffer");
  178.     }
  179.    
  180.     std::cout << "Getting SWScale context..." << std::endl;
  181.     m_sws_context = sws_getContext(
  182.         m_av_codec_context->width,
  183.         m_av_codec_context->height,
  184.         AV_PIX_FMT_GRAY8,
  185.         m_av_codec_context->width,
  186.         m_av_codec_context->height,
  187.         AV_PIX_FMT_YUV420P,
  188.         SWS_BILINEAR, NULL, NULL, NULL);
  189.    
  190.     if (!m_sws_context)
  191.     {
  192.         throw std::runtime_error("Failed to create conversion context");
  193.     }
  194.    
  195.  
  196.     return EXIT_SUCCESS;
  197. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement