Skip to content

Commit 0588177

Browse files
author
Clement Champetier
committed
VideoProperties: refactor how to estimate the video bitrate
* The first GOP is already decoded once, in analyseGopStructure private method. * Use the results already computed to estimate the bitrate.
1 parent efccced commit 0588177

File tree

1 file changed

+7
-66
lines changed

1 file changed

+7
-66
lines changed

src/AvTranscoder/properties/VideoProperties.cpp

Lines changed: 7 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -334,75 +334,16 @@ size_t VideoProperties::getBitRate() const
334334
return 0;
335335
}
336336

337-
LOG_INFO("Compute the video bitrate by decoding the first GOP.")
338-
339-
if(!_codecContext->width || !_codecContext->height)
340-
throw std::runtime_error("cannot compute bit rate: invalid frame size");
341-
342-
if(!_formatContext || !_codec)
343-
throw std::runtime_error("cannot compute bit rate: unknown format or codec");
344-
if(!_codecContext->width || !_codecContext->height)
345-
throw std::runtime_error("cannot compute bit rate: invalid frame size");
346-
347-
// discard no frame type when decode
348-
_codecContext->skip_frame = AVDISCARD_NONE;
349-
350-
Frame frame;
351-
AVPacket pkt;
352-
av_init_packet(&pkt);
353-
avcodec_open2(_codecContext, _codec, NULL);
354-
355-
int gotFrame = 0;
356-
size_t nbDecodedFrames = 0;
357-
int gopFramesSize = 0;
358-
int positionOfFirstKeyFrame = -1;
359-
int positionOfLastKeyFrame = -1;
360-
361-
while(!av_read_frame(const_cast<AVFormatContext*>(_formatContext), &pkt))
362-
{
363-
if(pkt.stream_index == (int)_streamIndex)
364-
{
365-
avcodec_decode_video2(_codecContext, &frame.getAVFrame(), &gotFrame, &pkt);
366-
if(gotFrame)
367-
{
368-
// check distance between key frames
369-
AVFrame& avFrame = frame.getAVFrame();
370-
if(avFrame.pict_type == AV_PICTURE_TYPE_I)
371-
{
372-
if(positionOfFirstKeyFrame == -1)
373-
positionOfFirstKeyFrame = nbDecodedFrames;
374-
else
375-
positionOfLastKeyFrame = nbDecodedFrames;
376-
}
377-
++nbDecodedFrames;
378-
379-
// added size of all frames of the same gop
380-
if(positionOfLastKeyFrame == -1)
381-
{
382-
#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(54, 7, 100)
383-
gopFramesSize += frame.getEncodedSize();
384-
#else
385-
gopFramesSize += pkt.size;
386-
#endif
387-
}
388-
}
389-
}
390-
av_free_packet(&pkt);
391-
if(positionOfFirstKeyFrame != -1 && positionOfLastKeyFrame != -1)
392-
break;
393-
}
394-
// Close a given AVCodecContext and free all the data associated with it (but not the AVCodecContext itself)
395-
avcodec_close(_codecContext);
396-
// Returns at the beginning of the stream
397-
const_cast<FormatContext*>(&_fileProperties->getFormatContext())->seek(0, AVSEEK_FLAG_BYTE);
337+
if(getGopSize() <= 0)
338+
return 0;
398339

399-
const size_t gopSize = positionOfLastKeyFrame - positionOfFirstKeyFrame;
400-
if(gopSize > 0)
340+
LOG_INFO("Estimate the video bitrate from the first GOP.")
341+
size_t gopFramesSize = 0;
342+
for(size_t picture = 0; picture < _gopStructure.size(); ++picture)
401343
{
402-
const float fps = av_q2d(_formatContext->streams[_streamIndex]->avg_frame_rate);
403-
return (gopFramesSize / gopSize) * 8 * fps;
344+
gopFramesSize += _gopStructure.at(picture).second;
404345
}
405-
return 0;
346+
return (gopFramesSize / getGopSize()) * 8 * getFps();
406347
}
407348

408349
size_t VideoProperties::getMaxBitRate() const

0 commit comments

Comments
 (0)