Skip to content

Commit 8d478d4

Browse files
committed
Merge pull request #57 from cchampet/fix_inputFile_seek_fps
* Fix InputFile seekAtFrame method * Fix Audio/VideoProperties getTimeBase and getFps methods
2 parents 4e4fe60 + 8452145 commit 8d478d4

File tree

9 files changed

+86
-9
lines changed

9 files changed

+86
-9
lines changed

src/AvTranscoder/file/InputFile.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <AvTranscoder/mediaProperty/SubtitleProperties.hpp>
88
#include <AvTranscoder/mediaProperty/AttachementProperties.hpp>
99
#include <AvTranscoder/mediaProperty/UnknownProperties.hpp>
10+
#include <AvTranscoder/progress/NoDisplayProgress.hpp>
1011

1112
extern "C" {
1213
#include <libavcodec/avcodec.h>
@@ -28,6 +29,10 @@ InputFile::InputFile( const std::string& filename )
2829
{
2930
_formatContext.findStreamInfo();
3031

32+
// Analyse header
33+
NoDisplayProgress p;
34+
analyse( p, eAnalyseLevelHeader );
35+
3136
// Create streams
3237
for( size_t streamIndex = 0; streamIndex < _formatContext.getNbStreams(); ++streamIndex )
3338
{
@@ -45,6 +50,8 @@ InputFile::~InputFile()
4550

4651
void InputFile::analyse( IProgress& progress, const EAnalyseLevel level )
4752
{
53+
_properties.clearStreamProperties();
54+
4855
if( level > eAnalyseLevelHeader )
4956
seekAtFrame( 0 );
5057

@@ -139,8 +146,16 @@ bool InputFile::readNextPacket( CodedData& data, const size_t streamIndex )
139146

140147
void InputFile::seekAtFrame( const size_t frame )
141148
{
142-
uint64_t pos = frame / 25 * AV_TIME_BASE; // WARNING: hardcoded fps
149+
// Get Fps from first video stream or first audio stream if no video
150+
double fps = 1;
151+
if( _properties.getNbVideoStreams() )
152+
fps = _properties.getVideoProperties().at( 0 ).getFps();
153+
else if( _properties.getNbAudioStreams() )
154+
fps = _properties.getAudioProperties().at( 0 ).getFps();
155+
156+
uint64_t pos = frame / fps * AV_TIME_BASE;
143157

158+
// Offset of start time
144159
if( (int)_formatContext.getStartTime() != AV_NOPTS_VALUE )
145160
pos += _formatContext.getStartTime();
146161

src/AvTranscoder/file/InputFile.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class AvExport InputFile
2020
public:
2121
/**
2222
* @brief Open a media file
23+
* @note The constructor also analyses header of input file
2324
* @param filename resource to access
2425
* @exception ios_base::failure launched if unable to open file
2526
**/

src/AvTranscoder/mediaProperty/AudioProperties.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,41 @@ size_t AudioProperties::getNbSamples() const
163163
return _formatContext->streams[_streamId]->nb_frames;
164164
}
165165

166+
size_t AudioProperties::getTicksPerFrame() const
167+
{
168+
if( ! _codecContext )
169+
throw std::runtime_error( "unknown codec context" );
170+
return _codecContext->ticks_per_frame;
171+
}
172+
173+
Rational AudioProperties::getTimeBase() const
174+
{
175+
if( ! _formatContext )
176+
throw std::runtime_error( "unknown format context" );
177+
178+
Rational timeBase = {
179+
_formatContext->streams[_streamId]->time_base.num,
180+
_formatContext->streams[_streamId]->time_base.den,
181+
};
182+
return timeBase;
183+
}
184+
185+
double AudioProperties::getFps() const
186+
{
187+
Rational timeBase = getTimeBase();
188+
double fps = timeBase.den / (double) timeBase.num;
189+
if( isinf( fps ) )
190+
fps = 0.0;
191+
return fps;
192+
}
193+
194+
double AudioProperties::getDuration() const
195+
{
196+
Rational timeBase = getTimeBase();
197+
double duration = ( timeBase.num / (double) timeBase.den ) * _formatContext->streams[_streamId]->duration;
198+
return duration;
199+
}
200+
166201
PropertiesMap AudioProperties::getPropertiesAsMap() const
167202
{
168203
PropertiesMap dataMap;
@@ -180,6 +215,10 @@ PropertiesMap AudioProperties::getPropertiesAsMap() const
180215
detail::add( dataMap, "channelLayout", getChannelLayout() );
181216
detail::add( dataMap, "channelName", getChannelName() );
182217
detail::add( dataMap, "channelDescription", getChannelDescription() );
218+
detail::add( dataMap, "ticksPerFrame", getTicksPerFrame() );
219+
detail::add( dataMap, "timeBase", getTimeBase() );
220+
detail::add( dataMap, "fps", getFps() );
221+
detail::add( dataMap, "duration", getDuration() );
183222

184223
for( size_t metadataIndex = 0; metadataIndex < _metadatas.size(); ++metadataIndex )
185224
{

src/AvTranscoder/mediaProperty/AudioProperties.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ class AvExport AudioProperties
3232
size_t getBitRate() const;
3333
size_t getNbSamples() const;
3434

35+
size_t getTicksPerFrame() const;
36+
Rational getTimeBase() const;
37+
double getFps() const; ///< Corresponds to the number of audio samples for one video frame
38+
double getDuration() const;
39+
3540
PropertiesMap& getMetadatas() { return _metadatas; }
3641

3742
#ifndef SWIG

src/AvTranscoder/mediaProperty/FileProperties.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,14 @@ PropertiesMap FileProperties::getPropertiesAsMap() const
109109
return dataMap;
110110
}
111111

112+
void FileProperties::clearStreamProperties()
113+
{
114+
_videoStreams.clear();
115+
_audioStreams.clear();
116+
_dataStreams.clear();
117+
_subtitleStreams.clear();
118+
_attachementStreams.clear();
119+
_unknownStreams.clear();
120+
}
121+
112122
}

src/AvTranscoder/mediaProperty/FileProperties.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ class AvExport FileProperties
6161

6262
PropertiesMap getPropertiesAsMap() const; ///< Return all file properties as a map (name of property: value)
6363

64+
void clearStreamProperties(); ///< Clear all array of stream properties
65+
6466
private:
6567
const AVFormatContext* _formatContext; ///< Has link (no ownership)
6668

src/AvTranscoder/mediaProperty/VideoProperties.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -335,11 +335,10 @@ std::string VideoProperties::getStartTimecodeString() const
335335
return os.str();
336336
}
337337

338-
339338
Rational VideoProperties::getTimeBase() const
340339
{
341-
if( ! _codecContext )
342-
throw std::runtime_error( "unknown codec context" );
340+
if( ! _formatContext )
341+
throw std::runtime_error( "unknown format context" );
343342

344343
Rational timeBase = {
345344
_formatContext->streams[_streamId]->time_base.num,
@@ -472,17 +471,14 @@ int VideoProperties::getLevel() const
472471
double VideoProperties::getFps() const
473472
{
474473
Rational timeBase = getTimeBase();
475-
double fps = 1.0 * timeBase.den / ( timeBase.num * getTicksPerFrame() );
474+
double fps = timeBase.den / (double) timeBase.num;
476475
if( isinf( fps ) )
477476
fps = 0.0;
478477
return fps;
479478
}
480479

481480
double VideoProperties::getDuration() const
482481
{
483-
if( ! _formatContext )
484-
throw std::runtime_error( "unknown format context" );
485-
486482
Rational timeBase = getTimeBase();
487483
double duration = ( timeBase.num / (double) timeBase.den ) * _formatContext->streams[_streamId]->duration;
488484
return duration;
@@ -592,7 +588,7 @@ PropertiesMap VideoProperties::getPropertiesAsMap() const
592588
detail::add( dataMap, "interlaced ", isInterlaced() );
593589
detail::add( dataMap, "topFieldFirst", isTopFieldFirst() );
594590
detail::add( dataMap, "fieldOrder", getFieldOrder() );
595-
detail::add( dataMap, "timeBase", getTimeBase().num / (double) getTimeBase().den );
591+
detail::add( dataMap, "timeBase", getTimeBase() );
596592
detail::add( dataMap, "duration", getDuration() );
597593
detail::add( dataMap, "fps", getFps() );
598594
detail::add( dataMap, "nbFrame", getNbFrames() );

src/AvTranscoder/mediaProperty/util.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ void add( PropertiesMap& propertiesMap, const std::string& key, const bool& valu
2222
add( propertiesMap, key, value ? "True" : "False" );
2323
}
2424

25+
template<>
26+
void add( PropertiesMap& propertiesMap, const std::string& key, const Rational& value )
27+
{
28+
add( propertiesMap, key, value.num / (double) value.den );
29+
}
30+
2531
void fillMetadataDictionnary( AVDictionary* avdictionnary, PropertiesMap& metadata )
2632
{
2733
AVDictionaryEntry* tag = NULL;

src/AvTranscoder/mediaProperty/util.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ void add( PropertiesMap& propertiesMap, const std::string& key, const std::strin
3333
template<>
3434
void add( PropertiesMap& propertiesMap, const std::string& key, const bool& value );
3535

36+
template<>
37+
void add( PropertiesMap& propertiesMap, const std::string& key, const Rational& value );
38+
3639
/**
3740
* @brief Fill metadata parameter with the given AVDictionary.
3841
*/

0 commit comments

Comments
 (0)