Skip to content

Commit c2170cc

Browse files
committed
Merge pull request #245 from cchampet/fix_outputStreamDuration
Fix output stream duration
2 parents a87d513 + 0837fbd commit c2170cc

File tree

6 files changed

+52
-12
lines changed

6 files changed

+52
-12
lines changed

src/AvTranscoder/file/OutputFile.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,13 @@ IOutputStream& OutputFile::addAudioStream( const AudioCodec& audioDesc )
7575
stream.codec->channels = audioDesc.getAVCodecContext().channels;
7676
stream.codec->sample_fmt = audioDesc.getAVCodecContext().sample_fmt;
7777

78+
// need to set the time_base on the AVCodecContext of the AVStream
79+
av_reduce(
80+
&stream.codec->time_base.num,
81+
&stream.codec->time_base.den,
82+
audioDesc.getAVCodecContext().time_base.num,
83+
audioDesc.getAVCodecContext().time_base.den,
84+
INT_MAX );
7885

7986
OutputStream* outputStream = new OutputStream( *this, _formatContext.getNbStreams() - 1 );
8087
_outputStreams.push_back( outputStream );

src/AvTranscoder/stream/IOutputStream.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,15 @@ class AvExport IOutputStream
2525
virtual ~IOutputStream() {};
2626

2727
virtual size_t getStreamIndex() const = 0;
28+
29+
/**
30+
* @return The current duration of the stream, in seconds.
31+
*/
2832
virtual float getStreamDuration() const = 0;
33+
34+
/**
35+
* @return The current number of frame of the stream.
36+
*/
2937
virtual size_t getNbFrames() const = 0;
3038

3139
virtual EWrappingStatus wrap( const CodedData& data ) = 0;

src/AvTranscoder/stream/InputStream.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ float InputStream::getDuration() const
118118
return _inputFile->getProperties().getStreamPropertiesWithIndex( _streamIndex ).getDuration();
119119
}
120120

121-
void InputStream::addPacket( AVPacket& packet )
121+
void InputStream::addPacket( const AVPacket& packet )
122122
{
123123
// Do not cache data if the stream is declared as unused in process
124124
if( ! _isActivated )

src/AvTranscoder/stream/InputStream.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class AvExport InputStream : public IInputStream
4040
*/
4141
void activate( const bool activate = true ){ _isActivated = activate; };
4242
bool isActivated() const { return _isActivated; };
43-
void addPacket( AVPacket& packet );
43+
void addPacket( const AVPacket& packet );
4444
void clearBuffering();
4545
//@}
4646

src/AvTranscoder/stream/OutputStream.cpp

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,40 +9,55 @@ namespace avtranscoder
99

1010
OutputStream::OutputStream( OutputFile& outputFile, const size_t streamIndex )
1111
: IOutputStream()
12-
, _outputFile( &outputFile )
12+
, _outputFile( outputFile )
13+
, _outputAVStream( outputFile.getFormatContext().getAVStream( streamIndex ) )
1314
, _streamIndex( streamIndex )
15+
, _wrappedPacketsDuration( 0 )
1416
{
1517
}
1618

1719
float OutputStream::getStreamDuration() const
1820
{
19-
const AVStream& outputStream = _outputFile->getFormatContext().getAVStream( _streamIndex );
21+
const AVFrac& outputPTS = _outputAVStream.pts;
22+
const AVRational& outputTimeBase = _outputAVStream.time_base;
2023

2124
// check floating point exception
22-
if( outputStream.time_base.den == 0 || outputStream.pts.den == 0 )
25+
if( outputTimeBase.den == 0 || outputPTS.den == 0 )
2326
{
2427
LOG_WARN( "Cannot compute stream duration of output stream at index " << _streamIndex )
2528
return 0.f;
2629
}
2730

31+
// if stream PTS is not set, use the duration of all packets wrapped
32+
if( ! outputPTS.val )
33+
{
34+
LOG_WARN( "PTS generation when outputting stream " << _streamIndex << " is not set." )
35+
if( _wrappedPacketsDuration )
36+
return av_q2d( _outputAVStream.codec->time_base ) * _wrappedPacketsDuration;
37+
}
38+
2839
#if AVTRANSCODER_FFMPEG_DEPENDENCY && LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(55, 40, 100)
2940
// returns the pts of the last muxed packet, converted from timebase to seconds
30-
return av_q2d( outputStream.time_base ) * av_stream_get_end_pts( &outputStream );
41+
return av_q2d( outputTimeBase ) * av_stream_get_end_pts( &_outputAVStream );
3142
#else
32-
return av_q2d( outputStream.time_base ) * ( outputStream.pts.val + ( outputStream.pts.num / outputStream.pts.den ) );
43+
return av_q2d( outputTimeBase ) * ( outputPTS.val + ( outputPTS.num / outputPTS.den ) );
3344
#endif
3445
}
3546

3647
size_t OutputStream::getNbFrames() const
3748
{
38-
const AVStream& outputStream = _outputFile->getFormatContext().getAVStream( _streamIndex );
39-
return outputStream.nb_frames;
49+
return _outputAVStream.nb_frames;
4050
}
4151

4252
IOutputStream::EWrappingStatus OutputStream::wrap( const CodedData& data )
4353
{
44-
assert( _outputFile != NULL );
45-
return _outputFile->wrap( data, _streamIndex );
54+
// wrap packet
55+
IOutputStream::EWrappingStatus status = _outputFile.wrap( data, _streamIndex );
56+
57+
// append duration of the packet to the stream
58+
_wrappedPacketsDuration += data.getAVPacket().duration;
59+
60+
return status;
4661
}
4762

4863
}

src/AvTranscoder/stream/OutputStream.hpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
#include "IOutputStream.hpp"
55

6+
struct AVStream;
7+
68
namespace avtranscoder
79
{
810

@@ -20,9 +22,17 @@ class AvExport OutputStream : public IOutputStream
2022
IOutputStream::EWrappingStatus wrap( const CodedData& data );
2123

2224
private:
23-
OutputFile* _outputFile; ///< Has link (no ownership)
25+
OutputFile& _outputFile; ///< Has link (no ownership)
26+
const AVStream& _outputAVStream; ///< Has link (no ownership)
2427

2528
size_t _streamIndex; ///< Index of the stream in the output file
29+
30+
/**
31+
* @brief This will help us to getStreamDuration if PTS of outputStream is not properly set during wrapping.
32+
* It corresponds to the addition of the duration of all packets wrapped by this stream.
33+
* @see getStreamDuration
34+
*/
35+
size_t _wrappedPacketsDuration;
2636
};
2737

2838
}

0 commit comments

Comments
 (0)