Skip to content

Commit 534c6a7

Browse files
update Desc structures and input for AudioDesc
1 parent d82a388 commit 534c6a7

File tree

8 files changed

+307
-15
lines changed

8 files changed

+307
-15
lines changed
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
#include "AudioDesc.hpp"
2+
3+
extern "C" {
4+
#ifndef __STDC_CONSTANT_MACROS
5+
#define __STDC_CONSTANT_MACROS
6+
#endif
7+
#include <libavcodec/avcodec.h>
8+
#include <libavformat/avformat.h>
9+
#include <libavutil/avutil.h>
10+
#include <libavutil/pixdesc.h>
11+
#include <libavutil/imgutils.h>
12+
#include <libavutil/mathematics.h>
13+
#include <libavutil/opt.h>
14+
#include <libavutil/error.h>
15+
}
16+
#include <iostream>
17+
#include <stdexcept>
18+
#include <sstream>
19+
20+
namespace avtranscoder
21+
{
22+
23+
AudioDesc::AudioDesc( const std::string& codecName )
24+
: m_codec( NULL )
25+
, m_codecContext( NULL )
26+
{
27+
if( codecName.size() )
28+
setAudioCodec( codecName );
29+
}
30+
31+
AudioDesc::AudioDesc( const AVCodecID codecId )
32+
: m_codec( NULL )
33+
, m_codecContext( NULL )
34+
{
35+
setAudioCodec( codecId );
36+
}
37+
38+
void AudioDesc::setAudioCodec( const std::string& codecName )
39+
{
40+
avcodec_register_all(); // Warning: should be called only once
41+
m_codec = avcodec_find_encoder_by_name( codecName.c_str() );
42+
initCodecContext();
43+
}
44+
45+
void AudioDesc::setAudioCodec( const AVCodecID codecId )
46+
{
47+
avcodec_register_all(); // Warning: should be called only once
48+
m_codec = avcodec_find_encoder( codecId );
49+
initCodecContext();
50+
}
51+
52+
void AudioDesc::initCodecContext( )
53+
{
54+
if( m_codec == NULL )
55+
return;
56+
57+
if( ( m_codecContext = avcodec_alloc_context3( m_codec ) ) == NULL )
58+
return;
59+
60+
// Set default codec parameters
61+
if( avcodec_get_context_defaults3( m_codecContext, m_codec ) != 0 )
62+
{
63+
m_codecContext = NULL;
64+
return;
65+
}
66+
}
67+
68+
void AudioDesc::set( const std::string& key, const std::string& flag, const bool enable )
69+
{
70+
int error = 0;
71+
int64_t optVal;
72+
73+
const AVOption* flagOpt = av_opt_find( m_codecContext, flag.c_str(), key.c_str(), 0, 0 );
74+
75+
if( ! flagOpt )
76+
{
77+
std::cout << flag << std::endl << " : " << flagOpt->default_val.i64 << std::endl;
78+
throw std::runtime_error( "unknown flag " + flag );
79+
}
80+
81+
error = av_opt_get_int( m_codecContext, key.c_str(), AV_OPT_SEARCH_CHILDREN, &optVal );
82+
if( error != 0 )
83+
{
84+
std::string err( "", AV_ERROR_MAX_STRING_SIZE );
85+
av_make_error_string( const_cast<char*>(err.c_str()), err.size(), error );
86+
throw std::runtime_error( "unknown key " + key + ": " + err );
87+
}
88+
89+
if( enable )
90+
optVal = optVal | flagOpt->default_val.i64;
91+
else
92+
optVal = optVal &~ flagOpt->default_val.i64;
93+
94+
error = av_opt_set_int( m_codecContext, key.c_str(), optVal, AV_OPT_SEARCH_CHILDREN );
95+
if( error != 0 )
96+
{
97+
std::string err( "", AV_ERROR_MAX_STRING_SIZE );
98+
av_make_error_string( const_cast<char*>(err.c_str()), err.size(), error );
99+
throw std::runtime_error( "setting " + key + " parameter to " + flag + ": " + err );
100+
}
101+
}
102+
103+
void AudioDesc::set( const std::string& key, const bool value )
104+
{
105+
int error = av_opt_set_int( m_codecContext, key.c_str(), value, AV_OPT_SEARCH_CHILDREN );
106+
if( error != 0 )
107+
{
108+
std::string err( "", AV_ERROR_MAX_STRING_SIZE );
109+
av_make_error_string( const_cast<char*>(err.c_str()), err.size(), error );
110+
throw std::runtime_error( "setting " + key + " parameter to " + ( value ? "true" : "false" ) + ": " + err );
111+
}
112+
}
113+
114+
void AudioDesc::set( const std::string& key, const int value )
115+
{
116+
const AVOption* flagOpt = av_opt_find( m_codecContext, key.c_str(), NULL, 0, AV_OPT_SEARCH_CHILDREN );
117+
118+
int error = av_opt_set_int( m_codecContext, key.c_str(), value, AV_OPT_SEARCH_CHILDREN );
119+
if( error != 0 )
120+
{
121+
std::ostringstream os;
122+
os << value;
123+
std::string err( "", AV_ERROR_MAX_STRING_SIZE );
124+
av_make_error_string( const_cast<char*>(err.c_str()), err.size(), error );
125+
throw std::runtime_error( "setting " + key + " parameter to " + os.str() + ": " + err );
126+
}
127+
}
128+
129+
void AudioDesc::set( const std::string& key, const int num, const int den )
130+
{
131+
AVRational ratio;
132+
ratio.num = num;
133+
ratio.den = den;
134+
int error = av_opt_set_q( m_codecContext, key.c_str(), ratio, AV_OPT_SEARCH_CHILDREN );
135+
if( error != 0 )
136+
{
137+
std::ostringstream os;
138+
os << num << "/" << den;
139+
std::string err( "", AV_ERROR_MAX_STRING_SIZE );
140+
av_make_error_string( const_cast<char*>(err.c_str()), err.size(), error );
141+
throw std::runtime_error( "setting " + key + " parameter to " + os.str() + ": " + err );
142+
}
143+
}
144+
145+
void AudioDesc::set( const std::string& key, const double value )
146+
{
147+
int error = av_opt_set_double( m_codecContext, key.c_str(), value, AV_OPT_SEARCH_CHILDREN );
148+
if( error != 0 )
149+
{
150+
std::ostringstream os;
151+
os << value;
152+
std::string err( "", AV_ERROR_MAX_STRING_SIZE );
153+
av_make_error_string( const_cast<char*>(err.c_str()), err.size(), error );
154+
throw std::runtime_error( "setting " + key + " parameter to " + os.str() + ": " + err );
155+
}
156+
}
157+
158+
void AudioDesc::set( const std::string& key, const std::string& value )
159+
{
160+
int error = av_opt_set( m_codecContext, key.c_str(), value.c_str(), AV_OPT_SEARCH_CHILDREN );
161+
if( error != 0 )
162+
{
163+
std::string err( "", AV_ERROR_MAX_STRING_SIZE );
164+
av_make_error_string( const_cast<char*>(err.c_str()), err.size(), error );
165+
throw std::runtime_error( "setting " + key + " parameter to " + value + ": " + err );
166+
}
167+
}
168+
169+
std::string AudioDesc::getAudioCodec() const
170+
{
171+
return m_codecContext->codec_name;
172+
}
173+
174+
AVCodecID AudioDesc::getAudioCodecId() const
175+
{
176+
return m_codecContext->codec_id;
177+
}
178+
179+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#ifndef _AV_TRANSCODER_DATA_AUDIO_DESC_HPP_
2+
#define _AV_TRANSCODER_DATA_AUDIO_DESC_HPP_
3+
4+
#include "Image.hpp"
5+
#include <string>
6+
7+
extern "C" {
8+
#ifndef __STDC_CONSTANT_MACROS
9+
#define __STDC_CONSTANT_MACROS
10+
#endif
11+
#ifndef INT64_C
12+
#define INT64_C(c) (c ## LL)
13+
#define UINT64_C(c) (c ## ULL)
14+
#endif
15+
#include <libavcodec/avcodec.h>
16+
}
17+
18+
namespace avtranscoder
19+
{
20+
21+
class AudioDesc
22+
{
23+
public:
24+
AudioDesc( const std::string& codecName = "" );
25+
AudioDesc( const AVCodecID codecId );
26+
27+
void setAudioCodec( const std::string& codecName );
28+
void setAudioCodec( const AVCodecID codecId );
29+
30+
void set( const std::string& key, const std::string& flag, const bool enable );
31+
void set( const std::string& key, const bool value );
32+
void set( const std::string& key, const int value );
33+
void set( const std::string& key, const int num, const int den );
34+
void set( const std::string& key, const double value );
35+
void set( const std::string& key, const std::string& value );
36+
37+
std::string getAudioCodec() const;
38+
AVCodecID getAudioCodecId() const;
39+
40+
#ifndef SWIG
41+
AVCodec* getCodec() const { return m_codec; }
42+
AVCodecContext* getCodecContext() const { return m_codecContext; }
43+
#endif
44+
45+
private:
46+
void initCodecContext( );
47+
48+
void checkError( int error );
49+
50+
AVCodec* m_codec;
51+
AVCodecContext* m_codecContext;
52+
};
53+
54+
}
55+
56+
#endif

src/AvTranscoder/DatasStructures/VideoDesc.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,23 @@ void VideoDesc::setTimeBase( const size_t num, const size_t den )
7373
m_codecContext->time_base.den = den;
7474
}
7575

76+
std::string VideoDesc::getVideoCodec() const
77+
{
78+
return m_codecContext->codec_name;
79+
}
80+
81+
AVCodecID VideoDesc::getVideoCodecId() const
82+
{
83+
return m_codecContext->codec_id;
84+
}
85+
86+
std::pair< size_t, size_t > VideoDesc::getTimeBase() const
87+
{
88+
std::pair< size_t, size_t > timeBase;
89+
timeBase.first = m_codecContext->time_base.num;
90+
timeBase.second = m_codecContext->time_base.den;
91+
}
92+
7693
void VideoDesc::initCodecContext( )
7794
{
7895
if( m_codec == NULL )

src/AvTranscoder/DatasStructures/VideoDesc.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,18 @@ class VideoDesc
3232
void setImageParameters( const size_t width, const size_t height, const AVPixelFormat& pixel );
3333

3434
void setTimeBase( const size_t num, const size_t den );
35-
35+
3636
void set( const std::string& key, const std::string& flag, const bool enable );
3737
void set( const std::string& key, const bool value );
3838
void set( const std::string& key, const int value );
3939
void set( const std::string& key, const int num, const int den );
4040
void set( const std::string& key, const double value );
4141
void set( const std::string& key, const std::string& value );
4242

43+
std::string getVideoCodec() const;
44+
AVCodecID getVideoCodecId() const;
45+
std::pair< size_t, size_t > getTimeBase() const;
46+
4347
#ifndef SWIG
4448
AVCodec* getCodec() const { return m_codec; }
4549
AVCodecContext* getCodecContext() const { return m_codecContext; }

src/AvTranscoder/InputFile.cpp

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ extern "C" {
2020

2121
#include <iostream>
2222
#include <stdexcept>
23+
#include <cassert>
2324

2425
namespace avtranscoder
2526
{
@@ -45,6 +46,8 @@ InputFile::~InputFile()
4546
InputFile& InputFile::setup( const std::string& filename )
4647
{
4748
m_filename = filename;
49+
assert( m_formatContext == NULL );
50+
4851
if( avformat_open_input( &m_formatContext, m_filename.c_str(), NULL, NULL ) < 0 )
4952
{
5053
throw std::runtime_error( "unable to open file" );
@@ -142,7 +145,9 @@ VideoDesc InputFile::getVideoDesc( size_t videoStreamId )
142145
}
143146

144147
if( selectedStream == -1 )
145-
throw std::runtime_error( "unable to find video stream" );
148+
{
149+
throw std::runtime_error( "unable to find video stream " );
150+
}
146151

147152
AVCodecContext* codecContext = m_formatContext->streams[selectedStream]->codec;
148153

@@ -154,6 +159,35 @@ VideoDesc InputFile::getVideoDesc( size_t videoStreamId )
154159
return desc;
155160
}
156161

162+
AudioDesc InputFile::getAudioDesc( size_t audioStreamId )
163+
{
164+
int selectedStream = -1;
165+
size_t audioStreamCount = 0;
166+
167+
for( size_t streamId = 0; streamId < m_formatContext->nb_streams; streamId++ )
168+
{
169+
if( m_formatContext->streams[streamId]->codec->codec_type == AVMEDIA_TYPE_AUDIO )
170+
{
171+
if( audioStreamCount == audioStreamId )
172+
{
173+
selectedStream = streamId;
174+
}
175+
audioStreamCount++;
176+
}
177+
}
178+
179+
if( selectedStream == -1 )
180+
{
181+
throw std::runtime_error( "unable to find audio stream " );
182+
}
183+
184+
AVCodecContext* codecContext = m_formatContext->streams[selectedStream]->codec;
185+
186+
AudioDesc desc( codecContext->codec_id );
187+
188+
return desc;
189+
}
190+
157191
bool InputFile::unwrap( DataStream& data, const size_t streamIndex )
158192
{
159193
AVPacket packet;

src/AvTranscoder/InputFile.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define _AV_TRANSCODER_INPUT_FILE_HPP_
33

44
#include "DatasStructures/DataStreamDesc.hpp"
5+
#include "DatasStructures/AudioDesc.hpp"
56
#include "DatasStructures/VideoDesc.hpp"
67
#include "Metadatas/MediaMetadatasStructures.hpp"
78

@@ -33,7 +34,7 @@ class InputFile
3334

3435

3536
VideoDesc getVideoDesc( size_t videoStreamId );
36-
bool getAudioStream( );
37+
AudioDesc getAudioDesc( size_t audioStreamId );
3738

3839

3940
bool unwrap( DataStream& data, const size_t streamIndex );

src/AvTranscoder/avTranscoder.i

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
%}
2626

2727
namespace std {
28+
%template(IntPair) pair< size_t, size_t >;
2829
%template(VideoVector) vector< avtranscoder::VideoProperties >;
2930
%template(AudioVector) vector< avtranscoder::AudioProperties >;
3031
%template(MetadataPair) pair< string, string >;

0 commit comments

Comments
 (0)