Skip to content

Commit eeb101a

Browse files
committed
Merge pull request #133 from valnoel/feature/compute_bit_rate
Properties : compute bit rate if not available
2 parents 6408eab + 8fac8d5 commit eeb101a

File tree

4 files changed

+63
-7
lines changed

4 files changed

+63
-7
lines changed

src/AvTranscoder/mediaProperty/AudioProperties.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,14 @@ size_t AudioProperties::getBitRate() const
157157
{
158158
if( ! _codecContext )
159159
throw std::runtime_error( "unknown codec context" );
160-
int bitsPerSample = av_get_bits_per_sample( _codecContext->codec_id );
161-
size_t bitRate = bitsPerSample ? _codecContext->sample_rate * _codecContext->channels * bitsPerSample : _codecContext->bit_rate;
162-
return bitRate;
160+
161+
// return bit rate of stream
162+
if( _codecContext->bit_rate )
163+
return _codecContext->bit_rate;
164+
165+
// else get computed bit rate from our computation (warning: way to compute bit rate of PCM audio data)
166+
int bitsPerSample = av_get_bits_per_sample( _codecContext->codec_id ); // 0 if unknown for the given codec
167+
return _codecContext->sample_rate * _codecContext->channels * bitsPerSample;
163168
}
164169

165170
size_t AudioProperties::getNbSamples() const

src/AvTranscoder/mediaProperty/AudioProperties.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ class AvExport AudioProperties
2828
size_t getCodecId() const;
2929
size_t getSampleRate() const;
3030
size_t getChannels() const;
31-
size_t getBitRate() const;
32-
size_t getNbSamples() const;
31+
size_t getBitRate() const; ///< 0 if unknown
32+
size_t getNbSamples() const; ///< 0 if unknown
3333

3434
size_t getTicksPerFrame() const;
3535
Rational getTimeBase() const;

src/AvTranscoder/mediaProperty/FileProperties.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class AvExport FileProperties
2929
size_t getProgramsCount() const;
3030
double getStartTime() const;
3131
double getDuration() const; ///< in seconds
32-
size_t getBitRate() const;
32+
size_t getBitRate() const; ///< total stream bitrate in bit/s, 0 if not available (result of a computation by ffmpeg)
3333
size_t getPacketSize() const;
3434

3535
PropertiesMap& getMetadatas() { return _metadatas; }

src/AvTranscoder/mediaProperty/VideoProperties.cpp

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,58 @@ size_t VideoProperties::getBitRate() const
392392
{
393393
if( ! _codecContext )
394394
throw std::runtime_error( "unknown codec context" );
395-
return _codecContext->bit_rate;
395+
// return bit rate of stream if present or VBR mode
396+
if( _codecContext->bit_rate || _codecContext->rc_max_rate )
397+
return _codecContext->bit_rate;
398+
399+
// else compute bit rate from the first GOP
400+
if( ! _formatContext || ! _codec )
401+
throw std::runtime_error( "cannot compute bit rate: unknown format or codec context" );
402+
403+
if( ! _codecContext->width || ! _codecContext->height )
404+
throw std::runtime_error( "cannot compute bit rate: invalid frame size" );
405+
406+
// discard no frame type when decode
407+
_codecContext->skip_frame = AVDISCARD_NONE;
408+
409+
#if LIBAVCODEC_VERSION_MAJOR > 54
410+
AVFrame* frame = av_frame_alloc();
411+
#else
412+
AVFrame* frame = avcodec_alloc_frame();
413+
#endif
414+
AVPacket pkt;
415+
av_init_packet( &pkt );
416+
avcodec_open2( _codecContext, _codec, NULL );
417+
418+
int gotFrame = 0;
419+
int count = 0;
420+
int gopFramesSize = 0;
421+
422+
while( ! av_read_frame( const_cast<AVFormatContext*>( _formatContext ), &pkt ) )
423+
{
424+
if( pkt.stream_index == (int)_streamIndex )
425+
{
426+
avcodec_decode_video2( _codecContext, frame, &gotFrame, &pkt );
427+
if( gotFrame )
428+
{
429+
gopFramesSize += frame->pkt_size;
430+
++count;
431+
}
432+
}
433+
av_free_packet( &pkt );
434+
if( _codecContext->gop_size == count )
435+
break;
436+
}
437+
#if LIBAVCODEC_VERSION_MAJOR > 54
438+
av_frame_free( &frame );
439+
#elif LIBAVCODEC_VERSION_MAJOR > 53
440+
avcodec_free_frame( &frame );
441+
#else
442+
av_free( frame );
443+
#endif
444+
445+
int bitsPerByte = 8;
446+
return (gopFramesSize / _codecContext->gop_size) * bitsPerByte * getFps();
396447
}
397448

398449
size_t VideoProperties::getMaxBitRate() const

0 commit comments

Comments
 (0)