Skip to content

Fix encoding of last frames #245

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

Merged
merged 9 commits into from
Apr 22, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
51 changes: 16 additions & 35 deletions src/AvTranscoder/encoder/AudioEncoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,6 @@ bool AudioEncoder::encodeFrame(const Frame& sourceFrame, CodedData& codedFrame)
AVCodecContext& avCodecContext = _codec.getAVCodecContext();

AVPacket& packet = codedFrame.getAVPacket();
packet.stream_index = 0;

if((avCodecContext.coded_frame) && (avCodecContext.coded_frame->pts != (int)AV_NOPTS_VALUE))
{
packet.pts = avCodecContext.coded_frame->pts;
Expand All @@ -108,55 +106,38 @@ bool AudioEncoder::encodeFrame(const Frame& sourceFrame, CodedData& codedFrame)
packet.flags |= AV_PKT_FLAG_KEY;
}

#if LIBAVCODEC_VERSION_MAJOR > 53
int gotPacket = 0;
int ret = avcodec_encode_audio2(&avCodecContext, &packet, &sourceFrame.getAVFrame(), &gotPacket);
if(ret != 0 && gotPacket == 0)
{
throw std::runtime_error("Encode audio frame error: avcodec encode audio frame - " +
getDescriptionFromErrorCode(ret));
}
#else
int ret = avcodec_encode_audio(&avCodecContext, packet.data, packet.size, &sourceFrame.getAVFrame());
if(ret < 0)
{
throw std::runtime_error("Encode audio frame error: avcodec encode audio frame - " +
getDescriptionFromErrorCode(ret));
}
#endif

#if LIBAVCODEC_VERSION_MAJOR > 53
return ret == 0 && gotPacket == 1;
#endif
return ret == 0;
return encode(&sourceFrame.getAVFrame(), packet);
}

bool AudioEncoder::encodeFrame(CodedData& codedFrame)
{
AVCodecContext& avCodecContext = _codec.getAVCodecContext();
return encode(NULL, codedFrame.getAVPacket());
}

AVPacket& packet = codedFrame.getAVPacket();
packet.stream_index = 0;
bool AudioEncoder::encode(const AVFrame* decodedData, AVPacket& encodedData)
{
// Be sure that data of AVPacket is NULL so that the encoder will allocate it
encodedData.data = NULL;

AVCodecContext& avCodecContext = _codec.getAVCodecContext();
#if LIBAVCODEC_VERSION_MAJOR > 53
int gotPacket = 0;
int ret = avcodec_encode_audio2(&avCodecContext, &packet, NULL, &gotPacket);
if(ret != 0 && gotPacket == 0)
const int ret = avcodec_encode_audio2(&avCodecContext, &encodedData, decodedData, &gotPacket);
if(ret != 0)
Copy link
Member

Choose a reason for hiding this comment

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

Same remark here..

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep: dea73ee

{
throw std::runtime_error("Encode audio frame error: avcodec encode last audio frame - " +
throw std::runtime_error("Encode audio frame error: avcodec encode audio frame - " +
getDescriptionFromErrorCode(ret));
}
return ret == 0 && gotPacket == 1;

return gotPacket == 1;
#else
int ret = avcodec_encode_audio(&avCodecContext, packet.data, packet.size, NULL);
const int ret = avcodec_encode_audio(&avCodecContext, encodedData.data, encodedData.size, decodedData);
if(ret < 0)
{
throw std::runtime_error("Encode audio frame error: avcodec encode last audio frame - " +
throw std::runtime_error("Encode audio frame error: avcodec encode audio frame - " +
getDescriptionFromErrorCode(ret));
}
return ret == 0;

return true;
Copy link
Member

Choose a reason for hiding this comment

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

hm.. Shouldn't ret be more than 0 ? And wouldn't it be a bad value ?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes: https://ffmpeg.org/doxygen/2.7/group__lavc__encoding.html#gaf12a9da0d33f50ff406e03572fab4763
"""
Returns:
On error a negative value is returned, on success zero or the number of bytes used to encode the data read from the input buffer.
"""

Copy link
Member

Choose a reason for hiding this comment

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

Ah yes ! Okay !

#endif
}

}
3 changes: 3 additions & 0 deletions src/AvTranscoder/encoder/AudioEncoder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ class AvExport AudioEncoder : public IEncoder
ICodec& getCodec() { return _codec; }
AudioCodec& getAudioCodec() { return _codec; }

private:
bool encode(const AVFrame* decodedData, AVPacket& encodedData);

private:
AudioCodec _codec;
};
Expand Down
10 changes: 6 additions & 4 deletions src/AvTranscoder/encoder/IEncoder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,18 @@ class AvExport IEncoder

/**
* @brief Encode a new frame, and get coded frame
* @param sourceFrame frame need to be encoded
* @param codedFrame data of the coded frame if present (first frames can be delayed)
* @param sourceFrame: frame that needs to be encoded
* @param codedFrame: output encoded coded data (first frames can be delayed)
* @return status of encoding
* @throw runtime_error if the encoded process failed.
*/
virtual bool encodeFrame(const Frame& sourceFrame, CodedData& codedFrame) = 0;

/**
* @brief Get delayed encoded frames
* @param codedFrame data of the coded frame if present (first frames can be delayed)
* @brief Get the frames remaining into the encoder
* @param codedFrame: output encoded data
* @return status of encoding
* @throw runtime_error if the encoded process failed.
*/
virtual bool encodeFrame(CodedData& codedFrame) = 0;

Expand Down
49 changes: 16 additions & 33 deletions src/AvTranscoder/encoder/VideoEncoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,6 @@ bool VideoEncoder::encodeFrame(const Frame& sourceFrame, CodedData& codedFrame)
AVCodecContext& avCodecContext = _codec.getAVCodecContext();

AVPacket& packet = codedFrame.getAVPacket();
packet.stream_index = 0;

if((avCodecContext.coded_frame) && (avCodecContext.coded_frame->pts != (int)AV_NOPTS_VALUE))
{
packet.pts = avCodecContext.coded_frame->pts;
Expand All @@ -121,53 +119,38 @@ bool VideoEncoder::encodeFrame(const Frame& sourceFrame, CodedData& codedFrame)
packet.flags |= AV_PKT_FLAG_KEY;
}

#if LIBAVCODEC_VERSION_MAJOR > 53
int gotPacket = 0;
int ret = avcodec_encode_video2(&avCodecContext, &packet, &sourceFrame.getAVFrame(), &gotPacket);
if(ret != 0 && gotPacket == 0)
{
throw std::runtime_error("Encode video frame error: avcodec encode video frame - " +
getDescriptionFromErrorCode(ret));
}
#else
int ret = avcodec_encode_video(&avCodecContext, packet.data, packet.size, &sourceFrame.getAVFrame());
if(ret < 0)
{
throw std::runtime_error("Encode video frame error: avcodec encode video frame - " +
getDescriptionFromErrorCode(ret));
}
#endif

#if LIBAVCODEC_VERSION_MAJOR > 53
return ret == 0 && gotPacket == 1;
#endif
return ret == 0;
return encode(&sourceFrame.getAVFrame(), packet);
}

bool VideoEncoder::encodeFrame(CodedData& codedFrame)
{
AVCodecContext& avCodecContext = _codec.getAVCodecContext();
return encode(NULL, codedFrame.getAVPacket());
}

AVPacket& packet = codedFrame.getAVPacket();
packet.stream_index = 0;
bool VideoEncoder::encode(const AVFrame* decodedData, AVPacket& encodedData)
{
// Be sure that data of AVPacket is NULL so that the encoder will allocate it
encodedData.data = NULL;

AVCodecContext& avCodecContext = _codec.getAVCodecContext();
#if LIBAVCODEC_VERSION_MAJOR > 53
int gotPacket = 0;
int ret = avcodec_encode_video2(&avCodecContext, &packet, NULL, &gotPacket);
if(ret != 0 && gotPacket == 0)
const int ret = avcodec_encode_video2(&avCodecContext, &encodedData, decodedData, &gotPacket);
if(ret != 0)
{
throw std::runtime_error("Encode video frame error: avcodec encode last video frame - " +
throw std::runtime_error("Encode video frame error: avcodec encode video frame - " +
getDescriptionFromErrorCode(ret));
}
return ret == 0 && gotPacket == 1;
return gotPacket == 1;
#else
int ret = avcodec_encode_video(&avCodecContext, packet.data, packet.size, NULL);
const int ret = avcodec_encode_video(&avCodecContext, encodedData.data, encodedData.size, decodedData);
if(ret < 0)
{
throw std::runtime_error("Encode video frame error: avcodec encode last video frame - " +
throw std::runtime_error("Encode video frame error: avcodec encode video frame - " +
getDescriptionFromErrorCode(ret));
}
return ret == 0;
return true;
#endif
}

}
3 changes: 3 additions & 0 deletions src/AvTranscoder/encoder/VideoEncoder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ class AvExport VideoEncoder : public IEncoder
ICodec& getCodec() { return _codec; }
VideoCodec& getVideoCodec() { return _codec; }

private:
bool encode(const AVFrame* decodedData, AVPacket& encodedData);

private:
VideoCodec _codec;
};
Expand Down