Skip to content

Commit 80017d6

Browse files
author
Valentin NOEL
committed
FilterGraph: add new internal FrameBuffer class
Used as frame buffers on the filter graph inputs. For the moment, this first version only handles audio frames.
1 parent 2dc9d24 commit 80017d6

File tree

2 files changed

+142
-1
lines changed

2 files changed

+142
-1
lines changed

src/AvTranscoder/filter/FilterGraph.cpp

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

33
#include <AvTranscoder/util.hpp>
4-
#include <AvTranscoder/data/decoded/AudioFrame.hpp>
54
#include <AvTranscoder/data/decoded/VideoFrame.hpp>
65

76
extern "C" {
@@ -16,6 +15,103 @@ extern "C" {
1615
namespace avtranscoder
1716
{
1817

18+
19+
/******************
20+
21+
FrameBuffer
22+
23+
******************/
24+
25+
FrameBuffer::FrameBuffer(const AudioFrameDesc& audioFrameDesc)
26+
: _audioFrameDesc(audioFrameDesc)
27+
, _frameQueue()
28+
, _totalDataSize(0)
29+
, _positionInFrontFrame(0)
30+
{
31+
}
32+
33+
FrameBuffer::~FrameBuffer()
34+
{
35+
for (int i = 0; i < _frameQueue.size(); ++i)
36+
popFrame();
37+
}
38+
39+
void FrameBuffer::addFrame(IFrame* frame)
40+
{
41+
AudioFrame* newAudioFrame = new AudioFrame(_audioFrameDesc, false);
42+
const size_t expectedNbSamples = frame->getDataSize() / (newAudioFrame->getNbChannels() * newAudioFrame->getBytesPerSample());
43+
newAudioFrame->setNbSamplesPerChannel(expectedNbSamples);
44+
newAudioFrame->allocateData();
45+
newAudioFrame->copyData(*frame);
46+
47+
_totalDataSize += newAudioFrame->getDataSize();
48+
_frameQueue.push(newAudioFrame);
49+
}
50+
51+
void FrameBuffer::popFrame()
52+
{
53+
_frameQueue.pop();
54+
}
55+
56+
IFrame* FrameBuffer::getFrame(const size_t size)
57+
{
58+
IFrame* next = _frameQueue.front();
59+
const size_t nextFrameSize = next->getDataSize();
60+
61+
// If no expected size, or if the expected size equals the front frame of the queue (with no offset)
62+
if(size == 0 || (size == nextFrameSize && _positionInFrontFrame == 0))
63+
{
64+
_totalDataSize -= nextFrameSize;
65+
popFrame();
66+
return next;
67+
}
68+
69+
// Create a new frame
70+
AudioFrame* newAudioFrame = new AudioFrame(_audioFrameDesc, false);
71+
const size_t expectedNbSamples = size / (newAudioFrame->getNbChannels() * newAudioFrame->getBytesPerSample());
72+
newAudioFrame->setNbSamplesPerChannel(expectedNbSamples);
73+
newAudioFrame->allocateData();
74+
75+
// Concatenate frames data
76+
size_t extractedDataSize = 0;
77+
unsigned char* outputData = new unsigned char[size];
78+
while(extractedDataSize != size && _frameQueue.size() != 0)
79+
{
80+
next = _frameQueue.front();
81+
size_t dataToGet = size - extractedDataSize;
82+
size_t remainingDataInNextFrame = next->getDataSize() - _positionInFrontFrame;
83+
84+
if(dataToGet > remainingDataInNextFrame)
85+
dataToGet = remainingDataInNextFrame;
86+
87+
for(size_t i = 0; i < dataToGet; i++)
88+
outputData[extractedDataSize++] = next->getData()[0][_positionInFrontFrame + i];
89+
90+
if(dataToGet < remainingDataInNextFrame)
91+
{
92+
_positionInFrontFrame += dataToGet;
93+
}
94+
else
95+
{
96+
popFrame();
97+
_positionInFrontFrame = 0;
98+
}
99+
}
100+
101+
_totalDataSize -= extractedDataSize;
102+
newAudioFrame->assignBuffer(outputData);
103+
104+
return newAudioFrame;
105+
}
106+
107+
108+
109+
/******************
110+
111+
FilterGraph
112+
113+
******************/
114+
19115
FilterGraph::FilterGraph(const ICodec& codec)
20116
: _graph(avfilter_graph_alloc())
21117
, _filters()

src/AvTranscoder/filter/FilterGraph.hpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,59 @@
55
#include <AvTranscoder/filter/Filter.hpp>
66
#include <AvTranscoder/codec/ICodec.hpp>
77
#include <AvTranscoder/data/decoded/IFrame.hpp>
8+
#include <AvTranscoder/data/decoded/AudioFrame.hpp>
89

910
#include <vector>
11+
#include <queue>
1012

1113
struct AVFilterGraph;
1214

1315
namespace avtranscoder
1416
{
1517

18+
/**
19+
* @brief Filter graph input frame buffer.
20+
* This FIFO buffer contains IFrame pointers and can deliver specific size frames.
21+
*
22+
* @todo Only for audio frame, for the moment. Make it usable with video frames.
23+
**/
24+
class FrameBuffer
25+
{
26+
public:
27+
FrameBuffer(const AudioFrameDesc& audioFrameDesc);
28+
~FrameBuffer();
29+
30+
/**
31+
* @brief Return whether the buffer is empty or not.
32+
*/
33+
bool isEmpty() { return _frameQueue.empty() && _totalDataSize == 0; }
34+
/**
35+
* @brief Return the total amount of data contained in the frames of the buffer.
36+
*/
37+
size_t getDataSize() { return _totalDataSize; }
38+
39+
/**
40+
* @brief Push a frame at the end of the buffer.
41+
*/
42+
void addFrame(IFrame* frame);
43+
44+
/**
45+
* @brief Retrieve a IFrame pointer of the specified size, from the beginning of the buffer.
46+
* If no size is specified, the whole first IFrame pointer is returned.
47+
*/
48+
IFrame* getFrame(const size_t size = 0);
49+
50+
private:
51+
void popFrame();
52+
53+
const AudioFrameDesc _audioFrameDesc;
54+
55+
std::queue<IFrame*> _frameQueue;
56+
size_t _totalDataSize;
57+
size_t _positionInFrontFrame;
58+
59+
};
60+
1661
/**
1762
* @brief Manager of filters.
1863
**/

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