diff --git a/src/lib_ccx/matroska.c b/src/lib_ccx/matroska.c index 231c1da5..5517e7c3 100644 --- a/src/lib_ccx/matroska.c +++ b/src/lib_ccx/matroska.c @@ -1,4 +1,4 @@ -#include "lib_ccx.h" +#include "lib_ccx.h" #include "utility.h" #include "matroska.h" #include "ccx_encoders_helpers.h" @@ -691,7 +691,8 @@ void parse_simple_block(struct matroska_ctx *mkv_ctx, ULLONG frame_timestamp) int is_avc = (track == mkv_ctx->avc_track_number); int is_hevc = (track == mkv_ctx->hevc_track_number); - if (!is_avc && !is_hevc) + int is_mpeg2 = (track == mkv_ctx->mpeg2_track_number); + if (!is_avc && !is_hevc && !is_mpeg2) { // Skip everything except AVC/HEVC tracks skip_bytes(file, len - 1); // 1 byte for track @@ -710,6 +711,8 @@ void parse_simple_block(struct matroska_ctx *mkv_ctx, ULLONG frame_timestamp) if (is_hevc) process_hevc_frame_mkv(mkv_ctx, frame); + else if (is_mpeg2) + process_mpeg2_frame_mkv(mkv_ctx, frame); else process_avc_frame_mkv(mkv_ctx, frame); @@ -723,6 +726,19 @@ static long bswap32(long v) return swapped; } +int process_mpeg2_frame_mkv(struct matroska_ctx *mkv_ctx, struct matroska_avc_frame frame) +{ + struct lib_cc_decode *dec_ctx = update_decoder_list(mkv_ctx->ctx); + struct encoder_ctx *enc_ctx = update_encoder_list(mkv_ctx->ctx); + // Set timing from frame timestamp + set_current_pts(dec_ctx->timing, frame.FTS * (MPEG_CLOCK_FREQ / 1000)); + set_fts(dec_ctx->timing); + // Use the existing MPEG-2 elementary stream processor (same as mp4.c and general_loop.c) + process_m2v(enc_ctx, dec_ctx, frame.data, frame.len, &mkv_ctx->dec_sub); + mkv_ctx->current_second = (int)(get_fts(dec_ctx->timing, dec_ctx->current_field) / 1000); + return 0; +} + int process_avc_frame_mkv(struct matroska_ctx *mkv_ctx, struct matroska_avc_frame frame) { int status = 0; @@ -940,6 +956,8 @@ void parse_segment_track_entry(struct matroska_ctx *mkv_ctx) mkv_ctx->avc_track_number = track_number; else if (strcmp((const char *)codec_id_string, (const char *)hevc_codec_id) == 0) mkv_ctx->hevc_track_number = track_number; + else if (strcmp((const char *)codec_id_string, (const char *)mpeg2_codec_id) == 0) + mkv_ctx->mpeg2_track_number = track_number; MATROSKA_SWITCH_BREAK(code, code_len); case MATROSKA_SEGMENT_TRACK_CODEC_PRIVATE: // We handle DVB's private data differently @@ -2042,6 +2060,7 @@ int matroska_loop(struct lib_ccx_ctx *ctx) memset(&mkv_ctx->dec_sub, 0, sizeof(mkv_ctx->dec_sub)); mkv_ctx->avc_track_number = -1; mkv_ctx->hevc_track_number = -1; + mkv_ctx->mpeg2_track_number = -1; matroska_parse(mkv_ctx); @@ -2055,6 +2074,7 @@ int matroska_loop(struct lib_ccx_ctx *ctx) int sentence_count = mkv_ctx->sentence_count; int avc_track_found = mkv_ctx->avc_track_number > -1; int hevc_track_found = mkv_ctx->hevc_track_number > -1; + int mpeg2_track_found = mkv_ctx->mpeg2_track_number > -1; int got_output = mkv_ctx->dec_sub.got_output; matroska_free_all(mkv_ctx); @@ -2068,10 +2088,12 @@ int matroska_loop(struct lib_ccx_ctx *ctx) mprint("Found AVC track. "); else if (hevc_track_found) mprint("Found HEVC track. "); + else if (mpeg2_track_found) + mprint("Found MPEG2 track. "); else - mprint("Found no AVC/HEVC track. "); + mprint("Found no AVC/HEVC/MPEG2 track. "); - if (got_output) + if (got_output || mpeg2_track_found) return 1; return sentence_count; } diff --git a/src/lib_ccx/matroska.h b/src/lib_ccx/matroska.h index 0a6dde7a..d5ebcd64 100644 --- a/src/lib_ccx/matroska.h +++ b/src/lib_ccx/matroska.h @@ -184,6 +184,7 @@ char *matroska_track_text_subtitle_id_extensions[] = { char *avc_codec_id = "V_MPEG4/ISO/AVC"; char *hevc_codec_id = "V_MPEGH/ISO/HEVC"; +char *mpeg2_codec_id = "V_MPEG2"; char *dvb_codec_id = "S_DVBSUB"; /* Messages */ @@ -247,6 +248,7 @@ struct matroska_ctx struct cc_subtitle dec_sub; int avc_track_number; // ID of AVC track. -1 if there is none int hevc_track_number; // ID of HEVC track. -1 if there is none + int mpeg2_track_number; // ID of MPEG2 track. -1 if there is none int sub_tracks_count; int block_index; int sentence_count; @@ -278,6 +280,7 @@ void parse_segment_cluster(struct matroska_ctx *mkv_ctx); void parse_simple_block(struct matroska_ctx *mkv_ctx, ULLONG frame_timestamp); int process_avc_frame_mkv(struct matroska_ctx *mkv_ctx, struct matroska_avc_frame frame); int process_hevc_frame_mkv(struct matroska_ctx *mkv_ctx, struct matroska_avc_frame frame); +int process_mpeg2_frame_mkv(struct matroska_ctx *mkv_ctx, struct matroska_avc_frame frame); void parse_segment_track_entry(struct matroska_ctx *mkv_ctx); void parse_private_codec_data(struct matroska_ctx *mkv_ctx, char *codec_id_string, ULLONG track_number, char *lang); void parse_segment_tracks(struct matroska_ctx *mkv_ctx);