Skip to content

Commit 525f0aa

Browse files
author
Clement Champetier
committed
VideoProperties: add analyseFull private method which decodes all the stream
And compute the exact number of frames.
1 parent dffb65a commit 525f0aa

File tree

2 files changed

+52
-3
lines changed

2 files changed

+52
-3
lines changed

src/AvTranscoder/properties/VideoProperties.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ VideoProperties::VideoProperties(const FileProperties& fileProperties, const siz
2828
, _isTopFieldFirst(false)
2929
, _gopSize(0)
3030
, _gopStructure()
31+
, _nbFrames(0)
3132
, _firstGopTimeCode(-1)
3233
{
3334
if(_codecContext)
@@ -38,6 +39,8 @@ VideoProperties::VideoProperties(const FileProperties& fileProperties, const siz
3839

3940
if(_levelAnalysis == eAnalyseLevelFirstGop)
4041
analyseGopStructure(progress);
42+
else if(_levelAnalysis == eAnalyseLevelFull)
43+
analyseFull(progress);
4144
}
4245

4346
std::string VideoProperties::getProfileName() const
@@ -365,6 +368,9 @@ size_t VideoProperties::getNbFrames() const
365368
size_t nbFrames = _formatContext->streams[_streamIndex]->nb_frames;
366369
if(nbFrames == 0)
367370
{
371+
if(_levelAnalysis == eAnalyseLevelFull)
372+
return _nbFrames;
373+
368374
LOG_WARN("The number of frames in the stream '" << _streamIndex << "' of file '" << _formatContext->filename
369375
<< "' is unknown.")
370376
const float duration = getDuration();
@@ -554,6 +560,38 @@ void VideoProperties::analyseGopStructure(IProgress& progress)
554560
}
555561
}
556562

563+
void VideoProperties::analyseFull(IProgress& progress)
564+
{
565+
analyseGopStructure(progress);
566+
567+
if(! _formatContext || ! _codecContext || ! _codec)
568+
return;
569+
if(! _codecContext->width || ! _codecContext->height)
570+
return;
571+
572+
InputFile& file = const_cast<InputFile&>(_fileProperties->getInputFile());
573+
// Get the stream
574+
IInputStream& stream = file.getStream(_streamIndex);
575+
stream.activate();
576+
// Create a decoder
577+
VideoDecoder decoder(static_cast<InputStream&>(stream));
578+
579+
VideoFrame frame(VideoFrameDesc(getWidth(), getHeight(), getPixelProperties().getAVPixelFormat()));
580+
while(decoder.decodeNextFrame(frame))
581+
{
582+
++_nbFrames;
583+
}
584+
585+
// Returns at the beginning of the stream
586+
file.seekAtFrame(0, AVSEEK_FLAG_BYTE);
587+
588+
// Check GOP size
589+
if(_nbFrames <= 0)
590+
{
591+
throw std::runtime_error("Invalid number of frames when decoding the video stream.");
592+
}
593+
}
594+
557595
PropertyVector& VideoProperties::fillVector(PropertyVector& data) const
558596
{
559597
// Add properties of base class

src/AvTranscoder/properties/VideoProperties.hpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,15 @@ class AvExport VideoProperties : public StreamProperties
101101

102102
private:
103103
/**
104-
* @brief frame type / is key frame
105-
* @param progress: callback to get analysis progression
104+
* @param progress: callback to get analysis progression
106105
*/
107106
void analyseGopStructure(IProgress& progress);
108107

108+
/**
109+
* @param progress: callback to get analysis progression
110+
*/
111+
void analyseFull(IProgress& progress);
112+
109113
#ifndef SWIG
110114
template <typename T>
111115
void addProperty(PropertyVector& dataVector, const std::string& key, T (VideoProperties::*getter)(void) const) const
@@ -133,13 +137,20 @@ class AvExport VideoProperties : public StreamProperties
133137
PixelProperties _pixelProperties;
134138

135139
//@{
136-
// Can acces these data when analyse first gop
140+
// @brief Can access these data when analysing the first GOP.
141+
// @see eAnalyseLevelFirstGOP
137142
bool _isInterlaced;
138143
bool _isTopFieldFirst;
139144
size_t _gopSize;
140145
std::vector<std::pair<char, int> > _gopStructure; ///< picture type, encoded frame size in bytes
141146
//@}
142147

148+
//@{
149+
// @brief Can access these data when analysing all the stream.
150+
// @see eAnalyseLevelFull
151+
size_t _nbFrames;
152+
//}
153+
143154
/**
144155
* @brief GOP timecode of the first frame
145156
* @note AVCodecContext stores the GOP timecode of the last decoded frame

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