mirror of
https://github.com/CCExtractor/ccextractor.git
synced 2024-12-24 11:53:25 +00:00
Added --analyzevideo
This commit is contained in:
parent
a842e1f7db
commit
d9796410bc
@ -6,7 +6,11 @@
|
||||
- New: Added build/installation script for .pkg.tar.xz (Arch Linux).
|
||||
- New: Added tarball generation script.
|
||||
- New: Added Autoconf build scripts for CCExtractor to generate makefiles.
|
||||
|
||||
- New: Added --analyzevideo. If present the video stream will be processed even if the
|
||||
subtitles are in a different stream. This is useful when we want video information
|
||||
(resolution, frame type, etc). -vides now implies this option too.
|
||||
[Note: Tentative - some possibly breaking changed were made for this, so if you
|
||||
use it validate results]
|
||||
|
||||
0.85b (2017-1-26)
|
||||
-----------------
|
||||
|
@ -69,6 +69,7 @@ void init_options (struct ccx_s_options *options)
|
||||
options->ocr_oem = 0; // By default, set Tesseract OEM mode OEM_TESSERACT_ONLY (0)
|
||||
options->mkvlang = NULL; // By default, all the languages are extracted
|
||||
options->ignore_pts_jumps = 1;
|
||||
options->analyze_video_stream = 0;
|
||||
|
||||
/*HardsubX related stuff*/
|
||||
options->hardsubx_ocr_mode = 0;
|
||||
|
@ -134,6 +134,7 @@ struct ccx_s_options // Options from user parameters
|
||||
char *ocrlang; // The name of the .traineddata file to be loaded with tesseract
|
||||
int ocr_oem; // The Tesseract OEM mode, could be 0 (default), 1 or 2
|
||||
char *mkvlang; // The name of the language stream for MKV
|
||||
int analyze_video_stream; // If 1, the video stream will be processed even if we're using a different one for subtitles.
|
||||
|
||||
/*HardsubX related stuff*/
|
||||
int hardsubx_ocr_mode;
|
||||
|
@ -242,7 +242,7 @@ static int es_video_sequence(struct lib_cc_decode *ctx, struct bitstream *esstre
|
||||
ctx->no_bitstream_error = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// Sequence header
|
||||
if (!ctx->in_pic_data && startcode == 0xB3)
|
||||
{
|
||||
if (!read_seq_info(ctx, esstream))
|
||||
@ -254,7 +254,7 @@ static int es_video_sequence(struct lib_cc_decode *ctx, struct bitstream *esstre
|
||||
ctx->saw_seqgoppic = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Group of pictures
|
||||
if (!ctx->in_pic_data && startcode == 0xB8)
|
||||
{
|
||||
if (!read_gop_info(ctx, esstream,sub))
|
||||
@ -266,7 +266,7 @@ static int es_video_sequence(struct lib_cc_decode *ctx, struct bitstream *esstre
|
||||
ctx->saw_seqgoppic = 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Picture
|
||||
if (!ctx->in_pic_data && startcode == 0x00)
|
||||
{
|
||||
if (!read_pic_info(ctx, esstream, sub))
|
||||
@ -679,6 +679,7 @@ static int gop_header(struct lib_cc_decode *ctx, struct bitstream *esstream, str
|
||||
// will point to where we want to restart after getting more.
|
||||
static int read_pic_info(struct lib_cc_decode *ctx, struct bitstream *esstream, struct cc_subtitle *sub)
|
||||
{
|
||||
char frame_type_to_char[] = { '?', 'I', 'P','B', 'D', '?', '?','?' };
|
||||
debug("Read PIC Info\n");
|
||||
|
||||
// We only get here after seeing that start code
|
||||
@ -728,10 +729,17 @@ static int read_pic_info(struct lib_cc_decode *ctx, struct bitstream *esstream,
|
||||
{
|
||||
set_fts(ctx->timing); // Initialize fts
|
||||
}
|
||||
|
||||
dbg_print(CCX_DMT_VIDES, " t:%d r:%d p:%d", ctx->top_field_first,
|
||||
/*
|
||||
dbg_print(CCX_DMT_VIDES, " frametype: %d (%c) t:%d r:%d p:%d", ctx->picture_coding_type,
|
||||
frame_type_to_char[ctx->picture_coding_type], ctx->top_field_first,
|
||||
ctx->repeat_first_field, ctx->progressive_frame);
|
||||
dbg_print(CCX_DMT_VIDES, " FTS: %s\n", print_mstime_static(get_fts(ctx->timing, ctx->current_field)));
|
||||
dbg_print(CCX_DMT_VIDES, " FTS: %lld (%s)\n", ctx->timing->current_pts,
|
||||
print_mstime_static(get_fts(ctx->timing, ctx->current_field)));
|
||||
*/
|
||||
if (ctx->picture_coding_type == 1) // Write I-Frame in ffprobe format for easy comparison
|
||||
{
|
||||
dbg_print(CCX_DMT_VIDES, "key_frame=1|pkt_pts=%lld|pict_type=I\n", ctx->timing->current_pts);
|
||||
}
|
||||
|
||||
// Set min_pts/sync_pts according to the current time stamp.
|
||||
// Use fts_at_gop_start as reference when a GOP header was seen
|
||||
|
@ -799,6 +799,7 @@ void segment_output_file(struct lib_ccx_ctx *ctx, struct lib_cc_decode *dec_ctx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int general_loop(struct lib_ccx_ctx *ctx)
|
||||
{
|
||||
struct lib_cc_decode *dec_ctx = NULL;
|
||||
@ -863,6 +864,7 @@ int general_loop(struct lib_ccx_ctx *ctx)
|
||||
{
|
||||
struct cap_info* cinfo = NULL;
|
||||
struct encoder_ctx *enc_ctx = NULL;
|
||||
// Find most promising stream: teletext, DVB, ISDB, ATSC, in that order
|
||||
int pid = get_best_stream(ctx->demux_ctx);
|
||||
if(pid < 0)
|
||||
{
|
||||
@ -873,6 +875,39 @@ int general_loop(struct lib_ccx_ctx *ctx)
|
||||
ignore_other_stream(ctx->demux_ctx, pid);
|
||||
data_node = get_data_stream(datalist, pid);
|
||||
}
|
||||
if (ccx_options.analyze_video_stream)
|
||||
{
|
||||
int video_pid= get_video_stream(ctx->demux_ctx);
|
||||
if (video_pid != pid && video_pid!=-1)
|
||||
{
|
||||
struct cap_info* cinfo_video = get_cinfo(ctx->demux_ctx, pid); // Must be pid, not video_pid or DVB crashes (possibly buffer consumption?) - TODO
|
||||
struct lib_cc_decode *dec_ctx_video = update_decoder_list_cinfo(ctx, cinfo_video);
|
||||
struct cc_subtitle *dec_sub_video = &dec_ctx_video->dec_sub;
|
||||
struct demuxer_data *data_node_video = get_data_stream(datalist, video_pid);
|
||||
if (data_node_video)
|
||||
{
|
||||
if (data_node_video->pts != CCX_NOPTS)
|
||||
{
|
||||
struct ccx_rational tb = { 1,MPEG_CLOCK_FREQ };
|
||||
LLONG pts;
|
||||
if (data_node_video->tb.num != 1 || data_node_video->tb.den != MPEG_CLOCK_FREQ)
|
||||
{
|
||||
pts = change_timebase(data_node_video->pts, data_node_video->tb, tb);
|
||||
}
|
||||
else
|
||||
pts = data_node_video->pts;
|
||||
set_current_pts(dec_ctx_video->timing, pts);
|
||||
set_fts(dec_ctx_video->timing);
|
||||
}
|
||||
size_t got = process_m2v(dec_ctx_video, data_node_video->buffer, data_node_video->len, dec_sub_video);
|
||||
if (got > 0)
|
||||
{
|
||||
memmove(data_node_video->buffer, data_node_video->buffer + got, (size_t)(data_node_video->len - got));
|
||||
data_node_video->len -= got;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cinfo = get_cinfo(ctx->demux_ctx, pid);
|
||||
enc_ctx = update_encoder_list_cinfo(ctx, cinfo);
|
||||
|
@ -1877,6 +1877,12 @@ int parse_parameters (struct ccx_s_options *opt, int argc, char *argv[])
|
||||
if (strcmp (argv[i],"-vides")==0)
|
||||
{
|
||||
opt->debug_mask |= CCX_DMT_VIDES;
|
||||
opt->analyze_video_stream = 1;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(argv[i], "-anvid") == 0 || strcmp(argv[i], "--analyzevideo") == 0)
|
||||
{
|
||||
opt->analyze_video_stream = 1;
|
||||
continue;
|
||||
}
|
||||
if (strcmp (argv[i],"-xds")==0)
|
||||
|
@ -578,7 +578,8 @@ int copy_payload_to_capbuf(struct cap_info *cinfo, struct ts_payload *payload)
|
||||
{
|
||||
int newcapbuflen;
|
||||
|
||||
if(cinfo->ignore == CCX_TRUE)
|
||||
if(cinfo->ignore == CCX_TRUE &&
|
||||
(cinfo->stream != CCX_STREAM_TYPE_VIDEO_MPEG2 || !ccx_options.analyze_video_stream))
|
||||
{
|
||||
return CCX_OK;
|
||||
}
|
||||
@ -914,7 +915,8 @@ long ts_readstream(struct ccx_demuxer *ctx, struct demuxer_data **data)
|
||||
look_for_caption_data (ctx, &payload);
|
||||
continue;
|
||||
}
|
||||
else if (cinfo->ignore)
|
||||
else if (cinfo->ignore == CCX_TRUE &&
|
||||
(cinfo->stream != CCX_STREAM_TYPE_VIDEO_MPEG2 || !ccx_options.analyze_video_stream))
|
||||
{
|
||||
if(cinfo->codec_private_data)
|
||||
{
|
||||
|
@ -97,6 +97,17 @@ void ignore_other_sib_stream(struct cap_info* head, int pid)
|
||||
}
|
||||
}
|
||||
|
||||
int get_video_stream(struct ccx_demuxer *ctx)
|
||||
{
|
||||
struct cap_info* iter;
|
||||
list_for_each_entry(iter, &ctx->cinfo_tree.all_stream, all_stream, struct cap_info)
|
||||
{
|
||||
if (iter->stream == CCX_STREAM_TYPE_VIDEO_MPEG2)
|
||||
return iter->pid;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int get_best_stream(struct ccx_demuxer *ctx)
|
||||
{
|
||||
struct cap_info* iter;
|
||||
|
@ -133,7 +133,7 @@ int parse_PMT (struct ccx_demuxer *ctx, unsigned char *buf, int len, struct pro
|
||||
}
|
||||
else if (table_id == 0xC1)
|
||||
{
|
||||
//SCTE 57 2003
|
||||
//SCTE 57 2003
|
||||
dbg_print(CCX_DMT_PARSE, "PMT: PROGRAM NAME Table need implementation");
|
||||
unsigned c0length = (buf[1] << 8 | buf[2]) & 0xFFF; // 12 bytes
|
||||
dbg_print(CCX_DMT_PARSE, "Program name message length: %u", c0length);
|
||||
|
Loading…
Reference in New Issue
Block a user