Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdlib>
- #include <iostream>
- extern "C"
- {
- #include <libavcodec/avcodec.h>
- #include <libavutil/opt.h>
- #include <libavutil/imgutils.h>
- #include <libavutil/common.h>
- #include <stdint.h>
- #include <inttypes.h>
- #include <libswscale/swscale.h>
- #include <libavformat/avformat.h>
- }
- int main()
- {
- avcodec_register_all();
- av_register_all();
- avformat_network_init();
- AVCodec *m_av_codec;
- AVCodecContext *m_av_codec_context;
- AVFrame *m_av_frame;
- AVPacket *m_av_packet;
- uint8_t m_end_code[4];
- size_t m_pts;
- SwsContext *m_sws_context;
- AVOutputFormat *m_av_output_format;
- AVFormatContext *m_av_format_context;
- AVStream *m_av_stream;
- AVIOContext *m_av_io_context;
- m_end_code[0] = m_end_code[1] = 0; m_end_code[2] = 1; m_end_code[3] = 0xb7;
- std::string filename = "/tmp/test.avi";
- m_av_output_format = av_guess_format(0, filename.c_str(), 0);
- if (!m_av_output_format)
- {
- throw std::runtime_error("No matching format found");
- }
- std::cout << "Allocating format context..." << std::endl;
- m_av_format_context = avformat_alloc_context();
- if (!m_av_format_context)
- {
- throw std::runtime_error("Failed to allocate format context");
- }
- m_av_format_context->oformat = m_av_output_format;
- std::string m_codec_name = "libx264";
- std::cout << "Finding codec by name: " << m_codec_name << std::endl;
- m_av_codec = avcodec_find_encoder_by_name(m_codec_name.c_str());
- if (!m_av_codec)
- {
- throw std::runtime_error("Failed to find codec by name: " + m_codec_name);
- }
- m_av_output_format->video_codec = m_av_codec->id;
- std::cout << "Allocating codec context..." << std::endl;
- m_av_codec_context = avcodec_alloc_context3(m_av_codec);
- if(!m_av_codec_context)
- {
- throw std::runtime_error("Failed to allocate codec context");
- }
- int quality = 25;
- int width = 640;
- int height = 480;
- int frames_per_second = 20;
- std::cout << "Setting codec context parameters..." << std::endl;
- // m_av_codec_context->bit_rate = 400000;
- m_av_codec_context->qmin = quality;
- m_av_codec_context->qmax = quality + 1;
- m_av_codec_context->width = width;
- m_av_codec_context->height = height;
- //m_av_codec_context->time_base = m_av_stream->time_base;
- m_av_codec_context->time_base.num = 1;
- m_av_codec_context->time_base.den = frames_per_second;
- m_av_codec_context->framerate.num = frames_per_second;
- m_av_codec_context->framerate.den = 1;
- m_av_codec_context->gop_size = 10;
- m_av_codec_context->max_b_frames = 1;
- m_av_codec_context->pix_fmt = AV_PIX_FMT_YUV420P;
- if (m_av_format_context->oformat->flags & AVFMT_GLOBALHEADER)
- {
- m_av_codec_context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
- }
- // weirdly this has to be done after setting up some stuff
- // in the codec_context (see above.) If this is called
- // before the setting up of codec parameters then we get an
- // error "The encoder timebase is not set"
- std::cout << "Initializing codec context..." << std::endl;
- int ret = avcodec_open2(m_av_codec_context, m_av_codec, NULL);
- //int ret = avcodec_open2(m_av_codec_context, NULL, NULL);
- if (ret < 0)
- {
- throw std::runtime_error("Could not initialize codec context");
- }
- #if 0
- if (m_av_codec->id == AV_CODEC_ID_H264)
- {
- av_opt_set(m_av_codec_context->priv_data, "preset", "medium", 0);
- }
- #endif
- std::cout << "Creating new stream..." << std::endl;
- m_av_stream = avformat_new_stream(m_av_format_context, m_av_codec);
- if (!m_av_stream)
- {
- throw std::runtime_error("Failed to create stream");
- }
- // m_av_codec_context = m_av_stream->codec;
- // m_av_codec_context = m_av_codec_context;
- m_av_stream->time_base.num = 1;
- m_av_stream->time_base.den = frames_per_second;
- m_av_stream->codecpar->width = width;
- m_av_stream->codecpar->height = height;
- std::cout << "Allocating packet..." << std::endl;
- m_av_packet = av_packet_alloc();
- if (!m_av_packet)
- {
- throw std::runtime_error("Failed to allocate packet");
- }
- if (!(m_av_output_format->flags & AVFMT_NOFILE))
- {
- std::cout << "Opening format context..." << std::endl;
- if (avio_open(&m_av_format_context->pb, filename.c_str(), AVIO_FLAG_READ_WRITE) < 0)
- {
- throw std::runtime_error("Could not open stream");
- }
- }
- std::cout << "Writing header..." << std::endl;
- if (avformat_write_header(m_av_format_context, 0) < 0)
- {
- throw std::runtime_error("Failed to write stream header");
- }
- std::cout << "Allocating frame..." << std::endl;
- m_av_frame = av_frame_alloc();
- if (!m_av_frame)
- {
- throw std::runtime_error("Failed to allocate frame");
- }
- m_av_frame->format = m_av_codec_context->pix_fmt;
- m_av_frame->width = m_av_codec_context->width;
- m_av_frame->height = m_av_codec_context->height;
- ret = av_frame_get_buffer(m_av_frame, 32);
- if (ret < 0)
- {
- throw std::runtime_error("Failed to get buffer");
- }
- std::cout << "Getting SWScale context..." << std::endl;
- m_sws_context = sws_getContext(
- m_av_codec_context->width,
- m_av_codec_context->height,
- AV_PIX_FMT_GRAY8,
- m_av_codec_context->width,
- m_av_codec_context->height,
- AV_PIX_FMT_YUV420P,
- SWS_BILINEAR, NULL, NULL, NULL);
- if (!m_sws_context)
- {
- throw std::runtime_error("Failed to create conversion context");
- }
- return EXIT_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement