Skip to content

Commit 27ad3d7

Browse files
author
Clement Champetier
committed
properties: defined bitRate in Video/AudioProperties
* Revert of commit 1804369. * * VideoProperties: need to override getDuration method (so StreamProperties::getDuration is virtual).
1 parent f6376f7 commit 27ad3d7

File tree

6 files changed

+128
-111
lines changed

6 files changed

+128
-111
lines changed

src/AvTranscoder/properties/AudioProperties.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,22 @@ std::string AudioProperties::getChannelDescription() const
104104
#endif
105105
}
106106

107+
size_t AudioProperties::getBitRate() const
108+
{
109+
if(!_codecContext)
110+
throw std::runtime_error("unknown codec context");
111+
112+
// return bit rate of stream if present
113+
if(_codecContext->bit_rate)
114+
return _codecContext->bit_rate;
115+
116+
LOG_WARN("The bitrate of the stream '" << _streamIndex << "' of file '" << _formatContext->filename << "' is unknown.")
117+
LOG_INFO("Compute the audio bitrate (suppose PCM audio data).")
118+
119+
const int bitsPerSample = av_get_bits_per_sample(_codecContext->codec_id); // 0 if unknown for the given codec
120+
return getSampleRate() * getNbChannels() * bitsPerSample;
121+
}
122+
107123
size_t AudioProperties::getSampleRate() const
108124
{
109125
if(!_codecContext)
@@ -144,6 +160,7 @@ PropertyVector& AudioProperties::fillVector(PropertyVector& data) const
144160

145161
addProperty(data, "sampleFormatName", &AudioProperties::getSampleFormatName);
146162
addProperty(data, "sampleFormatLongName", &AudioProperties::getSampleFormatLongName);
163+
addProperty(data, "bitRate", &AudioProperties::getBitRate);
147164
addProperty(data, "sampleRate", &AudioProperties::getSampleRate);
148165
addProperty(data, "nbSamples", &AudioProperties::getNbSamples);
149166
addProperty(data, "nbChannels", &AudioProperties::getNbChannels);

src/AvTranscoder/properties/AudioProperties.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class AvExport AudioProperties : public StreamProperties
1919
std::string getChannelName() const;
2020
std::string getChannelDescription() const;
2121

22+
size_t getBitRate() const; ///< in bits/s, 0 if unknown
2223
size_t getSampleRate() const;
2324
size_t getNbChannels() const;
2425
size_t getNbSamples() const;

src/AvTranscoder/properties/StreamProperties.cpp

Lines changed: 0 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#include <AvTranscoder/properties/util.hpp>
44
#include <AvTranscoder/properties/JsonWriter.hpp>
55
#include <AvTranscoder/properties/FileProperties.hpp>
6-
#include <AvTranscoder/data/decoded/Frame.hpp>
76

87
#include <stdexcept>
98

@@ -59,103 +58,6 @@ size_t StreamProperties::getStreamId() const
5958
return _formatContext->streams[_streamIndex]->id;
6059
}
6160

62-
size_t StreamProperties::getBitRate() const
63-
{
64-
if(!_codecContext)
65-
throw std::runtime_error("unknown codec context");
66-
67-
// return bit rate of stream if present or VBR mode
68-
if(_codecContext->bit_rate || _codecContext->rc_max_rate)
69-
return _codecContext->bit_rate;
70-
71-
LOG_WARN("The bitrate of the stream '" << _streamIndex << "' of file '" << _formatContext->filename << "' is unknown.")
72-
73-
const AVMediaType streamType = getStreamType();
74-
75-
// compute audio bitrate
76-
if(streamType == AVMEDIA_TYPE_AUDIO)
77-
{
78-
LOG_INFO("Compute the audio bitrate (suppose PCM audio data).")
79-
80-
// warning: this is the way to compute bit rate of PCM audio data
81-
const int bitsPerSample = av_get_bits_per_sample(_codecContext->codec_id); // 0 if unknown for the given codec
82-
return _codecContext->sample_rate * _codecContext->channels * bitsPerSample;
83-
}
84-
85-
// compute video bitrate
86-
if(streamType == AVMEDIA_TYPE_VIDEO)
87-
{
88-
LOG_INFO("Compute the video bitrate by decoding the first GOP.")
89-
90-
if(!_formatContext || !_codec)
91-
throw std::runtime_error("cannot compute bit rate: unknown format or codec context");
92-
if(!_codecContext->width || !_codecContext->height)
93-
throw std::runtime_error("cannot compute bit rate: invalid frame size");
94-
95-
// discard no frame type when decode
96-
_codecContext->skip_frame = AVDISCARD_NONE;
97-
98-
Frame frame;
99-
AVPacket pkt;
100-
av_init_packet(&pkt);
101-
avcodec_open2(_codecContext, _codec, NULL);
102-
103-
int gotFrame = 0;
104-
size_t nbDecodedFrames = 0;
105-
int gopFramesSize = 0;
106-
int positionOfFirstKeyFrame = -1;
107-
int positionOfLastKeyFrame = -1;
108-
109-
while(!av_read_frame(const_cast<AVFormatContext*>(_formatContext), &pkt))
110-
{
111-
if(pkt.stream_index == (int)_streamIndex)
112-
{
113-
avcodec_decode_video2(_codecContext, &frame.getAVFrame(), &gotFrame, &pkt);
114-
if(gotFrame)
115-
{
116-
// check distance between key frames
117-
AVFrame& avFrame = frame.getAVFrame();
118-
if(avFrame.pict_type == AV_PICTURE_TYPE_I)
119-
{
120-
if(positionOfFirstKeyFrame == -1)
121-
positionOfFirstKeyFrame = nbDecodedFrames;
122-
else
123-
positionOfLastKeyFrame = nbDecodedFrames;
124-
}
125-
++nbDecodedFrames;
126-
127-
// added size of all frames of the same gop
128-
if(positionOfLastKeyFrame == -1)
129-
{
130-
#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(54, 7, 100)
131-
gopFramesSize += frame.getEncodedSize();
132-
#else
133-
gopFramesSize += pkt.size;
134-
#endif
135-
}
136-
}
137-
}
138-
av_free_packet(&pkt);
139-
if(positionOfFirstKeyFrame != -1 && positionOfLastKeyFrame != -1)
140-
break;
141-
}
142-
// Close a given AVCodecContext and free all the data associated with it (but not the AVCodecContext itself)
143-
avcodec_close(_codecContext);
144-
145-
// Returns at the beginning of the stream
146-
const_cast<FormatContext*>(&_fileProperties->getFormatContext())->seek(0, AVSEEK_FLAG_BYTE);
147-
148-
const size_t gopSize = positionOfLastKeyFrame - positionOfFirstKeyFrame;
149-
if(gopSize > 0)
150-
{
151-
const float fps = av_q2d(_formatContext->streams[_streamIndex]->avg_frame_rate);
152-
return (gopFramesSize / gopSize) * 8 * fps;
153-
}
154-
}
155-
156-
return 0;
157-
}
158-
15961
Rational StreamProperties::getTimeBase() const
16062
{
16163
if(!_formatContext)
@@ -170,16 +72,6 @@ float StreamProperties::getDuration() const
17072
if(duration == (size_t)AV_NOPTS_VALUE)
17173
{
17274
LOG_WARN("The duration of the stream '" << _streamIndex << "' of file '" << _formatContext->filename << "' is unknown.")
173-
if(_fileProperties->isRawFormat())
174-
{
175-
LOG_INFO("Get the stream bitrate to compute the duration.")
176-
const size_t bitRate = getBitRate();
177-
if(bitRate)
178-
{
179-
LOG_INFO("Get the file size to compute the duration.")
180-
return _fileProperties->getFileSize() / bitRate * 8;
181-
}
182-
}
18375
return 0;
18476
}
18577
return av_q2d(timeBase) * duration;
@@ -247,7 +139,6 @@ PropertyVector& StreamProperties::fillVector(PropertyVector& data) const
247139
{
248140
addProperty(data, "streamId", &StreamProperties::getStreamId);
249141
addProperty(data, "streamIndex", &StreamProperties::getStreamIndex);
250-
addProperty(data, "bitRate", &StreamProperties::getBitRate);
251142
addProperty(data, "timeBase", &StreamProperties::getTimeBase);
252143
addProperty(data, "duration", &StreamProperties::getDuration);
253144
addProperty(data, "codecId", &StreamProperties::getCodecId);

src/AvTranscoder/properties/StreamProperties.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ class AvExport StreamProperties
2020

2121
size_t getStreamIndex() const { return _streamIndex; }
2222
size_t getStreamId() const;
23-
size_t getBitRate() const; ///< in bits/s, 0 if unknown
2423
Rational getTimeBase() const;
25-
float getDuration() const; ///< in seconds, 0 if not available
2624
AVMediaType getStreamType() const;
2725

26+
virtual float getDuration() const; ///< in seconds, 0 if not available
27+
2828
size_t getCodecId() const;
2929
std::string getCodecName() const;
3030
std::string getCodecLongName() const;

src/AvTranscoder/properties/VideoProperties.cpp

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,87 @@ Rational VideoProperties::getDar() const
319319
return dar;
320320
}
321321

322+
size_t VideoProperties::getBitRate() const
323+
{
324+
if(!_codecContext)
325+
throw std::runtime_error("unknown codec context");
326+
327+
// return bit rate of stream if present or VBR mode
328+
if(_codecContext->bit_rate || _codecContext->rc_max_rate)
329+
return _codecContext->bit_rate;
330+
331+
LOG_WARN("The bitrate of the stream '" << _streamIndex << "' of file '" << _formatContext->filename << "' is unknown.")
332+
LOG_INFO("Compute the video bitrate by decoding the first GOP.")
333+
334+
if(!_codecContext->width || !_codecContext->height)
335+
throw std::runtime_error("cannot compute bit rate: invalid frame size");
336+
337+
if(!_formatContext || !_codec)
338+
throw std::runtime_error("cannot compute bit rate: unknown format or codec");
339+
if(!_codecContext->width || !_codecContext->height)
340+
throw std::runtime_error("cannot compute bit rate: invalid frame size");
341+
342+
// discard no frame type when decode
343+
_codecContext->skip_frame = AVDISCARD_NONE;
344+
345+
Frame frame;
346+
AVPacket pkt;
347+
av_init_packet(&pkt);
348+
avcodec_open2(_codecContext, _codec, NULL);
349+
350+
int gotFrame = 0;
351+
size_t nbDecodedFrames = 0;
352+
int gopFramesSize = 0;
353+
int positionOfFirstKeyFrame = -1;
354+
int positionOfLastKeyFrame = -1;
355+
356+
while(!av_read_frame(const_cast<AVFormatContext*>(_formatContext), &pkt))
357+
{
358+
if(pkt.stream_index == (int)_streamIndex)
359+
{
360+
avcodec_decode_video2(_codecContext, &frame.getAVFrame(), &gotFrame, &pkt);
361+
if(gotFrame)
362+
{
363+
// check distance between key frames
364+
AVFrame& avFrame = frame.getAVFrame();
365+
if(avFrame.pict_type == AV_PICTURE_TYPE_I)
366+
{
367+
if(positionOfFirstKeyFrame == -1)
368+
positionOfFirstKeyFrame = nbDecodedFrames;
369+
else
370+
positionOfLastKeyFrame = nbDecodedFrames;
371+
}
372+
++nbDecodedFrames;
373+
374+
// added size of all frames of the same gop
375+
if(positionOfLastKeyFrame == -1)
376+
{
377+
#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(54, 7, 100)
378+
gopFramesSize += frame.getEncodedSize();
379+
#else
380+
gopFramesSize += pkt.size;
381+
#endif
382+
}
383+
}
384+
}
385+
av_free_packet(&pkt);
386+
if(positionOfFirstKeyFrame != -1 && positionOfLastKeyFrame != -1)
387+
break;
388+
}
389+
// Close a given AVCodecContext and free all the data associated with it (but not the AVCodecContext itself)
390+
avcodec_close(_codecContext);
391+
// Returns at the beginning of the stream
392+
const_cast<FormatContext*>(&_fileProperties->getFormatContext())->seek(0, AVSEEK_FLAG_BYTE);
393+
394+
const size_t gopSize = positionOfLastKeyFrame - positionOfFirstKeyFrame;
395+
if(gopSize > 0)
396+
{
397+
const float fps = av_q2d(_formatContext->streams[_streamIndex]->avg_frame_rate);
398+
return (gopFramesSize / gopSize) * 8 * fps;
399+
}
400+
return 0;
401+
}
402+
322403
size_t VideoProperties::getMaxBitRate() const
323404
{
324405
if(!_codecContext)
@@ -407,6 +488,25 @@ float VideoProperties::getFps() const
407488
return av_q2d(_formatContext->streams[_streamIndex]->avg_frame_rate);
408489
}
409490

491+
float VideoProperties::getDuration() const
492+
{
493+
const float duration = StreamProperties::getDuration();
494+
if(duration != 0)
495+
return duration;
496+
497+
if(_fileProperties->isRawFormat())
498+
{
499+
LOG_INFO("Get the stream bitrate to compute the duration.")
500+
const size_t bitRate = getBitRate();
501+
if(bitRate)
502+
{
503+
LOG_INFO("Get the file size to compute the duration.")
504+
return _fileProperties->getFileSize() / bitRate * 8;
505+
}
506+
}
507+
return 0;
508+
}
509+
410510
bool VideoProperties::hasBFrames() const
411511
{
412512
if(!_codecContext)
@@ -516,6 +616,7 @@ PropertyVector& VideoProperties::fillVector(PropertyVector& data) const
516616
addProperty(data, "fps", &VideoProperties::getFps);
517617
addProperty(data, "nbFrames", &VideoProperties::getNbFrames);
518618
addProperty(data, "ticksPerFrame", &VideoProperties::getTicksPerFrame);
619+
addProperty(data, "bitRate", &VideoProperties::getBitRate);
519620
addProperty(data, "maxBitRate", &VideoProperties::getMaxBitRate);
520621
addProperty(data, "minBitRate", &VideoProperties::getMinBitRate);
521622
addProperty(data, "hasBFrames", &VideoProperties::hasBFrames);

src/AvTranscoder/properties/VideoProperties.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class AvExport VideoProperties : public StreamProperties
4040
Rational getSar() const; // sample/pixel aspect ratio
4141
Rational getDar() const; // display aspect ratio
4242

43+
size_t getBitRate() const; ///< in bits/s, 0 if unknown
4344
size_t getMaxBitRate() const;
4445
size_t getMinBitRate() const;
4546
size_t getNbFrames() const; ///< 0 if unknown
@@ -60,6 +61,12 @@ class AvExport VideoProperties : public StreamProperties
6061
*/
6162
float getFps() const;
6263

64+
/**
65+
* @brief Override method.
66+
* @return the stream duration in seconds, 0 if not available
67+
*/
68+
float getDuration() const;
69+
6370
bool hasBFrames() const;
6471
// bool isClosedGop() const;
6572

0 commit comments

Comments
 (0)