Added --analyzevideo

This commit is contained in:
Carlos Fernandez 2017-06-02 12:32:45 -07:00
parent a842e1f7db
commit d9796410bc
9 changed files with 78 additions and 10 deletions

View File

@ -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)
-----------------

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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)

View File

@ -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)
{

View File

@ -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;

View File

@ -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);