AvTranscoder  0.9.4
C++APIforLibav/FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
VideoDecoder.cpp
Go to the documentation of this file.
1 #include "VideoDecoder.hpp"
2 
6 
7 extern "C" {
8 #include <libavcodec/avcodec.h>
9 #include <libavformat/avformat.h>
10 #include <libavutil/avutil.h>
11 #include <libavutil/pixdesc.h>
12 }
13 
14 #include <stdexcept>
15 
16 namespace avtranscoder
17 {
18 
20  : _inputStream(&inputStream)
21  , _isSetup(false)
22 {
23 }
24 
26 {
27 }
28 
30 {
31  // check the given profile
32  const bool isValid = ProfileLoader::checkVideoProfile(profile);
33  if(!isValid && !profile.empty())
34  {
35  const std::string msg("Invalid video profile to setup decoder.");
36  LOG_ERROR(msg)
37  throw std::runtime_error(msg);
38  }
39 
40  if(!profile.empty())
41  {
42  LOG_INFO("Setup video decoder with:\n" << profile)
43  }
44 
46 
47  // set threads before any other options
48  if(profile.count(constants::avProfileThreads))
50  else
52 
53  // set decoder options
54  for(ProfileLoader::Profile::const_iterator it = profile.begin(); it != profile.end(); ++it)
55  {
57  (*it).first == constants::avProfileType || (*it).first == constants::avProfileThreads)
58  continue;
59 
60  try
61  {
62  Option& decodeOption = codec.getOption((*it).first);
63  decodeOption.setString((*it).second);
64  }
65  catch(std::exception& e)
66  {
67  LOG_WARN("VideoDecoder - can't set option " << (*it).first << " to " << (*it).second << ": " << e.what())
68  }
69  }
70 
71  // open decoder
73  _isSetup = true;
74 }
75 
77 {
78  bool decodeNextFrame = false;
79 
80  if(!_isSetup)
81  setupDecoder();
82 
83  int got_frame = 0;
84  while(!got_frame)
85  {
86  CodedData data;
87 
88  // reading
89  const bool nextPacketRead = _inputStream->readNextPacket(data);
90 
91  // decoding
92  // @note could be called several times to return the remaining frames (last call with an empty packet)
93  // @see CODEC_CAP_DELAY
94  const int ret = avcodec_decode_video2(&_inputStream->getVideoCodec().getAVCodecContext(), &frameBuffer.getAVFrame(),
95  &got_frame, &data.getAVPacket());
96  if(ret < 0)
97  {
98  throw std::runtime_error("an error occured during video decoding - " + getDescriptionFromErrorCode(ret));
99  }
100 
101  // if no frame could be decompressed
102  if(!nextPacketRead && ret == 0 && got_frame == 0)
103  decodeNextFrame = false;
104  else
105  decodeNextFrame = true;
106 
107  // if no frame read and decompressed
108  if(!nextPacketRead && !decodeNextFrame)
109  {
110  data.clear();
111  return false;
112  }
113  }
114  return decodeNextFrame;
115 }
116 
117 bool VideoDecoder::decodeNextFrame(Frame& frameBuffer, const size_t subStreamIndex)
118 {
119  return false;
120 }
121 
123 {
124  avcodec_flush_buffers(&_inputStream->getVideoCodec().getAVCodecContext());
125 }
126 }
bool readNextPacket(CodedData &data)
Read the next packet of the stream.
Definition: InputStream.cpp:53
void setString(const std::string &value)
Definition: Option.cpp:187
#define LOG_ERROR(...)
Definition: log.hpp:35
void clear()
Clear existing data and set size to 0.
Definition: CodedData.cpp:71
void setInt(const int value)
Definition: Option.cpp:169
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
#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
This class describes decoded (raw) audio or video data.
Definition: Frame.hpp:16
InputStream * _inputStream
Stream from which we read next frames (no ownership, has link)
void openCodec()
Initialize the codec context.
Definition: ICodec.cpp:56
AVCodecContext & getAVCodecContext()
Definition: ICodec.hpp:53
This class describes coded data.
Definition: CodedData.hpp:18
void flushDecoder()
Reset the internal decoder state / flush internal buffers.
VideoCodec & getVideoCodec()
Definition: InputStream.cpp:75
const std::string avProfileThreads
bool decodeNextFrame(Frame &frameBuffer)
Decode next frame.
AVFrame & getAVFrame()
Definition: Frame.hpp:88
VideoDecoder(InputStream &inputStream)
const std::string avProfileType
void setupDecoder(const ProfileLoader::Profile &profile=ProfileLoader::Profile())
Setup the decoder.
static bool checkVideoProfile(const Profile &profileToCheck)