mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2024-12-24 20:01:53 +00:00
Do not use B frames but B frame like references for AVC as discussed on the matroska-devel mailing list. A new hack "avc_use_bframes" can mark those frames as B frames.
This commit is contained in:
parent
20d2438aec
commit
860c15c144
@ -36,6 +36,7 @@ static const char *mosu_hacks[] = {
|
|||||||
ENGAGE_NO_VARIABLE_DATA,
|
ENGAGE_NO_VARIABLE_DATA,
|
||||||
ENGAGE_NO_DEFAULT_HEADER_VALUES,
|
ENGAGE_NO_DEFAULT_HEADER_VALUES,
|
||||||
ENGAGE_FORCE_PASSTHROUGH_PACKETIZER,
|
ENGAGE_FORCE_PASSTHROUGH_PACKETIZER,
|
||||||
|
ENGAGE_AVC_USE_BFRAMES,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
static vector<string> engaged_hacks;
|
static vector<string> engaged_hacks;
|
||||||
|
@ -33,6 +33,7 @@ using namespace std;
|
|||||||
#define ENGAGE_NO_VARIABLE_DATA "no_variable_data"
|
#define ENGAGE_NO_VARIABLE_DATA "no_variable_data"
|
||||||
#define ENGAGE_NO_DEFAULT_HEADER_VALUES "no_default_header_values"
|
#define ENGAGE_NO_DEFAULT_HEADER_VALUES "no_default_header_values"
|
||||||
#define ENGAGE_FORCE_PASSTHROUGH_PACKETIZER "force_passthrough_packetizer"
|
#define ENGAGE_FORCE_PASSTHROUGH_PACKETIZER "force_passthrough_packetizer"
|
||||||
|
#define ENGAGE_AVC_USE_BFRAMES "avc_use_bframes"
|
||||||
|
|
||||||
void MTX_DLL_API engage_hacks(const string &hacks);
|
void MTX_DLL_API engage_hacks(const string &hacks);
|
||||||
bool MTX_DLL_API hack_engaged(const string &hack);
|
bool MTX_DLL_API hack_engaged(const string &hack);
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include "aac_common.h"
|
#include "aac_common.h"
|
||||||
#include "avilib.h"
|
#include "avilib.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "hacks.h"
|
||||||
#include "matroska.h"
|
#include "matroska.h"
|
||||||
#include "p_aac.h"
|
#include "p_aac.h"
|
||||||
#include "p_mp3.h"
|
#include "p_mp3.h"
|
||||||
@ -1037,7 +1038,8 @@ qtmp4_reader_c::handle_video_with_bframes(qtmp4_demuxer_ptr &dmx,
|
|||||||
mxerror(FMT_FN "The video track does not start with a key "
|
mxerror(FMT_FN "The video track does not start with a key "
|
||||||
"frame and a P frame but contains B frames. This is not "
|
"frame and a P frame but contains B frames. This is not "
|
||||||
"supported.\n", ti->fname.c_str());
|
"supported.\n", ti->fname.c_str());
|
||||||
fref = dmx->references[1];
|
if (dmx->avc_use_bframes)
|
||||||
|
fref = dmx->references[1];
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// This is a P frame. At the moment it references the second stored frame
|
// This is a P frame. At the moment it references the second stored frame
|
||||||
@ -1452,6 +1454,10 @@ qtmp4_reader_c::create_packetizer(int64_t tid) {
|
|||||||
false, ti));
|
false, ti));
|
||||||
ti->private_data = NULL;
|
ti->private_data = NULL;
|
||||||
|
|
||||||
|
if (hack_engaged(ENGAGE_AVC_USE_BFRAMES))
|
||||||
|
dmx->avc_use_bframes = true;
|
||||||
|
else
|
||||||
|
PTZR(dmx->ptzr)->relaxed_timecode_checking = true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ti->private_size = dmx->v_stsd_size;
|
ti->private_size = dmx->v_stsd_size;
|
||||||
|
@ -118,6 +118,7 @@ struct qtmp4_demuxer_t {
|
|||||||
uint32_t v_width, v_height, v_bitdepth;
|
uint32_t v_width, v_height, v_bitdepth;
|
||||||
int64_t v_dts_offset;
|
int64_t v_dts_offset;
|
||||||
deque<int64_t> references;
|
deque<int64_t> references;
|
||||||
|
bool avc_use_bframes;
|
||||||
int64_t max_timecode;
|
int64_t max_timecode;
|
||||||
uint32_t a_channels, a_bitdepth;
|
uint32_t a_channels, a_bitdepth;
|
||||||
float a_samplerate;
|
float a_samplerate;
|
||||||
@ -137,6 +138,7 @@ struct qtmp4_demuxer_t {
|
|||||||
esds_parsed(false),
|
esds_parsed(false),
|
||||||
v_stsd(NULL), v_stsd_size(0),
|
v_stsd(NULL), v_stsd_size(0),
|
||||||
v_width(0), v_height(0), v_bitdepth(0), v_dts_offset(0),
|
v_width(0), v_height(0), v_bitdepth(0), v_dts_offset(0),
|
||||||
|
avc_use_bframes(false),
|
||||||
max_timecode(0),
|
max_timecode(0),
|
||||||
a_channels(0), a_bitdepth(0), a_samplerate(0.0),
|
a_channels(0), a_bitdepth(0), a_samplerate(0.0),
|
||||||
priv(NULL), priv_size(0),
|
priv(NULL), priv_size(0),
|
||||||
|
@ -55,6 +55,7 @@ generic_packetizer_c::generic_packetizer_c(generic_reader_c *nreader,
|
|||||||
enqueued_bytes = 0;
|
enqueued_bytes = 0;
|
||||||
safety_last_timecode = 0;
|
safety_last_timecode = 0;
|
||||||
safety_last_duration = 0;
|
safety_last_duration = 0;
|
||||||
|
relaxed_timecode_checking = false;
|
||||||
last_cue_timecode = -1;
|
last_cue_timecode = -1;
|
||||||
correction_timecode_offset = 0;
|
correction_timecode_offset = 0;
|
||||||
append_timecode_offset = 0;
|
append_timecode_offset = 0;
|
||||||
@ -943,7 +944,8 @@ generic_packetizer_c::add_packet2(packet_t *pack) {
|
|||||||
// 'timecode < safety_last_timecode' may only occur for B frames. In this
|
// 'timecode < safety_last_timecode' may only occur for B frames. In this
|
||||||
// case we have the coding order, e.g. IPB1B2 and the timecodes
|
// case we have the coding order, e.g. IPB1B2 and the timecodes
|
||||||
// I: 0, P: 120, B1: 40, B2: 80.
|
// I: 0, P: 120, B1: 40, B2: 80.
|
||||||
if ((pack->timecode < safety_last_timecode) && (pack->fref < 0)) {
|
if (!relaxed_timecode_checking &&
|
||||||
|
(pack->timecode < safety_last_timecode) && (pack->fref < 0)) {
|
||||||
if (htrack_type == track_audio) {
|
if (htrack_type == track_audio) {
|
||||||
int64_t needed_timecode_offset;
|
int64_t needed_timecode_offset;
|
||||||
|
|
||||||
|
@ -446,6 +446,7 @@ public:
|
|||||||
int connected_to;
|
int connected_to;
|
||||||
int64_t correction_timecode_offset;
|
int64_t correction_timecode_offset;
|
||||||
int64_t append_timecode_offset, max_timecode_seen;
|
int64_t append_timecode_offset, max_timecode_seen;
|
||||||
|
bool relaxed_timecode_checking;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
generic_packetizer_c(generic_reader_c *nreader, track_info_c *nti)
|
generic_packetizer_c(generic_reader_c *nreader, track_info_c *nti)
|
||||||
|
Loading…
Reference in New Issue
Block a user