diff --git a/TODO b/TODO index be9e3c5..f300c59 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,6 @@ use libmagic to determine file types? add av_freep cleanup to raii interface for libav* (probably replacing unique_ptr in that case) raii-ify the muxing function -fix muxing fps/bitrate issue scale video thumbnails to same size as image thumbnails (500 in either dimension, same aspect ratio) crosspost title thread pool for workers. rehurn std::promise? diff --git a/src/test.cpp b/src/test.cpp index 2a03bf3..43e21f1 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -21,9 +21,19 @@ #include //move #include -#define DEBUG +#define DBG_LEVEL_NONE 0 +#define DBG_LEVEL_NORMAL 2 +#define DBG_LEVEL_VERBOSE 3 -#ifdef DEBUG +#define DEBUG_LEVEL DBG_LEVEL_NORMAL + +#if defined(DEBUG_LEVEL) && DEBUG_LEVEL >= DBG_LEVEL_VERBOSE +# define LIBAV_SET_LOG_LEVEL() av_log_set_level(AV_LOG_INFO) +#else +# define LIBAV_SET_LOG_LEVEL() av_log_set_level(AV_LOG_FATAL) +#endif + +#if defined(DEBUG_LEVEL) && DEBUG_LEVEL >= DBG_LEVEL_NORMAL # define DEBUG_PRINT(...) do{printf(__VA_ARGS__);}while(0) #else # define DEBUG_PRINT(...) do{}while(0) @@ -38,6 +48,8 @@ #include "reddit.hpp" #include "matrix.hpp" +#include //numeric_limits + extern "C"{ # include //AVCodecContext, AVCodec # include //AVFormatContext @@ -58,7 +70,7 @@ extern "C"{ //with the new code that fixes invalid input pts/dts, now the output framerate/bitrate is off bool mux_audio_video(const raii::string_base& audio_file, const raii::string_base& video_file, const raii::string_base& output_file){ REGISTER_LIBAV(); - av_log_set_level(AV_LOG_FATAL); + LIBAV_SET_LOG_LEVEL(); AVOutputFormat* out_format = NULL; AVFormatContext* audio_context = NULL, *video_context = NULL, *output_context = NULL; @@ -94,17 +106,10 @@ bool mux_audio_video(const raii::string_base& audio_file, const raii::string_bas audio_index_in = i; AVStream* in_stream = audio_context->streams[i]; - AVCodec* codec = avcodec_find_encoder(in_stream->codecpar->codec_id); - AVCodecContext* tmp = avcodec_alloc_context3(codec); - avcodec_parameters_to_context(tmp, in_stream->codecpar); - AVStream* out_stream = avformat_new_stream(output_context, codec); + AVStream* out_stream = avformat_new_stream(output_context, NULL); audio_index_out = out_stream->index; - if(output_context->oformat->flags & AVFMT_GLOBALHEADER){ - tmp->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; - } - tmp->codec_tag = 0; - avcodec_parameters_from_context(out_stream->codecpar, tmp); - avcodec_free_context(&tmp); + avcodec_parameters_copy(out_stream->codecpar, in_stream->codecpar); + out_stream->codecpar->codec_tag = 0; break; } @@ -114,17 +119,10 @@ bool mux_audio_video(const raii::string_base& audio_file, const raii::string_bas video_index_in = i; AVStream* in_stream = video_context->streams[i]; - AVCodec* codec = avcodec_find_encoder(in_stream->codecpar->codec_id); - AVCodecContext* tmp = avcodec_alloc_context3(codec); - avcodec_parameters_to_context(tmp, in_stream->codecpar); - AVStream* out_stream = avformat_new_stream(output_context, codec); + AVStream* out_stream = avformat_new_stream(output_context, NULL); video_index_out = out_stream->index; - if(output_context->oformat->flags & AVFMT_GLOBALHEADER){ - tmp->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; - } - tmp->codec_tag = 0; - avcodec_parameters_from_context(out_stream->codecpar, tmp); - avcodec_free_context(&tmp); + avcodec_parameters_copy(out_stream->codecpar, in_stream->codecpar); + out_stream->codecpar->codec_tag = 0; break; } @@ -150,7 +148,10 @@ bool mux_audio_video(const raii::string_base& audio_file, const raii::string_bas } int64_t video_pts = 0, audio_pts = 0; - int64_t last_video_dts = 0, last_audio_dts = 0; + + //took me 2 days to realize I had to initialize these to the smallest possible int64 value instead of just 0 + int64_t last_video_dts, last_audio_dts; + last_video_dts = last_audio_dts = std::numeric_limits::min(); while(true){ AVPacket packet; @@ -208,7 +209,7 @@ bool mux_audio_video(const raii::string_base& audio_file, const raii::string_bas //if dts is out of order, ffmpeg throws an error. So manually fix. Similar to what ffmpeg does in ffmpeg.c if(packet.dts < (*last_dts + !(output_context->oformat->flags & AVFMT_TS_NONSTRICT)) && packet.dts != AV_NOPTS_VALUE && (*last_dts) != AV_NOPTS_VALUE){ int64_t next_dts = (*last_dts)+1; - if(packet.pts >= packet.dts && packet.pts != AV_NOPTS_VALUE){ + if(packet.pts >= packet.dts){ packet.pts = FFMAX(packet.pts, next_dts); } if(packet.pts == AV_NOPTS_VALUE){