diff --git a/src/FFmpegWriter.cpp b/src/FFmpegWriter.cpp index 2a1238ab..cc6f1217 100644 --- a/src/FFmpegWriter.cpp +++ b/src/FFmpegWriter.cpp @@ -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) { - // 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, 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, 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, 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, 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, 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, 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, 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, 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;