Skip to content

Commit 60dc19c

Browse files
author
Clement Champetier
committed
Merge branch 'develop' of https://github.com/avTranscoder/avTranscoder into refactor_VideoPropertiesAnalyseFirstGOP
Conflicts: src/AvTranscoder/properties/VideoProperties.cpp
2 parents 462b50d + 6b535b3 commit 60dc19c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+939
-662
lines changed

app/avProcessor/avProcessor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ void parseConfigFile(const std::string& configFilename, avtranscoder::Transcoder
2828

2929
std::stringstream ss(streamId);
3030
size_t streamIndex = 0;
31-
char separator;
31+
char separator = 'x';
3232
std::vector<size_t> channelIndexArray;
3333
ss >> streamIndex;
3434
ss >> separator;

src/AvTranscoder/codec/AudioCodec.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "AudioCodec.hpp"
22

3+
#include <AvTranscoder/util.hpp>
4+
35
#include <cmath>
46
#include <cassert>
57

@@ -24,7 +26,7 @@ AudioCodec::AudioCodec(const ECodecType type, AVCodecContext& avCodecContext)
2426
AudioFrameDesc AudioCodec::getAudioFrameDesc() const
2527
{
2628
assert(_avCodecContext != NULL);
27-
return AudioFrameDesc(_avCodecContext->sample_rate, _avCodecContext->channels, _avCodecContext->sample_fmt);
29+
return AudioFrameDesc(_avCodecContext->sample_rate, _avCodecContext->channels, getSampleFormatName(_avCodecContext->sample_fmt));
2830
}
2931

3032
void AudioCodec::setAudioParameters(const AudioFrameDesc& audioFrameDesc)

src/AvTranscoder/codec/ICodec.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ ICodec::~ICodec()
4949
if(!_isCodecContextAllocated)
5050
return;
5151

52-
av_free(_avCodecContext);
52+
avcodec_free_context(&_avCodecContext);
5353
_avCodecContext = NULL;
5454
}
5555

@@ -148,7 +148,8 @@ void ICodec::allocateContext()
148148
_avCodecContext = avcodec_alloc_context3(_avCodec);
149149
if(!_avCodecContext)
150150
{
151-
throw std::runtime_error("Unable to allocate the codecContext and set its fields to default values");
151+
LOG_ERROR("Unable to allocate the codecContext and set its fields to default values.")
152+
throw std::bad_alloc();
152153
}
153154
_avCodecContext->codec = _avCodec;
154155
}

src/AvTranscoder/codec/VideoCodec.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "VideoCodec.hpp"
22

3+
#include <AvTranscoder/util.hpp>
4+
35
#include <cmath>
46
#include <cassert>
57

@@ -24,7 +26,7 @@ VideoCodec::VideoCodec(const ECodecType type, AVCodecContext& avCodecContext)
2426
VideoFrameDesc VideoCodec::getVideoFrameDesc() const
2527
{
2628
assert(_avCodecContext != NULL);
27-
VideoFrameDesc videoFrameDesc(_avCodecContext->width, _avCodecContext->height, _avCodecContext->pix_fmt);
29+
VideoFrameDesc videoFrameDesc(_avCodecContext->width, _avCodecContext->height, getPixelFormatName(_avCodecContext->pix_fmt));
2830
double fps = 1.0 * _avCodecContext->time_base.den / (_avCodecContext->time_base.num * _avCodecContext->ticks_per_frame);
2931
if(!std::isinf(fps))
3032
videoFrameDesc._fps = fps;

src/AvTranscoder/data/coded/CodedData.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,12 @@ CodedData::CodedData()
1414
CodedData::CodedData(const size_t dataSize)
1515
: _avStream(NULL)
1616
{
17-
av_new_packet(&_packet, dataSize);
17+
const int err = av_new_packet(&_packet, dataSize);
18+
if(err != 0)
19+
{
20+
LOG_ERROR("Unable to allocate the payload of a packet and initialize its fields with default values: " << getDescriptionFromErrorCode(err))
21+
throw std::bad_alloc();
22+
}
1823
}
1924

2025
CodedData::CodedData(const AVPacket& avPacket)

src/AvTranscoder/data/data.i

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
%{
44
#include <AvTranscoder/data/coded/CodedData.hpp>
5-
#include <AvTranscoder/data/decoded/Frame.hpp>
5+
#include <AvTranscoder/data/decoded/IFrame.hpp>
66
#include <AvTranscoder/data/decoded/VideoFrame.hpp>
77
#include <AvTranscoder/data/decoded/AudioFrame.hpp>
88
%}
99

1010
%include <AvTranscoder/data/coded/CodedData.hpp>
11-
%include <AvTranscoder/data/decoded/Frame.hpp>
11+
%include <AvTranscoder/data/decoded/IFrame.hpp>
1212
%include <AvTranscoder/data/decoded/VideoFrame.hpp>
1313
%include <AvTranscoder/data/decoded/AudioFrame.hpp>

src/AvTranscoder/data/decoded/AudioFrame.cpp

Lines changed: 69 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,19 @@ extern "C" {
1212
namespace avtranscoder
1313
{
1414

15-
AudioFrameDesc::AudioFrameDesc(const size_t sampleRate, const size_t nbChannels, const AVSampleFormat sampleFormat)
15+
AudioFrameDesc::AudioFrameDesc(const size_t sampleRate, const size_t nbChannels, const std::string& sampleFormatName)
1616
: _sampleRate(sampleRate)
1717
, _nbChannels(nbChannels)
18-
, _sampleFormat(sampleFormat)
18+
, _sampleFormat(getAVSampleFormat(sampleFormatName))
1919
{
2020
}
2121

22-
AudioFrameDesc::AudioFrameDesc(const size_t sampleRate, const size_t nbChannels, const std::string& sampleFormatName)
23-
: _sampleRate(sampleRate)
24-
, _nbChannels(nbChannels)
25-
, _sampleFormat(getAVSampleFormat(sampleFormatName))
22+
AudioFrameDesc::AudioFrameDesc(const ProfileLoader::Profile& profile)
23+
: _sampleRate(0)
24+
, _nbChannels(0)
25+
, _sampleFormat(AV_SAMPLE_FMT_NONE)
2626
{
27+
setParameters(profile);
2728
}
2829

2930
void AudioFrameDesc::setParameters(const ProfileLoader::Profile& profile)
@@ -39,15 +40,19 @@ void AudioFrameDesc::setParameters(const ProfileLoader::Profile& profile)
3940
_sampleFormat = getAVSampleFormat(profile.find(constants::avProfileSampleFormat)->second.c_str());
4041
}
4142

42-
AudioFrame::AudioFrame(const AudioFrameDesc& ref)
43-
: Frame()
43+
AudioFrame::AudioFrame(const AudioFrameDesc& desc, const bool forceDataAllocation)
44+
: IFrame()
45+
, _desc(desc)
4446
{
45-
allocateAVSample(ref);
46-
}
47+
// Set Frame properties
48+
av_frame_set_sample_rate(_frame, desc._sampleRate);
49+
av_frame_set_channels(_frame, desc._nbChannels);
50+
av_frame_set_channel_layout(_frame, av_get_default_channel_layout(desc._nbChannels));
51+
_frame->format = desc._sampleFormat;
52+
_frame->nb_samples = getDefaultNbSamples();
4753

48-
AudioFrame::AudioFrame(const Frame& otherFrame)
49-
: Frame(otherFrame)
50-
{
54+
if(forceDataAllocation)
55+
allocateData();
5156
}
5257

5358
std::string AudioFrame::getChannelLayoutDesc() const
@@ -57,75 +62,95 @@ std::string AudioFrame::getChannelLayoutDesc() const
5762
return std::string(buf);
5863
}
5964

60-
size_t AudioFrame::getSize() const
65+
AudioFrame::~AudioFrame()
66+
{
67+
if(_frame->buf[0])
68+
av_frame_unref(_frame);
69+
if(_dataAllocated)
70+
freeData();
71+
}
72+
73+
size_t AudioFrame::getBytesPerSample() const
74+
{
75+
return av_get_bytes_per_sample(getSampleFormat());
76+
}
77+
78+
size_t AudioFrame::getDataSize() const
6179
{
6280
if(getSampleFormat() == AV_SAMPLE_FMT_NONE)
6381
{
6482
LOG_WARN("Incorrect sample format when get size of audio frame: return a size of 0.")
6583
return 0;
6684
}
6785

68-
const size_t size = getNbSamplesPerChannel() * getNbChannels() * av_get_bytes_per_sample(getSampleFormat());
86+
const size_t size = getNbSamplesPerChannel() * getNbChannels() * getBytesPerSample();
6987
if(size == 0)
7088
{
7189
std::stringstream msg;
7290
msg << "Unable to determine audio buffer size:" << std::endl;
7391
msg << "nb sample per channel = " << getNbSamplesPerChannel() << std::endl;
7492
msg << "channels = " << getNbChannels() << std::endl;
75-
msg << "bytes per sample = " << av_get_bytes_per_sample(getSampleFormat()) << std::endl;
93+
msg << "bytes per sample = " << getBytesPerSample() << std::endl;
7694
throw std::runtime_error(msg.str());
7795
}
7896
return size;
7997
}
8098

81-
void AudioFrame::allocateAVSample(const AudioFrameDesc& desc)
99+
void AudioFrame::allocateData()
82100
{
101+
if(_dataAllocated)
102+
LOG_WARN("The AudioFrame seems to already have allocated data. This could lead to memory leaks.")
103+
83104
// Set Frame properties
84-
av_frame_set_sample_rate(_frame, desc._sampleRate);
85-
av_frame_set_channels(_frame, desc._nbChannels);
86-
av_frame_set_channel_layout(_frame, av_get_default_channel_layout(desc._nbChannels));
87-
_frame->format = desc._sampleFormat;
88-
_frame->nb_samples = desc._sampleRate / 25.; // cannot be known before calling avcodec_decode_audio4
105+
av_frame_set_sample_rate(_frame, _desc._sampleRate);
106+
av_frame_set_channels(_frame, _desc._nbChannels);
107+
av_frame_set_channel_layout(_frame, av_get_default_channel_layout(_desc._nbChannels));
108+
_frame->format = _desc._sampleFormat;
109+
if(_frame->nb_samples == 0)
110+
_frame->nb_samples = getDefaultNbSamples();
89111

90112
// Allocate data
91113
const int align = 0;
92114
const int ret =
93-
av_samples_alloc(_frame->data, _frame->linesize, _frame->channels, _frame->nb_samples, desc._sampleFormat, align);
115+
av_samples_alloc(_frame->data, _frame->linesize, _frame->channels, _frame->nb_samples, _desc._sampleFormat, align);
94116
if(ret < 0)
95117
{
96-
std::stringstream os;
97-
os << "Unable to allocate an audio frame of ";
98-
os << "sample rate = " << _frame->sample_rate << ", ";
99-
os << "nb channels = " << _frame->channels << ", ";
100-
os << "channel layout = " << av_get_channel_name(_frame->channels) << ", ";
101-
os << "nb samples = " << _frame->nb_samples << ", ";
102-
os << "sample format = " << getSampleFormatName(desc._sampleFormat);
103-
throw std::runtime_error(os.str());
118+
const std::string formatName = getSampleFormatName(_desc._sampleFormat);
119+
std::stringstream msg;
120+
msg << "Unable to allocate an audio frame of ";
121+
msg << "sample rate = " << _frame->sample_rate << ", ";
122+
msg << "nb channels = " << _frame->channels << ", ";
123+
msg << "channel layout = " << av_get_channel_name(_frame->channels) << ", ";
124+
msg << "nb samples = " << _frame->nb_samples << ", ";
125+
msg << "sample format = " << (formatName.empty() ? "none" : formatName);
126+
LOG_ERROR(msg.str())
127+
throw std::bad_alloc();
104128
}
129+
_dataAllocated = true;
105130
}
106131

107-
void AudioFrame::assign(const unsigned char value)
132+
void AudioFrame::freeData()
108133
{
109-
// Create the audio buffer
110-
// The buffer will be freed in destructor of based class
111-
const int audioSize = getSize();
112-
unsigned char* audioBuffer = new unsigned char[audioSize];
113-
memset(audioBuffer, value, audioSize);
114-
115-
// Fill the picture
116-
assign(audioBuffer);
134+
av_freep(&_frame->data[0]);
135+
_dataAllocated = false;
117136
}
118137

119-
void AudioFrame::assign(const unsigned char* ptrValue)
138+
void AudioFrame::assignBuffer(const unsigned char* ptrValue)
120139
{
121140
const int align = 0;
122141
const int ret = av_samples_fill_arrays(_frame->data, _frame->linesize, ptrValue, getNbChannels(),
123142
getNbSamplesPerChannel(), getSampleFormat(), align);
124143
if(ret < 0)
125144
{
126-
std::stringstream os;
127-
os << "Unable to assign an audio buffer: " << getDescriptionFromErrorCode(ret);
128-
throw std::runtime_error(os.str());
145+
std::stringstream msg;
146+
msg << "Unable to assign an audio buffer: " << getDescriptionFromErrorCode(ret);
147+
throw std::runtime_error(msg.str());
129148
}
130149
}
150+
151+
size_t AudioFrame::getDefaultNbSamples() const
152+
{
153+
return _desc._sampleRate / 25.;
154+
}
155+
131156
}

src/AvTranscoder/data/decoded/AudioFrame.hpp

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef _AV_TRANSCODER_FRAME_AUDIO_FRAME_HPP_
22
#define _AV_TRANSCODER_FRAME_AUDIO_FRAME_HPP_
33

4-
#include "Frame.hpp"
4+
#include "IFrame.hpp"
55
#include <AvTranscoder/profile/ProfileLoader.hpp>
66

77
namespace avtranscoder
@@ -14,9 +14,8 @@ namespace avtranscoder
1414
struct AvExport AudioFrameDesc
1515
{
1616
public:
17-
AudioFrameDesc(const size_t sampleRate = 0, const size_t channels = 0,
18-
const AVSampleFormat sampleFormat = AV_SAMPLE_FMT_NONE);
1917
AudioFrameDesc(const size_t sampleRate, const size_t channels, const std::string& sampleFormatName);
18+
AudioFrameDesc(const ProfileLoader::Profile& profile);
2019

2120
/**
2221
* @brief Set the attributes from the given profile.
@@ -33,50 +32,59 @@ struct AvExport AudioFrameDesc
3332
/**
3433
* @brief This class describes decoded audio data.
3534
*/
36-
class AvExport AudioFrame : public Frame
35+
class AvExport AudioFrame : public IFrame
3736
{
37+
private:
38+
AudioFrame(const AudioFrame& otherFrame);
39+
AudioFrame& operator=(const AudioFrame& otherFrame);
40+
3841
public:
42+
AudioFrame(const AudioFrameDesc& desc, const bool forceDataAllocation = true);
43+
~AudioFrame();
44+
3945
/**
40-
* @note Allocated data will be initialized to silence.
46+
* @brief Allocated data will be initialized to silence.
47+
* @warning The allocated data should be freed by the caller.
48+
* @see freeData
4149
*/
42-
AudioFrame(const AudioFrameDesc& ref);
43-
AudioFrame(const Frame& otherFrame);
50+
void allocateData();
51+
void freeData();
52+
size_t getDataSize() const;
4453

4554
size_t getSampleRate() const { return av_frame_get_sample_rate(_frame); }
4655
size_t getNbChannels() const { return av_frame_get_channels(_frame); }
4756
size_t getChannelLayout() const { return av_frame_get_channel_layout(_frame); }
4857
std::string getChannelLayoutDesc() const; ///< Get a description of a channel layout (example: '5.1').
4958
AVSampleFormat getSampleFormat() const { return static_cast<AVSampleFormat>(_frame->format); }
59+
size_t getBytesPerSample() const; ///< 0 if unknown sample format
5060
size_t getNbSamplesPerChannel() const { return _frame->nb_samples; }
51-
AudioFrameDesc desc() const { return AudioFrameDesc(getSampleRate(), getNbChannels(), getSampleFormat()); }
52-
53-
size_t getSize() const; ///< in bytes
54-
55-
void setNbSamplesPerChannel(const size_t nbSamples) { _frame->nb_samples = nbSamples; }
5661

5762
/**
58-
* @brief Assign the given value to all the data of the audio frame.
63+
* @brief This methods dynamically updates the size that the data buffer would occupy if allocated.
64+
* @warning If the data buffer is already allocated, this could lead to memory leaks or seg fault.
5965
*/
60-
void assign(const unsigned char value);
66+
void setNbSamplesPerChannel(const size_t nbSamples) { _frame->nb_samples = nbSamples; }
6167

62-
/**
63-
* @brief Assign the given ptr of data to the data of the audio frame.
64-
* @warning the given ptr should have the size of the audio frame..
65-
* @see getSize
66-
*/
67-
void assign(const unsigned char* ptrValue);
68+
void assignBuffer(const unsigned char* ptrValue);
6869

6970
private:
7071
/**
71-
* @brief Allocate the audio buffer of the frame.
72+
* @brief The number of samples of a frame cannot be known before calling avcodec_decode_audio4,
73+
* and can be variable in a same stream. Because we need to allocate some frames without knowing this parameter,
74+
* we access here a default number of samples.
75+
* @note This value depends on the sample rate (example: 1920 samples at 48kHz).
76+
* @return the number of samples of our default AudioFrame.
77+
* @see setNbSamplesPerChannel
7278
*/
73-
void allocateAVSample(const AudioFrameDesc& ref);
79+
size_t getDefaultNbSamples() const;
7480

81+
private:
7582
/**
76-
* @note To allocate new audio buffer if needed.
77-
* @see allocateAVSample
83+
* @brief Description of the frame to allocate.
84+
* @warning This description could be different from the current frame (a decoder could have reseted it).
85+
* We need to keep this description to allocate again the frame even if it was reseted.
7886
*/
79-
friend class AudioGenerator;
87+
const AudioFrameDesc _desc;
8088
};
8189
}
8290

0 commit comments

Comments
 (0)
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