From: =?utf-8?q?Martin_Stegh=C3=B6fer?= <martin@steghoefer.eu>
Date: Tue, 13 Nov 2012 20:19:11 +0100
Subject: Add missing includes for libavutil
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit

Author: Martin Steghöfer <martin@steghoefer.eu>
Bug: http://sourceforge.net/tracker/?func=detail&aid=3512390&group_id=290648&atid=1229531
Forwarded: not-needed

Added includes necessary for the use of the function "av_rescale_q".
Forwarding to upstream not needed because an equivalent patch has already been
posted to upstream's bug tracker (see URL in the "Bug" field).
---
 src/audioplayerprivate.cpp | 3 +++
 src/ffmpegvideoencoder.cpp | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/src/audioplayerprivate.cpp b/src/audioplayerprivate.cpp
index ffff90e..1b6b32d 100644
--- a/src/audioplayerprivate.cpp
+++ b/src/audioplayerprivate.cpp
@@ -21,6 +21,9 @@
 
 #include "audioplayer.h"
 #include "audioplayerprivate.h"
+extern "C" {
+#include "libavutil/mathematics.h"
+}
 #include <SDL/SDL.h>
 
 // SDL defines its own main() function in SDL_main. And so does Qt, so if we continue without
diff --git a/src/ffmpegvideoencoder.cpp b/src/ffmpegvideoencoder.cpp
index 5734d2e..49182b5 100644
--- a/src/ffmpegvideoencoder.cpp
+++ b/src/ffmpegvideoencoder.cpp
@@ -28,6 +28,9 @@
 #include "videoencodingprofiles.h"
 #include "audioplayer.h"
 #include "audioplayerprivate.h"
+extern "C" {
+#include "libavutil/mathematics.h"
+}
 
 
 #define MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio
From: =?utf-8?q?Martin_Stegh=C3=B6fer?= <martin@steghoefer.eu>
Date: Sat, 12 Apr 2014 15:19:48 +0200
Subject: Fix compilation: FFmpeg/Libav
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit

Author: Martin Steghöfer <martin@steghoefer.eu>
Forwarded: not-needed

The upstream developers compile Karlyriceditor against FFmpeg, but in Debian
there is only Libav available, whose API is slowly drifting away from
FFmpeg's. This patch adapts the code to several of those differences:
* The second parameters of "avformat_new_stream" is of non-const pointer
  type, but the code tries to pass a const pointer to it.
* There is no AV_ROUND_PASS_MINMAX flag for the rounding parameter of
  av_rescale_q_rnd in Libav.
* The member r_frame_rate is no longer present in AVStream. The recommended
  replacement is avg_frame_rate.
* The enums CODEC_ID_MP3 and CODEC_ID_AC3 have been prefixed with AV_.
* The function avcodec_alloc_frame was removed in favor of av_frame_alloc.
  The corresponding deallocation function is av_frame_free (not the generic
  av_free).
---
 src/audioplayerprivate.cpp |  4 ++--
 src/ffmpegvideodecoder.cpp |  8 ++++----
 src/ffmpegvideoencoder.cpp | 32 ++++++++++++++++++++------------
 3 files changed, 26 insertions(+), 18 deletions(-)

diff --git a/src/audioplayerprivate.cpp b/src/audioplayerprivate.cpp
index 1b6b32d..a6536cd 100644
--- a/src/audioplayerprivate.cpp
+++ b/src/audioplayerprivate.cpp
@@ -118,7 +118,7 @@ void AudioPlayerPrivate::close()
 	}
 
 	if ( m_frame )
-		av_free( m_frame );
+		av_frame_free( &m_frame );
 
 	m_frame = 0;
 	pFormatCtx = 0;
@@ -227,7 +227,7 @@ bool AudioPlayerPrivate::open( const QString& filename )
 	}
 
 	// Allocate the buffer
-	m_frame = avcodec_alloc_frame();
+	m_frame = av_frame_alloc();
 
 	if ( !m_frame )
 	{
diff --git a/src/ffmpegvideodecoder.cpp b/src/ffmpegvideodecoder.cpp
index 2ec5969..7820f72 100644
--- a/src/ffmpegvideodecoder.cpp
+++ b/src/ffmpegvideodecoder.cpp
@@ -113,8 +113,8 @@ bool FFMpegVideoDecoder::openFile( const QString& filename, unsigned int seekto
 	if ( d->videoStream == -1 )
 		return false; // Didn't find a video stream
 
-	d->m_fps_den = d->pFormatCtx->streams[d->videoStream]->r_frame_rate.den;
-	d->m_fps_num = d->pFormatCtx->streams[d->videoStream]->r_frame_rate.num;
+	d->m_fps_den = d->pFormatCtx->streams[d->videoStream]->avg_frame_rate.den;
+	d->m_fps_num = d->pFormatCtx->streams[d->videoStream]->avg_frame_rate.num;
 
 	if ( d->m_fps_den == 60000 )
 		d->m_fps_den = 30000;
@@ -139,10 +139,10 @@ bool FFMpegVideoDecoder::openFile( const QString& filename, unsigned int seekto
 	}
 
 	// Allocate video frame
-	d->pFrame = avcodec_alloc_frame();
+	d->pFrame = av_frame_alloc();
 
 	// Allocate an AVFrame structure
-	d->pFrameRGB = avcodec_alloc_frame();
+	d->pFrameRGB = av_frame_alloc();
 
 	if ( !d->pFrame || !d->pFrameRGB )
 	{
diff --git a/src/ffmpegvideoencoder.cpp b/src/ffmpegvideoencoder.cpp
index 49182b5..bdf1730 100644
--- a/src/ffmpegvideoencoder.cpp
+++ b/src/ffmpegvideoencoder.cpp
@@ -174,10 +174,10 @@ bool FFMpegVideoEncoderPriv::close()
 	delete[] audioSampleBuffer;
 
 	if ( videoFrame )
-		av_free(videoFrame);
+		av_frame_free( &videoFrame );
 
 	if ( audioFrame )
-		av_free( audioFrame );
+		av_frame_free( &audioFrame );
 
 	outputFormatCtx = 0;
 	outputFormat = 0;
@@ -383,7 +383,11 @@ av_log_set_level(AV_LOG_VERBOSE);
 	}
 
 	// Create the video stream, index
-	videoStream = avformat_new_stream( outputFormatCtx, videoCodecCtx->codec );
+	// Use a block to keep the helper variable "codec" local to avoid conflict with gotos
+	{
+	    AVCodec codec = *videoCodecCtx->codec;
+	    videoStream = avformat_new_stream( outputFormatCtx, &codec );
+	}
 
 	if ( !videoStream )
 	{
@@ -425,10 +429,10 @@ av_log_set_level(AV_LOG_VERBOSE);
 			// We're copying the stream
 			memcpy( newCtx, m_aplayer->aCodecCtx, sizeof(AVCodecContext) );
 
-			if ( newCtx->block_align == 1 && newCtx->codec_id == CODEC_ID_MP3 )
+			if ( newCtx->block_align == 1 && newCtx->codec_id == AV_CODEC_ID_MP3 )
 				newCtx->block_align= 0;
 
-			if ( newCtx->codec_id == CODEC_ID_AC3 )
+			if ( newCtx->codec_id == AV_CODEC_ID_AC3 )
 				newCtx->block_align= 0;
 		}
 		else
@@ -443,7 +447,7 @@ av_log_set_level(AV_LOG_VERBOSE);
 			}
 
 			// Hack to use the fixed AC3 codec if available
-			if ( audioCodec->id == CODEC_ID_AC3 && avcodec_find_encoder_by_name( "ac3_fixed" ) )
+			if ( audioCodec->id == AV_CODEC_ID_AC3 && avcodec_find_encoder_by_name( "ac3_fixed" ) )
 				audioCodec = avcodec_find_encoder_by_name( "ac3_fixed" );
 
 			// Allocate the audio context
@@ -544,7 +548,7 @@ av_log_set_level(AV_LOG_VERBOSE);
 				goto cleanup;
 			}
 
-			audioFrame = avcodec_alloc_frame();
+			audioFrame = av_frame_alloc();
 
 			if ( !audioFrame )
 			{
@@ -573,10 +577,10 @@ av_log_set_level(AV_LOG_VERBOSE);
 				goto cleanup;
 			}
 
-			if ( audioStream->codec->block_align == 1 && audioStream->codec->codec_id == CODEC_ID_MP3 )
+			if ( audioStream->codec->block_align == 1 && audioStream->codec->codec_id == AV_CODEC_ID_MP3 )
 				audioStream->codec->block_align= 0;
 
-			if ( audioStream->codec->codec_id == CODEC_ID_AC3 )
+			if ( audioStream->codec->codec_id == AV_CODEC_ID_AC3 )
 				audioStream->codec->block_align= 0;
 		}
 
@@ -595,7 +599,7 @@ av_log_set_level(AV_LOG_VERBOSE);
 	}
 
 	// Allocate the YUV frame
-	videoFrame = avcodec_alloc_frame();
+	videoFrame = av_frame_alloc();
 
 	if ( !videoFrame )
 	{
@@ -753,8 +757,12 @@ int FFMpegVideoEncoderPriv::encodeImage( const QImage &img, qint64 )
 					pkt.flags |= AV_PKT_FLAG_KEY;
 
 					// Rescale output packet timestamp values from codec to stream timebase
-					pkt.pts = av_rescale_q_rnd( pkt.pts, audioCodecCtx->time_base, audioStream->time_base, (AVRounding) (AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX) );
-					pkt.dts = av_rescale_q_rnd( pkt.dts, audioCodecCtx->time_base, audioStream->time_base, (AVRounding) (AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX) );
+					if ( pkt.pts != AV_NOPTS_VALUE ) {
+					    pkt.pts = av_rescale_q_rnd( pkt.pts, audioCodecCtx->time_base, audioStream->time_base, AV_ROUND_NEAR_INF );
+					}
+					if ( pkt.dts != AV_NOPTS_VALUE ) {
+					    pkt.dts = av_rescale_q_rnd( pkt.dts, audioCodecCtx->time_base, audioStream->time_base, AV_ROUND_NEAR_INF );
+					}
 					pkt.duration = av_rescale_q( pkt.duration, audioCodecCtx->time_base, audioStream->time_base);
 
 					// And write the file
From: =?utf-8?q?Martin_Stegh=C3=B6fer?= <martin@steghoefer.eu>
Date: Sat, 10 May 2014 01:04:56 +0200
Subject: Fix segfault: AVFrame initialization (Libav/FFmpeg)
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit

Author: Martin Steghöfer <martin@steghoefer.eu>
Forwarded: not-needed

The upstream developers compile Karlyriceditor against FFmpeg, but in Debian
there is only Libav available, whose API is slowly drifting away from
FFmpeg's. This patch adapts the code to one of those differences.
In Libav the function avcodec_get_frame_defaults cannot be called on a
completely uninitialized object. It expects at least some pointers inside
the struct to be initialized to NULL. Otherwise (depending on the random
pointer value) it may perform a free() on that random pointer. In Libav the
preferred way to initialize an AVFrame object is by calling
avcodec_alloc_frame(), which allocates the memory, initializes it to zero
and then calls avcodec_get_frame_defaults itself. This involves changing
"srcaudio" from a stack object to a heap object and freeing it after use.
---
 src/ffmpegvideoencoder.cpp | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/src/ffmpegvideoencoder.cpp b/src/ffmpegvideoencoder.cpp
index bdf1730..ccfdc7c 100644
--- a/src/ffmpegvideoencoder.cpp
+++ b/src/ffmpegvideoencoder.cpp
@@ -685,12 +685,11 @@ int FFMpegVideoEncoderPriv::encodeImage( const QImage &img, qint64 )
 			}
 
 			// Initialize the frame
-			AVFrame srcaudio;
-			avcodec_get_frame_defaults( &srcaudio );
+			AVFrame *srcaudio = av_frame_alloc();
 
 			// Decode the original audio into the srcaudio frame
 			int got_audio;
-			err = avcodec_decode_audio4( m_aplayer->aCodecCtx, &srcaudio, &got_audio, &pkt );
+			err = avcodec_decode_audio4( m_aplayer->aCodecCtx, srcaudio, &got_audio, &pkt );
 
 			if ( err < 0 )
 			{
@@ -710,9 +709,9 @@ int FFMpegVideoEncoderPriv::encodeImage( const QImage &img, qint64 )
 											NULL,
 											0,
 											0,
-											srcaudio.data,
+											srcaudio->data,
 											0,
-											srcaudio.nb_samples )) < 0 )
+											srcaudio->nb_samples )) < 0 )
 			{
 				qWarning( "Error resampling decoded audio: %d", err );
 				return -1;
@@ -777,6 +776,8 @@ int FFMpegVideoEncoderPriv::encodeImage( const QImage &img, qint64 )
 					av_free_packet( &pkt );
 				}
 			}
+
+			av_frame_free( &srcaudio );
 		}
 	}
 
From: =?utf-8?q?Martin_Stegh=C3=B6fer?= <martin@steghoefer.eu>
Date: Sat, 10 May 2014 13:19:25 +0200
Subject: Fix FP exception: Sample aspect ratio (Libav/FFmpeg)
MIME-Version: 1.0
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit

Author: Martin Steghöfer <martin@steghoefer.eu>
Forwarded: not-needed

The upstream developers compile Karlyriceditor against FFmpeg, but in Debian
there is only Libav available, whose API is slowly drifting away from
FFmpeg's. This patch adapts the code to one of those differences.
In Libav sample aspect ratio of a AVStream object is not automatically
initialized to the one of its codec. So this has to be done manually.
---
 src/ffmpegvideoencoder.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/ffmpegvideoencoder.cpp b/src/ffmpegvideoencoder.cpp
index ccfdc7c..3122f2a 100644
--- a/src/ffmpegvideoencoder.cpp
+++ b/src/ffmpegvideoencoder.cpp
@@ -399,6 +399,7 @@ av_log_set_level(AV_LOG_VERBOSE);
 	videoStream->codec = videoCodecCtx;
 
 	// Set the video stream timebase if not set
+	videoStream->sample_aspect_ratio = videoCodecCtx->sample_aspect_ratio;
 	if ( videoStream->time_base.den == 0 )
 		videoStream->time_base = videoCodecCtx->time_base;
 
