mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2025-01-17 15:42:10 +00:00
MPEG TS: don't exit on MPEG-1/2 errors
This commit is contained in:
parent
3c9a9c4737
commit
60dfa439e1
@ -1,3 +1,9 @@
|
||||
2014-10-07 Moritz Bunkus <moritz@bunkus.org>
|
||||
|
||||
* mkvmerge: bug fix: probing MPEG transport streams with certain
|
||||
types of broken MPEG-2 inside caused mkvmerge to exit with an
|
||||
error message. Such tracks are now ignored instead.
|
||||
|
||||
2014-09-29 Moritz Bunkus <moritz@bunkus.org>
|
||||
|
||||
* mkvmerge, mmg's chapter editor: fixed the default value for the
|
||||
|
@ -116,6 +116,7 @@ mpeg_ts_track_c::new_stream_v_mpeg_1_2() {
|
||||
if (!m_m2v_parser) {
|
||||
m_m2v_parser = std::shared_ptr<M2VParser>(new M2VParser);
|
||||
m_m2v_parser->SetProbeMode();
|
||||
m_m2v_parser->SetThrowOnError(true);
|
||||
}
|
||||
|
||||
m_m2v_parser->WriteData(pes_payload->get_buffer(), pes_payload->get_size());
|
||||
@ -973,40 +974,50 @@ mpeg_ts_reader_c::parse_packet(unsigned char *buf) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
mpeg_ts_reader_c::determine_track_parameters(mpeg_ts_track_ptr const &track) {
|
||||
if (track->type == PAT_TYPE)
|
||||
return parse_pat(track->pes_payload->get_buffer());
|
||||
|
||||
else if (track->type == PMT_TYPE)
|
||||
return parse_pmt(track->pes_payload->get_buffer());
|
||||
|
||||
else if (track->type == ES_VIDEO_TYPE) {
|
||||
if (track->codec.is(CT_V_MPEG12))
|
||||
return track->new_stream_v_mpeg_1_2();
|
||||
else if (track->codec.is(CT_V_MPEG4_P10))
|
||||
return track->new_stream_v_avc();
|
||||
else if (track->codec.is(CT_V_VC1))
|
||||
return track->new_stream_v_vc1();
|
||||
|
||||
track->pes_payload->set_chunk_size(512 * 1024);
|
||||
|
||||
} else if (track->type != ES_AUDIO_TYPE)
|
||||
return -1;
|
||||
|
||||
if (track->codec.is(CT_A_MP3))
|
||||
return track->new_stream_a_mpeg();
|
||||
else if (track->codec.is(CT_A_AAC))
|
||||
return track->new_stream_a_aac();
|
||||
else if (track->codec.is(CT_A_AC3))
|
||||
return track->new_stream_a_ac3();
|
||||
else if (track->codec.is(CT_A_DTS))
|
||||
return track->new_stream_a_dts();
|
||||
else if (track->codec.is(CT_A_PCM))
|
||||
return track->new_stream_a_pcm();
|
||||
else if (track->codec.is(CT_A_TRUEHD))
|
||||
return track->new_stream_a_truehd();
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
mpeg_ts_reader_c::probe_packet_complete(mpeg_ts_track_ptr &track) {
|
||||
int result = -1;
|
||||
|
||||
if (track->type == PAT_TYPE)
|
||||
result = parse_pat(track->pes_payload->get_buffer());
|
||||
|
||||
else if (track->type == PMT_TYPE)
|
||||
result = parse_pmt(track->pes_payload->get_buffer());
|
||||
|
||||
else if (track->type == ES_VIDEO_TYPE) {
|
||||
if (track->codec.is(CT_V_MPEG12))
|
||||
result = track->new_stream_v_mpeg_1_2();
|
||||
else if (track->codec.is(CT_V_MPEG4_P10))
|
||||
result = track->new_stream_v_avc();
|
||||
else if (track->codec.is(CT_V_VC1))
|
||||
result = track->new_stream_v_vc1();
|
||||
|
||||
track->pes_payload->set_chunk_size(512 * 1024);
|
||||
|
||||
} else if (track->type == ES_AUDIO_TYPE) {
|
||||
if (track->codec.is(CT_A_MP3))
|
||||
result = track->new_stream_a_mpeg();
|
||||
else if (track->codec.is(CT_A_AAC))
|
||||
result = track->new_stream_a_aac();
|
||||
else if (track->codec.is(CT_A_AC3))
|
||||
result = track->new_stream_a_ac3();
|
||||
else if (track->codec.is(CT_A_DTS))
|
||||
result = track->new_stream_a_dts();
|
||||
else if (track->codec.is(CT_A_PCM))
|
||||
result = track->new_stream_a_pcm();
|
||||
else if (track->codec.is(CT_A_TRUEHD))
|
||||
result = track->new_stream_a_truehd();
|
||||
|
||||
try {
|
||||
result = determine_track_parameters(track);
|
||||
} catch (...) {
|
||||
}
|
||||
|
||||
track->pes_payload->remove(track->pes_payload->get_size());
|
||||
|
@ -414,6 +414,7 @@ private:
|
||||
int parse_pmt(unsigned char *pmt);
|
||||
bool parse_start_unit_packet(mpeg_ts_track_ptr &track, mpeg_ts_packet_header_t *ts_packet_header, unsigned char *&ts_payload, unsigned char &ts_payload_size);
|
||||
void probe_packet_complete(mpeg_ts_track_ptr &track);
|
||||
int determine_track_parameters(mpeg_ts_track_ptr const &track);
|
||||
|
||||
file_status_e finish();
|
||||
int send_to_packetizer(mpeg_ts_track_ptr &track);
|
||||
|
@ -102,8 +102,9 @@ void M2VParser::DumpQueues(){
|
||||
}
|
||||
}
|
||||
|
||||
M2VParser::M2VParser(){
|
||||
|
||||
M2VParser::M2VParser()
|
||||
: throwOnError{}
|
||||
{
|
||||
mpgBuf = new MPEGVideoBuffer(BUFF_SIZE);
|
||||
|
||||
notReachedFirstGOP = true;
|
||||
@ -237,7 +238,10 @@ int32_t M2VParser::OrderFrame(MPEGFrame* frame){
|
||||
bool flushQueue = false;
|
||||
|
||||
if (waitSecondField && (p->pictureStructure == MPEG2_PICTURE_TYPE_FRAME)){
|
||||
mxerror(Y("Unexpected picture frame after single field frame. Fix the MPEG2 video stream before attempting to multiplex it.\n"));
|
||||
auto error = Y("Unexpected picture frame after single field frame. Fix the MPEG2 video stream before attempting to multiplex it.\n");
|
||||
if (throwOnError)
|
||||
throw error;
|
||||
mxerror(error);
|
||||
}
|
||||
|
||||
if((p->timecode == queueTime) && waitQueue.empty()){
|
||||
@ -389,7 +393,10 @@ int32_t M2VParser::FillQueues(){
|
||||
gopNum++;
|
||||
/* Perform some sanity checks */
|
||||
if(waitSecondField){
|
||||
mxerror(Y("Single field frame before GOP header detected. Fix the MPEG2 video stream before attempting to multiplex it.\n"));
|
||||
auto error = Y("Single field frame before GOP header detected. Fix the MPEG2 video stream before attempting to multiplex it.\n");
|
||||
if (throwOnError)
|
||||
throw error;
|
||||
mxerror(error);
|
||||
}
|
||||
// There are too many broken videos to do the following so ReferenceBlock will be wrong for broken videos.
|
||||
/*
|
||||
@ -433,8 +440,12 @@ int32_t M2VParser::FillQueues(){
|
||||
break;
|
||||
default: //B-frames
|
||||
if(firstRef == -1 || secondRef == -1){
|
||||
if(!m_gopHdr.closedGOP && !m_gopHdr.brokenLink && (0 < gopNum))
|
||||
mxerror(Y("Found B frame without second reference in a non closed GOP. Fix the MPEG2 video stream before attempting to multiplex it.\n"));
|
||||
if(!m_gopHdr.closedGOP && !m_gopHdr.brokenLink && (0 < gopNum)) {
|
||||
auto error = Y("Found B frame without second reference in a non closed GOP. Fix the MPEG2 video stream before attempting to multiplex it.\n");
|
||||
if (throwOnError)
|
||||
throw error;
|
||||
mxerror(error);
|
||||
}
|
||||
invisible = true;
|
||||
}
|
||||
PrepareFrame(chunk, myTime, picHdr);
|
||||
@ -468,3 +479,8 @@ M2VParser::AddTimecode(int64_t timecode) {
|
||||
idx++;
|
||||
m_timecodes.insert(idx, timecode);
|
||||
}
|
||||
|
||||
void
|
||||
M2VParser::SetThrowOnError(bool doThrow) {
|
||||
throwOnError = doThrow;
|
||||
}
|
||||
|
@ -90,6 +90,7 @@ private:
|
||||
MPEG2ParserState_e parserState;
|
||||
MPEGVideoBuffer * mpgBuf;
|
||||
std::list<int64_t> m_timecodes;
|
||||
bool throwOnError;
|
||||
|
||||
int32_t InitParser();
|
||||
void DumpQueues();
|
||||
@ -146,6 +147,8 @@ public:
|
||||
}
|
||||
|
||||
void AddTimecode(int64_t timecode);
|
||||
|
||||
void SetThrowOnError(bool doThrow);
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user