Skip to content

VideoProperties: fix decoding of first frames #246

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
a021550
Frame: added getEncodedSize method
May 3, 2016
f6da521
VideoProperties: refactored the methods that use AVFrame
May 3, 2016
742d9d9
VideoProperties: refactored getProfileName method
May 3, 2016
7aa1179
VideoProperties: refactored getBitRate method
May 3, 2016
4c82c58
VideoProperties: refactored the methods that use gop_size
May 3, 2016
1dffc17
VideoProperties: added _levelAnalysis private attribute
May 3, 2016
7d7f788
VideoProperties: fixed getGopSize method
May 3, 2016
2a81f06
VideoProperties: added doc to _pixelProperties attribute
May 3, 2016
2525317
FormatContext: added const to local variables of methods
May 3, 2016
68cc0dd
pyTest: updated testInputFileAnalyseFirstGop
May 3, 2016
81bc92e
VideoProperties: updated value returned by getGopStructure
May 3, 2016
4cee3de
VideoProperties: get encoded frame size of GOP when fillVector of pro…
May 3, 2016
c8ddd63
StreamProperties: update getDuration method
May 3, 2016
5625a87
FileProperties: removed seek at the beginning when extractStreamPrope…
May 3, 2016
b4cd1aa
properties: fixed GopPair/GopVector generated by SWIG
May 3, 2016
f56b7d1
pyTest: updated testInputFileAnalyseFirstGop
May 3, 2016
4df7cc4
VideoProperties: removed check of profile when getProfileName
May 9, 2016
378814d
VideoProperties: used attribute instead of parameter in constructor
May 9, 2016
bad195b
PixelProperties: fixed colorComponents value if not found
May 11, 2016
8cb866a
VideoProperties: fixed value of properties available when decode firs…
May 12, 2016
36a4f1a
FileProperties: added seek before and after extractStreamProperties
May 12, 2016
258d7ff
FileProperties: added mimeType to the list of properties when fillVector
May 12, 2016
17dca5e
FileProperties: throw runtime error if mime type is not found
May 12, 2016
daee1cf
FormatContext: no seek is done if the format is a raw bitstreams
May 12, 2016
79fab62
FormatContext: fixed seek method if format long name is unknown
May 13, 2016
a5ef6a1
pyTest: fixed dnx transcode tests
May 13, 2016
c7db438
pyTest: check width/height when transcode to dnxhd
May 13, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/AvTranscoder/data/decoded/Frame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ Frame::~Frame()
}
}

int Frame::getEncodedSize() const
{
return av_frame_get_pkt_size(_frame);
}

void Frame::copyData(const Frame& frameToRef)
{
const int ret = av_frame_copy(_frame, &frameToRef.getAVFrame());
Expand Down
6 changes: 6 additions & 0 deletions src/AvTranscoder/data/decoded/Frame.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ class AvExport Frame
*/
int* getLineSize() const { return _frame->linesize; }

/**
* @return Size of the corresponding packet containing the compressed frame (in bytes)
* @warning returns a negative value if the size is unknown
*/
int getEncodedSize() const;

/**
* @brief Copy the data of the given Frame.
* @note This function does not allocate anything: the current frame must be already initialized and
Expand Down
26 changes: 18 additions & 8 deletions src/AvTranscoder/file/FormatContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ FormatContext::~FormatContext()

void FormatContext::findStreamInfo(AVDictionary** options)
{
int err = avformat_find_stream_info(_avFormatContext, options);
const int err = avformat_find_stream_info(_avFormatContext, options);
if(err < 0)
{
throw std::ios_base::failure("Unable to find stream informations: " + getDescriptionFromErrorCode(err));
Expand All @@ -65,7 +65,7 @@ void FormatContext::openRessource(const std::string& url, int flags)
if((_avFormatContext->flags & AVFMT_NOFILE) == AVFMT_NOFILE)
return;

int err = avio_open2(&_avFormatContext->pb, url.c_str(), flags, NULL, NULL);
const int err = avio_open2(&_avFormatContext->pb, url.c_str(), flags, NULL, NULL);
if(err < 0)
{
throw std::ios_base::failure("Error when opening output format: " + getDescriptionFromErrorCode(err));
Expand All @@ -77,7 +77,7 @@ void FormatContext::closeRessource()
if((_avFormatContext->flags & AVFMT_NOFILE) == AVFMT_NOFILE)
return;

int err = avio_close(_avFormatContext->pb);
const int err = avio_close(_avFormatContext->pb);
if(err < 0)
{
throw std::ios_base::failure("Error when close output format: " + getDescriptionFromErrorCode(err));
Expand All @@ -86,7 +86,7 @@ void FormatContext::closeRessource()

void FormatContext::writeHeader(AVDictionary** options)
{
int ret = avformat_write_header(_avFormatContext, options);
const int ret = avformat_write_header(_avFormatContext, options);
if(ret != 0)
{
throw std::runtime_error("Could not write header: " + getDescriptionFromErrorCode(ret));
Expand Down Expand Up @@ -115,7 +115,7 @@ void FormatContext::writeFrame(AVPacket& packet, bool interleaved)

void FormatContext::writeTrailer()
{
int ret = av_write_trailer(_avFormatContext);
const int ret = av_write_trailer(_avFormatContext);
if(ret != 0)
{
throw std::runtime_error("Could not write trailer: " + getDescriptionFromErrorCode(ret));
Expand All @@ -124,7 +124,7 @@ void FormatContext::writeTrailer()

void FormatContext::addMetaData(const std::string& key, const std::string& value)
{
int ret = av_dict_set(&_avFormatContext->metadata, key.c_str(), value.c_str(), 0);
const int ret = av_dict_set(&_avFormatContext->metadata, key.c_str(), value.c_str(), 0);
if(ret < 0)
{
LOG_ERROR(getDescriptionFromErrorCode(ret))
Expand All @@ -144,8 +144,18 @@ AVStream& FormatContext::addAVStream(const AVCodec& avCodec)

bool FormatContext::seek(const uint64_t position, const int flag)
{
LOG_INFO("Seek in '" << _avFormatContext->filename << "' at " << position << " (in AV_TIME_BASE units)")
int err = av_seek_frame(_avFormatContext, -1, position, flag);
// Check if the format is a raw bitstreams, without any container.
// In this case, avoid seeking.
const std::string formatLongName(_avFormatContext->iformat->long_name ? _avFormatContext->iformat->long_name : "");
const std::size_t rawIndex = formatLongName.find("raw");
if(rawIndex != std::string::npos)
{
LOG_WARN("Seek in '" << _avFormatContext->filename << "' is not possible since this is a raw bitstreams without access to timing information.")
return false;
}

LOG_INFO("Seek in '" << _avFormatContext->filename << "' at " << position << " with flag '"<< flag << "'")
const int err = av_seek_frame(_avFormatContext, -1, position, flag);
if(err < 0)
{
LOG_ERROR("Error when seek at " << position << " (in AV_TIME_BASE units) in file")
Expand Down
1 change: 1 addition & 0 deletions src/AvTranscoder/file/FormatContext.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class AvExport FormatContext
* @param position: can be in AV_TIME_BASE units, in frames... depending on the flag value
* @param flag: seeking mode (AVSEEK_FLAG_xxx)
* @return seek status
* @warn No seek is done if the format is a raw bitstreams
* @see flushDecoder
*/
bool seek(const uint64_t position, const int flag);
Expand Down
14 changes: 5 additions & 9 deletions src/AvTranscoder/properties/FileProperties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ void FileProperties::extractStreamProperties(IProgress& progress, const EAnalyse
{
clearStreamProperties();

// if the analysis level wiil decode some streams parts, seek at the beginning
// Seek at first key frame before the analysis
if(level > eAnalyseLevelHeader)
const_cast<FormatContext*>(_formatContext)->seek(0, AVSEEK_FLAG_BACKWARD);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain why seeking at the beginning of the stream " make analysis impossible for some AVC Intra media " ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My mistake, this is deleted lines.. :)

Expand Down Expand Up @@ -119,7 +119,7 @@ void FileProperties::extractStreamProperties(IProgress& progress, const EAnalyse
_streams[unknownStreamIndex] = &_unknownStreams.at(streamIndex);
}

// if the analysis level has decoded some streams parts, return at the beginning
// Seek at first key frame after the analysis
if(level > eAnalyseLevelHeader)
const_cast<FormatContext*>(_formatContext)->seek(0, AVSEEK_FLAG_BACKWARD);
}
Expand Down Expand Up @@ -148,15 +148,10 @@ std::string FileProperties::getFormatLongName() const
std::string FileProperties::getFormatMimeType() const
{
#if LIBAVFORMAT_VERSION_MAJOR <= 55
LOG_WARN("Cannot get mime type format of '" << getFilename()
<< "' because your libavformat library has a major version <= 55.")
return "not available";
throw std::runtime_error("cannot get mime type format: libavformat library has a major version <= 55.");
#else
if(_avFormatContext->iformat->mime_type == NULL)
{
LOG_WARN("Unknown demuxer format mime type of '" << getFilename() << "'.")
return "";
}
throw std::runtime_error("Unknown demuxer format mime type");
return std::string(_avFormatContext->iformat->mime_type);
#endif
}
Expand Down Expand Up @@ -235,6 +230,7 @@ PropertyVector& FileProperties::fillVector(PropertyVector& data) const
addProperty(data, "filename", &FileProperties::getFilename);
addProperty(data, "formatName", &FileProperties::getFormatName);
addProperty(data, "formatLongName", &FileProperties::getFormatLongName);
addProperty(data, "mimeType", &FileProperties::getFormatMimeType);

addProperty(data, "startTime", &FileProperties::getStartTime);
addProperty(data, "duration", &FileProperties::getDuration);
Expand Down
2 changes: 1 addition & 1 deletion src/AvTranscoder/properties/PixelProperties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ PropertyVector& PixelProperties::fillVector(PropertyVector& data) const
}
catch(const std::exception& e)
{
detail::add(data, "colorComponents", e.what());
detail::add(data, "colorComponents", detail::propertyValueIfError);
}

try
Expand Down
5 changes: 4 additions & 1 deletion src/AvTranscoder/properties/StreamProperties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@ Rational StreamProperties::getTimeBase() const
float StreamProperties::getDuration() const
{
const Rational timeBase = getTimeBase();
return av_q2d(timeBase) * _formatContext->streams[_streamIndex]->duration;
const size_t streamDurationInStreamTimeBase = _formatContext->streams[_streamIndex]->duration;
if(streamDurationInStreamTimeBase == (size_t)AV_NOPTS_VALUE)
throw std::runtime_error("unknown stream duration");
return av_q2d(timeBase) * streamDurationInStreamTimeBase;
}

AVMediaType StreamProperties::getStreamType() const
Expand Down
7 changes: 7 additions & 0 deletions src/AvTranscoder/properties/StreamProperties.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ class AvExport StreamProperties
size_t getStreamIndex() const { return _streamIndex; }
size_t getStreamId() const;
Rational getTimeBase() const;

/**
* @return duration of the stream in seconds
* @throw runtime_error if the duration is unknown
* @note If a source file does not specify a duration, but does specify
* a bitrate, this value will be estimated from bitrate and file size.
*/
float getDuration() const; ///< in seconds
AVMediaType getStreamType() const;

Expand Down
Loading