fixed the fps/bitrate issue unless the input is severely messed up
This commit is contained in:
parent
051a694789
commit
8cc6272158
1
TODO
1
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?
|
||||
|
||||
51
src/test.cpp
51
src/test.cpp
@ -21,9 +21,19 @@
|
||||
#include <utility> //move
|
||||
#include <tuple>
|
||||
|
||||
#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 <limits> //numeric_limits
|
||||
|
||||
extern "C"{
|
||||
# include <libavcodec/avcodec.h> //AVCodecContext, AVCodec
|
||||
# include <libavformat/avformat.h> //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<int64_t>::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){
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user