AvTranscoder  0.9.4
C++APIforLibav/FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
VideoEncoder.cpp
Go to the documentation of this file.
1 #include "VideoEncoder.hpp"
2 
3 extern "C" {
4 #include <libavcodec/avcodec.h>
5 #include <libavformat/avformat.h>
6 #include <libavutil/avutil.h>
7 }
8 
9 #include <stdexcept>
10 #include <cstdlib>
11 
12 namespace avtranscoder
13 {
14 
15 VideoEncoder::VideoEncoder(const std::string& videoCodecName)
16  : _codec(eCodecTypeEncoder, videoCodecName)
17 {
18 }
19 
21 {
22 }
23 
25 {
26  if(!profile.empty())
27  {
28  LOG_INFO("Setup video encoder with:\n" << profile)
29  }
30 
31  // set width, height, pixel format, fps
32  _codec.setImageParameters(frameDesc);
33 
34  // setup encoder
35  setupEncoder(profile);
36 }
37 
39 {
40  // check the given profile
41  const bool isValid = ProfileLoader::checkVideoProfile(profile);
42  if(!isValid && !profile.empty())
43  {
44  const std::string msg("Invalid video profile to setup encoder.");
45  LOG_ERROR(msg)
46  throw std::runtime_error(msg);
47  }
48 
49  // set threads before any other options
50  if(profile.count(constants::avProfileThreads))
52  else
54 
55  // set encoder options
56  for(ProfileLoader::Profile::const_iterator it = profile.begin(); it != profile.end(); ++it)
57  {
59  (*it).first == constants::avProfileType || (*it).first == constants::avProfileCodec ||
60  (*it).first == constants::avProfileWidth || (*it).first == constants::avProfileHeight ||
61  (*it).first == constants::avProfilePixelFormat || (*it).first == constants::avProfileFrameRate ||
62  (*it).first == constants::avProfileThreads)
63  continue;
64 
65  try
66  {
67  Option& encodeOption = _codec.getOption((*it).first);
68  encodeOption.setString((*it).second);
69  }
70  catch(std::exception& e)
71  {
72  }
73  }
74 
75  // open encoder
76  int encoderFlags = 0;
77  if(profile.count(constants::avProfileProcessStat))
78  {
79  LOG_INFO("SetUp video encoder to compute statistics during process")
80  encoderFlags |= CODEC_FLAG_PSNR;
81  }
82  _codec.getAVCodecContext().flags |= encoderFlags;
83  _codec.openCodec();
84 
85  // after open encoder, set specific encoder options
86  for(ProfileLoader::Profile::const_iterator it = profile.begin(); it != profile.end(); ++it)
87  {
89  (*it).first == constants::avProfileType || (*it).first == constants::avProfileCodec ||
90  (*it).first == constants::avProfileWidth || (*it).first == constants::avProfileHeight ||
91  (*it).first == constants::avProfilePixelFormat || (*it).first == constants::avProfileFrameRate ||
92  (*it).first == constants::avProfileThreads)
93  continue;
94 
95  try
96  {
97  Option& encodeOption = _codec.getOption((*it).first);
98  encodeOption.setString((*it).second);
99  }
100  catch(std::exception& e)
101  {
102  LOG_WARN("VideoEncoder - can't set option " << (*it).first << " to " << (*it).second << ": " << e.what())
103  }
104  }
105 }
106 
107 bool VideoEncoder::encodeFrame(const Frame& sourceFrame, CodedData& codedFrame)
108 {
109  AVCodecContext& avCodecContext = _codec.getAVCodecContext();
110 
111  AVPacket& packet = codedFrame.getAVPacket();
112  if((avCodecContext.coded_frame) && (avCodecContext.coded_frame->pts != (int)AV_NOPTS_VALUE))
113  {
114  packet.pts = avCodecContext.coded_frame->pts;
115  }
116 
117  if(avCodecContext.coded_frame && avCodecContext.coded_frame->key_frame)
118  {
119  packet.flags |= AV_PKT_FLAG_KEY;
120  }
121 
122  return encode(&sourceFrame.getAVFrame(), packet);
123 }
124 
126 {
127  return encode(NULL, codedFrame.getAVPacket());
128 }
129 
130 bool VideoEncoder::encode(const AVFrame* decodedData, AVPacket& encodedData)
131 {
132  // Be sure that data of AVPacket is NULL so that the encoder will allocate it
133  encodedData.data = NULL;
134 
135  AVCodecContext& avCodecContext = _codec.getAVCodecContext();
136 #if LIBAVCODEC_VERSION_MAJOR > 53
137  int gotPacket = 0;
138  const int ret = avcodec_encode_video2(&avCodecContext, &encodedData, decodedData, &gotPacket);
139  if(ret != 0)
140  {
141  throw std::runtime_error("Encode video frame error: avcodec encode video frame - " +
143  }
144  return gotPacket == 1;
145 #else
146  const int ret = avcodec_encode_video(&avCodecContext, encodedData.data, encodedData.size, decodedData);
147  if(ret < 0)
148  {
149  throw std::runtime_error("Encode video frame error: avcodec encode video frame - " +
151  }
152  return true;
153 #endif
154 }
155 
156 }
Description to create a video frame.
Definition: VideoFrame.hpp:21
void setString(const std::string &value)
Definition: Option.cpp:187
#define LOG_ERROR(...)
Definition: log.hpp:35
const std::string avProfileFrameRate
bool encodeFrame(const Frame &sourceFrame, CodedData &codedFrame)
Encode a new frame, and get coded frame.
void setupEncoder(const ProfileLoader::Profile &profile=ProfileLoader::Profile())
Setup the encoder.
const std::string avProfileProcessStat
Do statistics during the process.
void setImageParameters(const VideoFrameDesc &videoFrameDesc)
Definition: VideoCodec.cpp:34
void setInt(const int value)
Definition: Option.cpp:169
void setupVideoEncoder(const VideoFrameDesc &frameDesc, const ProfileLoader::Profile &profile=ProfileLoader::Profile())
std::string getDescriptionFromErrorCode(const int code)
Get the string description corresponding to the error code provided by ffmpeg/libav.
Definition: common.cpp:22
AVPacket & getAVPacket()
Definition: CodedData.hpp:78
std::map< std::string, std::string > Profile
const std::string avProfileIdentificator
const std::string avProfileIdentificatorHuman
const std::string avProfilePixelFormat
#define LOG_INFO(...)
Definition: log.hpp:23
Option & getOption(const std::string &optionName)
Definition: ICodec.hpp:50
Wrapper of AVOption. Get its type to know what the option is about: Int, Double, Ratio, Choice... Parse its array of options to get the potential childs (Choice and Group).
Definition: Option.hpp:36
#define LOG_WARN(...)
Definition: log.hpp:29
VideoEncoder(const std::string &videoCodecName)
This class describes decoded (raw) audio or video data.
Definition: Frame.hpp:16
void openCodec()
Initialize the codec context.
Definition: ICodec.cpp:56
const std::string avProfileWidth
const std::string avProfileHeight
AVCodecContext & getAVCodecContext()
Definition: ICodec.hpp:53
This class describes coded data.
Definition: CodedData.hpp:18
const std::string avProfileCodec
const std::string avProfileThreads
AVFrame & getAVFrame()
Definition: Frame.hpp:88
const std::string avProfileType
bool encode(const AVFrame *decodedData, AVPacket &encodedData)
static bool checkVideoProfile(const Profile &profileToCheck)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy