You've already forked libopenshot
mirror of
https://github.com/OpenShot/libopenshot.git
synced 2026-03-02 08:53:52 -08:00
Replace av_init_packet in FFmpeg 3.2+ (#784)
This commit is contained in:
@@ -856,16 +856,20 @@ void FFmpegWriter::flush_encoders() {
|
||||
#endif
|
||||
|
||||
// FLUSH VIDEO ENCODER
|
||||
if (info.has_video)
|
||||
if (info.has_video) {
|
||||
for (;;) {
|
||||
|
||||
// Increment PTS (in frames and scaled to the codec's timebase)
|
||||
video_timestamp += av_rescale_q(1, av_make_q(info.fps.den, info.fps.num), video_codec_ctx->time_base);
|
||||
video_timestamp += av_rescale_q(1, av_make_q(info.fps.den, info.fps.num), video_codec_ctx->time_base);
|
||||
|
||||
AVPacket pkt;
|
||||
av_init_packet(&pkt);
|
||||
pkt.data = NULL;
|
||||
pkt.size = 0;
|
||||
#if IS_FFMPEG_3_2
|
||||
AVPacket* pkt = av_packet_alloc();
|
||||
#else
|
||||
AVPacket* pkt;
|
||||
av_init_packet(pkt);
|
||||
#endif
|
||||
pkt->data = NULL;
|
||||
pkt->size = 0;
|
||||
|
||||
/* encode the image */
|
||||
int got_packet = 0;
|
||||
@@ -876,21 +880,21 @@ void FFmpegWriter::flush_encoders() {
|
||||
error_code = avcodec_send_frame(video_codec_ctx, NULL);
|
||||
got_packet = 0;
|
||||
while (error_code >= 0) {
|
||||
error_code = avcodec_receive_packet(video_codec_ctx, &pkt);
|
||||
error_code = avcodec_receive_packet(video_codec_ctx, pkt);
|
||||
if (error_code == AVERROR(EAGAIN)|| error_code == AVERROR_EOF) {
|
||||
got_packet = 0;
|
||||
// Write packet
|
||||
avcodec_flush_buffers(video_codec_ctx);
|
||||
break;
|
||||
}
|
||||
av_packet_rescale_ts(&pkt, video_codec_ctx->time_base, video_st->time_base);
|
||||
pkt.stream_index = video_st->index;
|
||||
error_code = av_interleaved_write_frame(oc, &pkt);
|
||||
av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
|
||||
pkt->stream_index = video_st->index;
|
||||
error_code = av_interleaved_write_frame(oc, pkt);
|
||||
}
|
||||
#else // IS_FFMPEG_3_2
|
||||
|
||||
// Encode video packet (older than FFmpeg 3.2)
|
||||
error_code = avcodec_encode_video2(video_codec_ctx, &pkt, NULL, &got_packet);
|
||||
error_code = avcodec_encode_video2(video_codec_ctx, pkt, NULL, &got_packet);
|
||||
|
||||
#endif // IS_FFMPEG_3_2
|
||||
|
||||
@@ -905,11 +909,11 @@ void FFmpegWriter::flush_encoders() {
|
||||
}
|
||||
|
||||
// set the timestamp
|
||||
av_packet_rescale_ts(&pkt, video_codec_ctx->time_base, video_st->time_base);
|
||||
pkt.stream_index = video_st->index;
|
||||
av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
|
||||
pkt->stream_index = video_st->index;
|
||||
|
||||
// Write packet
|
||||
error_code = av_interleaved_write_frame(oc, &pkt);
|
||||
error_code = av_interleaved_write_frame(oc, pkt);
|
||||
if (error_code < 0) {
|
||||
ZmqLogger::Instance()->AppendDebugMethod(
|
||||
"FFmpegWriter::flush_encoders ERROR ["
|
||||
@@ -917,15 +921,20 @@ void FFmpegWriter::flush_encoders() {
|
||||
"error_code", error_code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// FLUSH AUDIO ENCODER
|
||||
if (info.has_audio) {
|
||||
for (;;) {
|
||||
AVPacket pkt;
|
||||
av_init_packet(&pkt);
|
||||
pkt.data = NULL;
|
||||
pkt.size = 0;
|
||||
pkt.pts = pkt.dts = audio_timestamp;
|
||||
#if IS_FFMPEG_3_2
|
||||
AVPacket* pkt = av_packet_alloc();
|
||||
#else
|
||||
AVPacket* pkt;
|
||||
av_init_packet(pkt);
|
||||
#endif
|
||||
pkt->data = NULL;
|
||||
pkt->size = 0;
|
||||
pkt->pts = pkt->dts = audio_timestamp;
|
||||
|
||||
/* encode the image */
|
||||
int error_code = 0;
|
||||
@@ -933,7 +942,7 @@ void FFmpegWriter::flush_encoders() {
|
||||
#if IS_FFMPEG_3_2
|
||||
error_code = avcodec_send_frame(audio_codec_ctx, NULL);
|
||||
#else
|
||||
error_code = avcodec_encode_audio2(audio_codec_ctx, &pkt, NULL, &got_packet);
|
||||
error_code = avcodec_encode_audio2(audio_codec_ctx, pkt, NULL, &got_packet);
|
||||
#endif
|
||||
if (error_code < 0) {
|
||||
ZmqLogger::Instance()->AppendDebugMethod(
|
||||
@@ -947,17 +956,17 @@ void FFmpegWriter::flush_encoders() {
|
||||
|
||||
// Since the PTS can change during encoding, set the value again. This seems like a huge hack,
|
||||
// but it fixes lots of PTS related issues when I do this.
|
||||
pkt.pts = pkt.dts = audio_timestamp;
|
||||
pkt->pts = pkt->dts = audio_timestamp;
|
||||
|
||||
// Scale the PTS to the audio stream timebase (which is sometimes different than the codec's timebase)
|
||||
av_packet_rescale_ts(&pkt, audio_codec_ctx->time_base, audio_st->time_base);
|
||||
av_packet_rescale_ts(pkt, audio_codec_ctx->time_base, audio_st->time_base);
|
||||
|
||||
// set stream
|
||||
pkt.stream_index = audio_st->index;
|
||||
pkt.flags |= AV_PKT_FLAG_KEY;
|
||||
pkt->stream_index = audio_st->index;
|
||||
pkt->flags |= AV_PKT_FLAG_KEY;
|
||||
|
||||
// Write packet
|
||||
error_code = av_interleaved_write_frame(oc, &pkt);
|
||||
error_code = av_interleaved_write_frame(oc, pkt);
|
||||
if (error_code < 0) {
|
||||
ZmqLogger::Instance()->AppendDebugMethod(
|
||||
"FFmpegWriter::flush_encoders ERROR ["
|
||||
@@ -966,10 +975,10 @@ void FFmpegWriter::flush_encoders() {
|
||||
}
|
||||
|
||||
// Increment PTS by duration of packet
|
||||
audio_timestamp += pkt.duration;
|
||||
audio_timestamp += pkt->duration;
|
||||
|
||||
// deallocate memory for packet
|
||||
AV_FREE_PACKET(&pkt);
|
||||
AV_FREE_PACKET(pkt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1035,8 +1044,8 @@ void FFmpegWriter::Close() {
|
||||
}
|
||||
|
||||
// Reset frame counters
|
||||
video_timestamp = 0;
|
||||
audio_timestamp = 0;
|
||||
video_timestamp = 0;
|
||||
audio_timestamp = 0;
|
||||
|
||||
// Free the context which frees the streams too
|
||||
avformat_free_context(oc);
|
||||
@@ -1920,13 +1929,17 @@ void FFmpegWriter::write_audio_packets(bool is_final) {
|
||||
frame_final->pts = audio_timestamp;
|
||||
|
||||
// Init the packet
|
||||
AVPacket pkt;
|
||||
av_init_packet(&pkt);
|
||||
pkt.data = audio_encoder_buffer;
|
||||
pkt.size = audio_encoder_buffer_size;
|
||||
#if IS_FFMPEG_3_2
|
||||
AVPacket* pkt = av_packet_alloc();
|
||||
#else
|
||||
AVPacket* pkt;
|
||||
av_init_packet(pkt);
|
||||
#endif
|
||||
pkt->data = audio_encoder_buffer;
|
||||
pkt->size = audio_encoder_buffer_size;
|
||||
|
||||
// Set the packet's PTS prior to encoding
|
||||
pkt.pts = pkt.dts = audio_timestamp;
|
||||
pkt->pts = pkt->dts = audio_timestamp;
|
||||
|
||||
/* encode the audio samples */
|
||||
int got_packet_ptr = 0;
|
||||
@@ -1942,8 +1955,8 @@ void FFmpegWriter::write_audio_packets(bool is_final) {
|
||||
}
|
||||
else {
|
||||
if (ret >= 0)
|
||||
pkt.size = 0;
|
||||
ret = avcodec_receive_packet(audio_codec_ctx, &pkt);
|
||||
pkt->size = 0;
|
||||
ret = avcodec_receive_packet(audio_codec_ctx, pkt);
|
||||
if (ret >= 0)
|
||||
frame_finished = 1;
|
||||
if(ret == AVERROR(EINVAL) || ret == AVERROR_EOF) {
|
||||
@@ -1954,31 +1967,31 @@ void FFmpegWriter::write_audio_packets(bool is_final) {
|
||||
ret = frame_finished;
|
||||
}
|
||||
}
|
||||
if (!pkt.data && !frame_finished)
|
||||
if (!pkt->data && !frame_finished)
|
||||
{
|
||||
ret = -1;
|
||||
}
|
||||
got_packet_ptr = ret;
|
||||
#else
|
||||
// Encode audio (older versions of FFmpeg)
|
||||
int error_code = avcodec_encode_audio2(audio_codec_ctx, &pkt, frame_final, &got_packet_ptr);
|
||||
int error_code = avcodec_encode_audio2(audio_codec_ctx, pkt, frame_final, &got_packet_ptr);
|
||||
#endif
|
||||
/* if zero size, it means the image was buffered */
|
||||
if (error_code == 0 && got_packet_ptr) {
|
||||
|
||||
// Since the PTS can change during encoding, set the value again. This seems like a huge hack,
|
||||
// but it fixes lots of PTS related issues when I do this.
|
||||
pkt.pts = pkt.dts = audio_timestamp;
|
||||
pkt->pts = pkt->dts = audio_timestamp;
|
||||
|
||||
// Scale the PTS to the audio stream timebase (which is sometimes different than the codec's timebase)
|
||||
av_packet_rescale_ts(&pkt, audio_codec_ctx->time_base, audio_st->time_base);
|
||||
av_packet_rescale_ts(pkt, audio_codec_ctx->time_base, audio_st->time_base);
|
||||
|
||||
// set stream
|
||||
pkt.stream_index = audio_st->index;
|
||||
pkt.flags |= AV_PKT_FLAG_KEY;
|
||||
pkt->stream_index = audio_st->index;
|
||||
pkt->flags |= AV_PKT_FLAG_KEY;
|
||||
|
||||
/* write the compressed frame in the media file */
|
||||
error_code = av_interleaved_write_frame(oc, &pkt);
|
||||
error_code = av_interleaved_write_frame(oc, pkt);
|
||||
}
|
||||
|
||||
if (error_code < 0) {
|
||||
@@ -1996,7 +2009,7 @@ void FFmpegWriter::write_audio_packets(bool is_final) {
|
||||
AV_FREE_FRAME(&frame_final);
|
||||
|
||||
// deallocate memory for packet
|
||||
AV_FREE_PACKET(&pkt);
|
||||
AV_FREE_PACKET(pkt);
|
||||
|
||||
// Reset position
|
||||
audio_input_position = 0;
|
||||
@@ -2044,23 +2057,23 @@ AVFrame *FFmpegWriter::allocate_avframe(PixelFormat pix_fmt, int width, int heig
|
||||
|
||||
// process video frame
|
||||
void FFmpegWriter::process_video_packet(std::shared_ptr<Frame> frame) {
|
||||
// Determine the height & width of the source image
|
||||
int source_image_width = frame->GetWidth();
|
||||
int source_image_height = frame->GetHeight();
|
||||
// Determine the height & width of the source image
|
||||
int source_image_width = frame->GetWidth();
|
||||
int source_image_height = frame->GetHeight();
|
||||
|
||||
// Do nothing if size is 1x1 (i.e. no image in this frame)
|
||||
if (source_image_height == 1 && source_image_width == 1)
|
||||
return;
|
||||
// Do nothing if size is 1x1 (i.e. no image in this frame)
|
||||
if (source_image_height == 1 && source_image_width == 1)
|
||||
return;
|
||||
|
||||
// Init rescalers (if not initialized yet)
|
||||
if (image_rescalers.size() == 0)
|
||||
InitScalers(source_image_width, source_image_height);
|
||||
// Init rescalers (if not initialized yet)
|
||||
if (image_rescalers.size() == 0)
|
||||
InitScalers(source_image_width, source_image_height);
|
||||
|
||||
// Get a unique rescaler (for this thread)
|
||||
SwsContext *scaler = image_rescalers[rescaler_position];
|
||||
rescaler_position++;
|
||||
if (rescaler_position == num_of_rescalers)
|
||||
rescaler_position = 0;
|
||||
// Get a unique rescaler (for this thread)
|
||||
SwsContext *scaler = image_rescalers[rescaler_position];
|
||||
rescaler_position++;
|
||||
if (rescaler_position == num_of_rescalers)
|
||||
rescaler_position = 0;
|
||||
|
||||
// Allocate an RGB frame & final output frame
|
||||
int bytes_source = 0;
|
||||
@@ -2131,8 +2144,14 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame *fra
|
||||
if (oc->oformat->flags & AVFMT_RAWPICTURE) {
|
||||
#endif
|
||||
// Raw video case.
|
||||
#if IS_FFMPEG_3_2
|
||||
AVPacket* pkt = av_packet_alloc();
|
||||
#else
|
||||
AVPacket* pkt;
|
||||
av_packet_from_data(
|
||||
av_init_packet(pkt);
|
||||
#endif
|
||||
|
||||
av_packet_from_data(
|
||||
pkt, frame_final->data[0],
|
||||
frame_final->linesize[0] * frame_final->height);
|
||||
|
||||
@@ -2158,11 +2177,15 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame *fra
|
||||
} else
|
||||
{
|
||||
|
||||
AVPacket pkt;
|
||||
av_init_packet(&pkt);
|
||||
pkt.data = NULL;
|
||||
pkt.size = 0;
|
||||
pkt.pts = pkt.dts = AV_NOPTS_VALUE;
|
||||
#if IS_FFMPEG_3_2
|
||||
AVPacket* pkt = av_packet_alloc();
|
||||
#else
|
||||
AVPacket* pkt;
|
||||
av_init_packet(pkt);
|
||||
#endif
|
||||
pkt->data = NULL;
|
||||
pkt->size = 0;
|
||||
pkt->pts = pkt->dts = AV_NOPTS_VALUE;
|
||||
|
||||
// Assign the initial AVFrame PTS from the frame counter
|
||||
frame_final->pts = video_timestamp;
|
||||
@@ -2188,12 +2211,12 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame *fra
|
||||
int got_packet_ptr = 0;
|
||||
int error_code = 0;
|
||||
#if IS_FFMPEG_3_2
|
||||
// Write video packet (latest version of FFmpeg)
|
||||
// Write video packet
|
||||
int ret;
|
||||
|
||||
#if USE_HW_ACCEL
|
||||
if (hw_en_on && hw_en_supported) {
|
||||
ret = avcodec_send_frame(video_codec_ctx, hw_frame); //hw_frame!!!
|
||||
ret = avcodec_send_frame(video_codec_ctx, hw_frame); //hw_frame!!!
|
||||
} else
|
||||
#endif // USE_HW_ACCEL
|
||||
{
|
||||
@@ -2213,7 +2236,7 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame *fra
|
||||
}
|
||||
else {
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_packet(video_codec_ctx, &pkt);
|
||||
ret = avcodec_receive_packet(video_codec_ctx, pkt);
|
||||
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
||||
avcodec_flush_buffers(video_codec_ctx);
|
||||
@@ -2228,7 +2251,7 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame *fra
|
||||
}
|
||||
#else
|
||||
// Write video packet (older than FFmpeg 3.2)
|
||||
error_code = avcodec_encode_video2(video_codec_ctx, &pkt, frame_final, &got_packet_ptr);
|
||||
error_code = avcodec_encode_video2(video_codec_ctx, pkt, frame_final, &got_packet_ptr);
|
||||
if (error_code != 0) {
|
||||
ZmqLogger::Instance()->AppendDebugMethod(
|
||||
"FFmpegWriter::write_video_packet ERROR ["
|
||||
@@ -2244,11 +2267,11 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame *fra
|
||||
/* if zero size, it means the image was buffered */
|
||||
if (error_code == 0 && got_packet_ptr) {
|
||||
// set the timestamp
|
||||
av_packet_rescale_ts(&pkt, video_codec_ctx->time_base, video_st->time_base);
|
||||
pkt.stream_index = video_st->index;
|
||||
av_packet_rescale_ts(pkt, video_codec_ctx->time_base, video_st->time_base);
|
||||
pkt->stream_index = video_st->index;
|
||||
|
||||
/* write the compressed frame in the media file */
|
||||
int result = av_interleaved_write_frame(oc, &pkt);
|
||||
int result = av_interleaved_write_frame(oc, pkt);
|
||||
if (result < 0) {
|
||||
ZmqLogger::Instance()->AppendDebugMethod(
|
||||
"FFmpegWriter::write_video_packet ERROR ["
|
||||
@@ -2259,7 +2282,7 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame *fra
|
||||
}
|
||||
|
||||
// Deallocate packet
|
||||
AV_FREE_PACKET(&pkt);
|
||||
AV_FREE_PACKET(pkt);
|
||||
#if USE_HW_ACCEL
|
||||
if (hw_en_on && hw_en_supported) {
|
||||
if (hw_frame) {
|
||||
@@ -2270,8 +2293,8 @@ bool FFmpegWriter::write_video_packet(std::shared_ptr<Frame> frame, AVFrame *fra
|
||||
#endif // USE_HW_ACCEL
|
||||
}
|
||||
|
||||
// Increment PTS (in frames and scaled to the codec's timebase)
|
||||
video_timestamp += av_rescale_q(1, av_make_q(info.fps.den, info.fps.num), video_codec_ctx->time_base);
|
||||
// Increment PTS (in frames and scaled to the codec's timebase)
|
||||
video_timestamp += av_rescale_q(1, av_make_q(info.fps.den, info.fps.num), video_codec_ctx->time_base);
|
||||
|
||||
// Success
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user