Skip to content

Commit ebd558d

Browse files
author
Clement Champetier
committed
Video/Audio generators: fix data generated after a transcoded stream
* Solution: keep the original description when the frame was created, and use it to reallocate it when needed. * No need to check and reallocate data in the generators.
1 parent fb44ea5 commit ebd558d

File tree

7 files changed

+38
-22
lines changed

7 files changed

+38
-22
lines changed

src/AvTranscoder/data/decoded/AudioFrame.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ void AudioFrameDesc::setParameters(const ProfileLoader::Profile& profile)
4141

4242
AudioFrame::AudioFrame(const AudioFrameDesc& desc)
4343
: Frame()
44+
, _desc(desc)
4445
{
4546
// Set Frame properties
4647
av_frame_set_sample_rate(_frame, desc._sampleRate);
@@ -89,11 +90,17 @@ void AudioFrame::allocateData()
8990
if(_dataAllocated)
9091
return;
9192

93+
// Set Frame properties
94+
av_frame_set_sample_rate(_frame, _desc._sampleRate);
95+
av_frame_set_channels(_frame, _desc._nbChannels);
96+
av_frame_set_channel_layout(_frame, av_get_default_channel_layout(_desc._nbChannels));
97+
_frame->format = _desc._sampleFormat;
98+
_frame->nb_samples = _desc._sampleRate / 25.; // cannot be known before calling avcodec_decode_audio4
99+
92100
// Allocate data
93101
const int align = 0;
94-
const AVSampleFormat format = static_cast<AVSampleFormat>(_frame->format);
95102
const int ret =
96-
av_samples_alloc(_frame->data, _frame->linesize, _frame->channels, _frame->nb_samples, format, align);
103+
av_samples_alloc(_frame->data, _frame->linesize, _frame->channels, _frame->nb_samples, _desc._sampleFormat, align);
97104
if(ret < 0)
98105
{
99106
std::stringstream os;
@@ -102,7 +109,7 @@ void AudioFrame::allocateData()
102109
os << "nb channels = " << _frame->channels << ", ";
103110
os << "channel layout = " << av_get_channel_name(_frame->channels) << ", ";
104111
os << "nb samples = " << _frame->nb_samples << ", ";
105-
os << "sample format = " << getSampleFormatName(format);
112+
os << "sample format = " << getSampleFormatName(_desc._sampleFormat);
106113
throw std::runtime_error(os.str());
107114
}
108115
_dataAllocated = true;

src/AvTranscoder/data/decoded/AudioFrame.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,14 @@ class AvExport AudioFrame : public Frame
7070
* @see getSize
7171
*/
7272
void assign(const unsigned char* ptrValue);
73+
74+
private:
75+
/**
76+
* @brief Description of the frame to allocate.
77+
* @warning This description could be different from the current frame (a decoder could have reseted it).
78+
* We need to keep this description to allocate again the frame even if it was reseted.
79+
*/
80+
const AudioFrameDesc _desc;
7381
};
7482
}
7583

src/AvTranscoder/data/decoded/VideoFrame.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ void VideoFrameDesc::setParameters(const ProfileLoader::Profile& profile)
4747

4848
VideoFrame::VideoFrame(const VideoFrameDesc& desc)
4949
: Frame()
50+
, _desc(desc)
5051
{
5152
_frame->width = desc._width;
5253
_frame->height = desc._height;
@@ -78,15 +79,20 @@ void VideoFrame::allocateData()
7879
if(_dataAllocated)
7980
return;
8081

81-
const AVPixelFormat format = static_cast<AVPixelFormat>(_frame->format);
82-
const int ret = avpicture_alloc(reinterpret_cast<AVPicture*>(_frame), format, _frame->width, _frame->height);
82+
// Set Frame properties
83+
_frame->width = _desc._width;
84+
_frame->height = _desc._height;
85+
_frame->format = _desc._pixelFormat;
86+
87+
// Allocate data
88+
const int ret = avpicture_alloc(reinterpret_cast<AVPicture*>(_frame), _desc._pixelFormat, _desc._width, _desc._height);
8389
if(ret < 0)
8490
{
8591
std::stringstream os;
8692
os << "Unable to allocate an image frame of ";
8793
os << "width = " << _frame->width << ", ";
8894
os << "height = " << _frame->height << ", ";
89-
os << "pixel format = " << getPixelFormatName(format);
95+
os << "pixel format = " << getPixelFormatName(_desc._pixelFormat);
9096
throw std::runtime_error(os.str());
9197
}
9298
_dataAllocated = true;

src/AvTranscoder/data/decoded/VideoFrame.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@ class AvExport VideoFrame : public Frame
7272
* @see getSize
7373
*/
7474
void assign(const unsigned char* ptrValue);
75+
76+
private:
77+
/**
78+
* @brief Description of the frame to allocate.
79+
* @warning This description could be different from the current frame (a decoder could have reseted it).
80+
* We need to keep this description to allocate again the frame even if it was reseted.
81+
*/
82+
const VideoFrameDesc _desc;
7583
};
7684
}
7785

src/AvTranscoder/decoder/AudioGenerator.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,6 @@ AudioGenerator::~AudioGenerator()
2121

2222
bool AudioGenerator::decodeNextFrame(Frame& frameBuffer)
2323
{
24-
// check the given frame
25-
if(! frameBuffer.isAudioFrame())
26-
{
27-
LOG_WARN("The given frame to put data is not a valid audio frame: try to reallocate it.")
28-
static_cast<AudioFrame&>(frameBuffer).freeAVSample();
29-
static_cast<AudioFrame&>(frameBuffer).allocateAVSample(_frameDesc);
30-
}
31-
3224
// Generate silent
3325
if(!_inputFrame)
3426
{

src/AvTranscoder/decoder/VideoGenerator.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,6 @@ VideoGenerator::~VideoGenerator()
2121

2222
bool VideoGenerator::decodeNextFrame(Frame& frameBuffer)
2323
{
24-
// check the given frame
25-
if(! frameBuffer.isVideoFrame())
26-
{
27-
LOG_WARN("The given frame to put data is not a valid video frame: try to reallocate it.")
28-
static_cast<VideoFrame&>(frameBuffer).freeAVPicture();
29-
static_cast<VideoFrame&>(frameBuffer).allocateAVPicture(_frameDesc);
30-
}
31-
3224
// Generate black image
3325
if(!_inputFrame)
3426
{

src/AvTranscoder/transcoder/StreamTranscoder.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,9 @@ bool StreamTranscoder::processTranscode()
588588
if(_needToSwitchToGenerator)
589589
{
590590
switchToGeneratorDecoder();
591+
// force reallocation of the buffers since de decoders have cleared them
592+
for(std::vector<Frame*>::iterator it = _decodedData.begin(); it != _decodedData.end(); ++it)
593+
(*it)->allocateData();
591594
return processTranscode();
592595
}
593596
return false;

0 commit comments

Comments
 (0)