Skip to content

Commit af7e0d9

Browse files
clean read, using same InputFile for streams, need to bufferize if read stream
1 parent 5feacb1 commit af7e0d9

File tree

9 files changed

+104
-56
lines changed

9 files changed

+104
-56
lines changed

app/avplay/main.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -613,9 +613,13 @@ int main( int argc, char** argv )
613613
img.type = GL_UNSIGNED_BYTE;
614614
//GLenum type = GL_UNSIGNED_SHORT;
615615

616-
avtranscoder::InputStreamVideo inputStreamVideo( inputFile.getStream( 0 ) );
616+
size_t videoStream = inputFile.getProperties().videoStreams.at(0).streamId;
617+
618+
inputFile.readStream( videoStream );
619+
620+
avtranscoder::InputStreamVideo inputStreamVideo( inputFile.getStream( videoStream ) );
617621
pInputStreamVideo = &inputStreamVideo;
618-
avtranscoder::Image sourceImage( inputFile.getStream( 0 ).getVideoDesc().getImageDesc() );
622+
avtranscoder::Image sourceImage( inputFile.getStream( videoStream ).getVideoDesc().getImageDesc() );
619623

620624
avtranscoder::Pixel pixel;
621625
pixel.setBitsPerPixel( img.component * 8 );

src/AvTranscoder/InputFile.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,4 +137,39 @@ InputStream& InputFile::getStream( size_t index )
137137
return m_inputStreams.at( index );
138138
}
139139

140+
bool InputFile::readNextPacket( const size_t streamIndex )
141+
{
142+
AVPacket packet;
143+
av_init_packet( &packet );
144+
while( 1 )
145+
{
146+
int ret = av_read_frame( m_formatContext, &packet );
147+
if( ret < 0 ) // error or end of file
148+
{
149+
av_free_packet( &packet );
150+
return false;
151+
}
152+
153+
// send packet to stream buffer
154+
m_inputStreams.at( packet.stream_index ).addPacket( packet );
155+
156+
// We only read one stream and skip others
157+
if( packet.stream_index == (int)streamIndex )
158+
{
159+
av_free_packet( &packet );
160+
return true;
161+
}
162+
163+
// do not delete these 2 lines
164+
// need to skip packet, delete this one and re-init for reading the next one
165+
av_free_packet( &packet );
166+
av_init_packet( &packet );
167+
}
168+
}
169+
170+
void InputFile::readStream( const size_t streamIndex, bool readStream )
171+
{
172+
m_inputStreams.at( streamIndex ).setBufferred( readStream );
173+
}
174+
140175
}

src/AvTranscoder/InputFile.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ class AvExport InputFile
3838

3939
AVFormatContext* getFormatContext() const { return m_formatContext; }
4040

41+
bool readNextPacket( const size_t streamIndex );
42+
43+
void readStream( const size_t streamIndex, const bool readStream = true );
44+
4145
protected:
4246
AVFormatContext* m_formatContext;
4347
Properties m_properties;

src/AvTranscoder/InputStream.cpp

Lines changed: 33 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@ extern "C" {
1717
namespace avtranscoder
1818
{
1919

20-
InputStream::InputStream( const InputFile* inputFile, const size_t streamIndex )
20+
InputStream::InputStream( InputFile* inputFile, const size_t streamIndex )
2121
: m_inputFile( inputFile )
2222
, m_packetDuration( 0 )
2323
, m_streamIndex( streamIndex )
24+
, m_bufferized( false )
2425
{
2526
};
2627

@@ -30,51 +31,44 @@ InputStream::~InputStream( )
3031

3132
bool InputStream::readNextPacket( DataStream& data )
3233
{
33-
AVPacket packet;
34-
av_init_packet( &packet );
34+
if( m_streamCache.empty() )
35+
m_inputFile->readNextPacket( m_streamIndex );
3536

36-
if( readNextPacket( packet ) )
37-
{
38-
m_packetDuration = packet.duration;
37+
if( m_streamCache.empty() )
38+
return false;
3939

40-
// is it possible to remove this copy ?
41-
// using : av_packet_unref ?
42-
data.getBuffer().resize( packet.size );
43-
if( packet.size != 0 )
44-
memcpy( data.getPtr(), packet.data, packet.size );
45-
}
46-
else
47-
{
48-
data.getBuffer().resize( 0 );
49-
}
40+
m_streamCache.front().getBuffer().swap( data.getBuffer() );
5041

51-
av_free_packet( &packet );
42+
m_streamCache.erase( m_streamCache.begin() );
5243

53-
return data.getBuffer().size() != 0;
44+
return true;
5445
}
5546

56-
bool InputStream::readNextPacket( AVPacket& packet ) const
47+
void InputStream::addPacket( AVPacket& packet )
5748
{
58-
assert( m_inputFile->getFormatContext() != NULL );
59-
while( 1 )
60-
{
61-
int ret = av_read_frame( m_inputFile->getFormatContext(), &packet );
62-
if( ret < 0 ) // error or end of file
63-
{
64-
return false;
65-
}
66-
67-
// We only read one stream and skip others
68-
if( packet.stream_index == (int)m_streamIndex )
69-
{
70-
return true;
71-
}
72-
73-
// do not delete these 2 lines
74-
// need to skip packet, delete this one and re-init for reading the next one
75-
av_free_packet( &packet );
76-
av_init_packet( &packet );
77-
}
49+
//std::cout << "add packet for stream " << m_streamIndex << std::endl;
50+
DataStream data;
51+
m_streamCache.push_back( data );
52+
m_packetDuration = packet.duration;
53+
54+
if( ! m_bufferized )
55+
return;
56+
57+
// is it possible to remove this copy ?
58+
// using : av_packet_unref ?
59+
m_streamCache.back().getBuffer().resize( packet.size );
60+
if( packet.size != 0 )
61+
memcpy( m_streamCache.back().getPtr(), packet.data, packet.size );
62+
63+
// std::vector<unsigned char> tmpData( 0,0 );
64+
// &tmpData[0] = packet.data;
65+
// tmpData.size( packet.size );
66+
67+
// remove reference on packet because it's passed to DataStream
68+
// packet.data = NULL;
69+
// packet.size = 0;
70+
71+
// std::cout << this << " buffer size " << m_streamCache.size() << std::endl;
7872
}
7973

8074
VideoDesc InputStream::getVideoDesc() const

src/AvTranscoder/InputStream.hpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ extern "C" {
1414

1515
#include <string>
1616
#include <iostream>
17+
#include <queue>
1718

1819
#include "InputFile.hpp"
1920

@@ -23,12 +24,13 @@ namespace avtranscoder
2324
class AvExport InputStream
2425
{
2526
public:
26-
InputStream( const InputFile* inputFile, const size_t streamIndex );
27+
InputStream( InputFile* inputFile, const size_t streamIndex );
2728
~InputStream( );
2829

2930
InputStream( const InputStream& inputStream )
3031
: m_inputFile( inputStream.m_inputFile )
3132
, m_streamIndex( inputStream.m_streamIndex )
33+
, m_bufferized( inputStream.m_bufferized )
3234
{
3335
}
3436

@@ -43,15 +45,17 @@ class AvExport InputStream
4345
double getDuration() const;
4446
double getPacketDuration() const;
4547

46-
// protected:
47-
bool readNextPacket( AVPacket& packet ) const;
48+
void addPacket( AVPacket& packet );
49+
50+
void setBufferred( const bool bufferized ){ m_bufferized = bufferized; }
4851

4952
private:
50-
const InputFile* m_inputFile;
53+
InputFile* m_inputFile;
5154
std::vector<DataStream> m_streamCache;
5255

5356
int m_packetDuration;
5457
size_t m_streamIndex;
58+
bool m_bufferized;
5559
};
5660

5761
}

src/AvTranscoder/InputStreamAudio.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ InputStreamAudio::InputStreamAudio( const InputStream& inputStream )
5858

5959
char err[250];
6060

61-
av_make_error_string( err, 250, ret );
61+
av_strerror( ret, err, 250 );
6262
std::cout << err << std::endl;
6363
throw std::runtime_error( msg );
6464
}
@@ -99,8 +99,8 @@ InputStreamAudio::~InputStreamAudio()
9999

100100
bool InputStreamAudio::readNextFrame( AudioFrame& audioFrameBuffer )
101101
{
102+
/*
102103
int got_frame = 0;
103-
104104
while( ! got_frame )
105105
{
106106
AVPacket packet;
@@ -120,7 +120,7 @@ bool InputStreamAudio::readNextFrame( AudioFrame& audioFrameBuffer )
120120
}
121121
122122
av_free_packet( &packet );
123-
}
123+
}*/
124124

125125
//size_t unpadded_linesize = m_frame->nb_samples * av_get_bytes_per_sample( m_frame->format );
126126

src/AvTranscoder/InputStreamVideo.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ extern "C" {
1717
namespace avtranscoder
1818
{
1919

20-
InputStreamVideo::InputStreamVideo( const InputStream& inputStream )
20+
InputStreamVideo::InputStreamVideo( InputStream& inputStream )
2121
: m_inputStream ( inputStream )
2222
, m_codec ( NULL )
2323
, m_codecContext ( NULL )
@@ -90,18 +90,21 @@ InputStreamVideo::~InputStreamVideo()
9090

9191
bool InputStreamVideo::readNextFrame( Image& frameBuffer )
9292
{
93+
9394
int got_frame = 0;
9495

9596
while( ! got_frame )
9697
{
98+
DataStream data;
99+
if( ! m_inputStream.readNextPacket( data ) )
100+
return false;
101+
97102
AVPacket packet;
98103
av_init_packet( &packet );
99104

100-
if( ! m_inputStream.readNextPacket( packet ) ) // error or end of file
101-
{
102-
av_free_packet( &packet );
103-
return false;
104-
}
105+
packet.stream_index = m_selectedStream;
106+
packet.data = data.getPtr();
107+
packet.size = data.getSize();
105108

106109
avcodec_decode_video2( m_codecContext, m_frame, &got_frame, &packet );
107110

src/AvTranscoder/InputStreamVideo.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ namespace avtranscoder
1717
class AvExport InputStreamVideo
1818
{
1919
public:
20-
InputStreamVideo( const InputStream& inputStream );
20+
InputStreamVideo( InputStream& inputStream );
2121
~InputStreamVideo();
2222

2323
bool readNextFrame( Image& frameBuffer );
2424

2525
private:
26-
const InputStream m_inputStream;
26+
InputStream& m_inputStream;
2727
AVCodec* m_codec;
2828
AVCodecContext* m_codecContext;
2929
AVFrame* m_frame;

src/SConscript

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ Import( "installPrefix" )
88

99
AvTranscoderVersion = "0.0.1"
1010

11+
env.Append(
12+
SHLIBVERSION = AvTranscoderVersion
13+
)
14+
1115
sAvTranscoder = env.StaticLibrary(
1216
'sAvTranscoder',
1317
Glob( 'AvTranscoder/*.cpp' ) + Glob( 'AvTranscoder/DatasStructures/*.cpp' ) ,

0 commit comments

Comments
 (0)