Skip to content

Commit 72fc695

Browse files
author
Clement Champetier
committed
Audio: encode outputStreamAudio
* OutputStreamAudio: * define setup to open codec. * define encodeFrame. * AudioFrame: add nbSamples attribute to get the number of samples to transcode. * InputStreamAudio: * delete print. * set number of samples decoded in the AudioFrame ; get this value during encode. * Update Rewrapper: add encode and wrap process.
1 parent e8f1c25 commit 72fc695

File tree

5 files changed

+174
-15
lines changed

5 files changed

+174
-15
lines changed

app/audioRewrapper/audioRewrapper.cpp

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <AvTranscoder/InputFile.hpp>
55
#include <AvTranscoder/AvInputStream.hpp>
66
#include <AvTranscoder/InputStreamAudio.hpp>
7+
#include <AvTranscoder/OutputStreamAudio.hpp>
78

89
#include <AvTranscoder/OutputFile.hpp>
910

@@ -54,38 +55,52 @@ void transcodeAudio( const char* inputfilename, const char* outputFilename )
5455
// init audio decoders
5556
InputStreamAudio inputStreamAudio( inputFile.getStream( 0 ) );
5657
inputFile.getStream( 0 ).setBufferred( true );
57-
58+
5859
OutputFile outputFile( outputFilename );
59-
6060
outputFile.setup();
61-
6261
outputFile.addAudioStream( inputFile.getStream( 0 ).getAudioDesc() );
63-
64-
DataStream data;
65-
62+
outputFile.beginWrap();
63+
64+
OutputStreamAudio outputStreamAudio;
65+
AudioDesc& audioDesc = outputStreamAudio.getAudioDesc();
66+
audioDesc.setAudioCodec( "pcm_s16le" );
67+
audioDesc.setAudioParameters(
68+
inputFile.getStream( 0 ).getAudioDesc().getSampleRate(),
69+
inputFile.getStream( 0 ).getAudioDesc().getChannels(),
70+
inputFile.getStream( 0 ).getAudioDesc().getSampleFormat()
71+
);
72+
73+
DataStream codedFrame;
74+
75+
if( ! outputStreamAudio.setup( ) )
76+
{
77+
std::cout << "error during initialising audio output stream" << std::endl;
78+
exit( -1 );
79+
}
80+
6681
// Transcoding
6782
std::cout << "start transcoding" << std::endl;
6883

6984
size_t frame = 0;
7085
AudioFrameDesc audioFrameDesc;
7186

7287
AudioFrame audioFrame( audioFrameDesc );
73-
74-
DataStream codedFrame;
7588

7689
while( inputStreamAudio.readNextFrame( audioFrame ) )
7790
{
7891
std::cout << "\rprocess frame " << (int)frame - 1 << std::endl << std::flush;
7992

8093
// convert
8194

82-
//outputStreamAudio.encodeFrame( audioFrame, codedFrame );
95+
outputStreamAudio.encodeFrame( audioFrame, codedFrame );
8396

84-
// outputFile.wrap( codedFrame, 0 );
97+
outputFile.wrap( codedFrame, 0 );
8598

8699
++frame;
87100
}
88101
std::cout << std::endl;
102+
103+
outputFile.endWrap();
89104
}
90105

91106
int main( int argc, char** argv )

src/AvTranscoder/DatasStructures/AudioFrame.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class AudioFrame
6565
AudioFrame( const AudioFrameDesc& ref )
6666
: m_dataBuffer( ref.getDataSize(), 0 )
6767
, m_audioFrameDesc( ref )
68+
, m_nbSamples( 0 )
6869
{ }
6970

7071
const AudioFrameDesc& desc() const { return m_audioFrameDesc; }
@@ -74,10 +75,14 @@ class AudioFrame
7475
const unsigned char* getPtr() const { return &m_dataBuffer[0]; }
7576
#endif
7677
size_t getSize() const { return m_dataBuffer.size(); }
78+
79+
size_t getNbSamples() const { return m_nbSamples; }
80+
void setNbSamples( size_t nbSamples ) { m_nbSamples = nbSamples; }
7781

7882
private:
7983
DataBuffer m_dataBuffer;
8084
const AudioFrameDesc m_audioFrameDesc;
85+
size_t m_nbSamples;
8186
};
8287

8388
}

src/AvTranscoder/InputStreamAudio.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,6 @@ InputStreamAudio::InputStreamAudio( AvInputStream& inputStream )
5050

5151
int ret = avcodec_open2( m_codecContext, m_codec, NULL );
5252

53-
std::cout << "ret value : " << ret << std::endl;
54-
5553
if( ret < 0 || m_codecContext == NULL || m_codec == NULL )
5654
{
5755
std::string msg = "unable open audio codec: ";
@@ -135,6 +133,8 @@ bool InputStreamAudio::readNextFrame( AudioFrame& audioFrameBuffer )
135133
m_frame->nb_samples,
136134
m_codecContext->sample_fmt, 1);
137135

136+
audioFrameBuffer.setNbSamples( m_frame->nb_samples );
137+
138138
if( decodedSize )
139139
{
140140
if( audioFrameBuffer.getSize() != decodedSize )
Lines changed: 123 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,123 @@
1-
#include "OutputStreamAudio.hpp"
1+
#include "OutputStreamAudio.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+
}
11+
12+
namespace avtranscoder
13+
{
14+
15+
OutputStreamAudio::OutputStreamAudio()
16+
: m_audioDesc( "pcm_s16le" )
17+
{
18+
}
19+
20+
bool OutputStreamAudio::setup()
21+
{
22+
av_register_all(); // Warning: should be called only once
23+
24+
AVCodecContext* codecContext( m_audioDesc.getCodecContext() );
25+
26+
if( codecContext == NULL )
27+
return false;
28+
29+
// try to open encoder with parameters.
30+
if( avcodec_open2( codecContext, m_audioDesc.getCodec(), NULL ) < 0 )
31+
return false;
32+
33+
return true;
34+
}
35+
36+
bool OutputStreamAudio::encodeFrame( const AudioFrame& decodedFrame, DataStream& codedFrame )
37+
{
38+
#if LIBAVCODEC_VERSION_MAJOR > 54
39+
AVFrame* frame = av_frame_alloc();
40+
#else
41+
AVFrame* frame = avcodec_alloc_frame();
42+
#endif
43+
44+
AVCodecContext* codecContext = m_audioDesc.getCodecContext();
45+
46+
// Set default frame parameters
47+
#if LIBAVCODEC_VERSION_MAJOR > 54
48+
av_frame_unref( frame );
49+
#else
50+
avcodec_get_frame_defaults( frame );
51+
#endif
52+
53+
frame->nb_samples = decodedFrame.getNbSamples();
54+
frame->format = codecContext->sample_fmt;
55+
frame->channel_layout = codecContext->channel_layout;
56+
57+
// we calculate the size of the samples buffer in bytes
58+
int buffer_size = av_samples_get_buffer_size(NULL, codecContext->channels, frame->nb_samples, codecContext->sample_fmt, 0);
59+
if( buffer_size < 0 )
60+
{
61+
char err[250];
62+
av_strerror( buffer_size, err, 250);
63+
64+
throw std::runtime_error( "EncodeFrame error: buffer size < 0 - " + std::string(err) );
65+
}
66+
67+
int retvalue = avcodec_fill_audio_frame(frame, codecContext->channels, codecContext->sample_fmt, decodedFrame.getPtr(), buffer_size, 0);
68+
if( retvalue < 0 )
69+
{
70+
char err[250];
71+
av_strerror( retvalue, err, 250);
72+
73+
throw std::runtime_error( "EncodeFrame error: avcodec fill audio frame - " + std::string(err) );
74+
}
75+
76+
AVPacket packet;
77+
av_init_packet( &packet );
78+
79+
packet.size = 0;
80+
packet.data = NULL;
81+
packet.stream_index = 0;
82+
83+
if( ( codecContext->coded_frame ) &&
84+
( codecContext->coded_frame->pts != (int)AV_NOPTS_VALUE ) )
85+
{
86+
packet.pts = codecContext->coded_frame->pts;
87+
}
88+
89+
if( codecContext->coded_frame &&
90+
codecContext->coded_frame->key_frame )
91+
{
92+
packet.flags |= AV_PKT_FLAG_KEY;
93+
}
94+
95+
#if LIBAVCODEC_VERSION_MAJOR > 53
96+
int gotPacket = 0;
97+
int ret = avcodec_encode_audio2( codecContext, &packet, frame, &gotPacket );
98+
if( ret == 0 && gotPacket == 1 )
99+
{
100+
codedFrame.getBuffer().resize( packet.size );
101+
memcpy( codedFrame.getPtr(), packet.data, packet.size );
102+
}
103+
#else
104+
// throw...
105+
#endif
106+
107+
av_free_packet( &packet );
108+
109+
#if LIBAVCODEC_VERSION_MAJOR > 54
110+
av_frame_free( &frame );
111+
return ret == 0 && gotPacket == 1;
112+
#else
113+
#if LIBAVCODEC_VERSION_MAJOR > 53
114+
avcodec_free_frame( &frame );
115+
return ret == 0 && gotPacket == 1;
116+
#else
117+
av_free( frame );
118+
#endif
119+
#endif
120+
return ret == 0;
121+
}
122+
123+
}

src/AvTranscoder/OutputStreamAudio.hpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,34 @@
22
#define _AV_TRANSCODER_OUTPUT_STREAM_AUDIO_HPP_
33

44
#include "OutputStream.hpp"
5+
#include "DatasStructures/AudioFrame.hpp"
6+
#include "DatasStructures/AudioDesc.hpp"
7+
#include "DatasStructures/DataStreamDesc.hpp"
58

69
namespace avtranscoder
710
{
811

912
class OutputStreamAudio : public OutputStream
1013
{
1114
public:
12-
OutputStreamAudio(){};
15+
OutputStreamAudio();
16+
17+
bool setup();
1318

14-
private:
19+
/**
20+
* @param[out] codedFrame
21+
*/
22+
bool encodeFrame( const AudioFrame& decodedFrame, DataStream& codedFrame );
23+
24+
/**
25+
* get delayed encoded frames
26+
*/
27+
//bool encodeFrame( DataStream& codedFrame );
1528

29+
AudioDesc& getAudioDesc() { return m_audioDesc; }
30+
31+
private:
32+
AudioDesc m_audioDesc;
1633
};
1734

1835
}

0 commit comments

Comments
 (0)