mirror of
https://github.com/CCExtractor/ccextractor.git
synced 2024-12-25 04:11:38 +00:00
Merge branch 'pr/n46_rkuchumov'
This commit is contained in:
commit
ac485d7984
11
src/608.c
11
src/608.c
@ -251,7 +251,6 @@ void write_char(const unsigned char c, struct s_context_cc608 *context)
|
||||
context->ts_start_of_current_line = get_fts();
|
||||
context->ts_last_char_received = get_fts();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Handle MID-ROW CODES. */
|
||||
@ -1208,6 +1207,14 @@ void process608(const unsigned char *data, int length, struct s_context_cc608 *c
|
||||
|
||||
// printf ("\r[%02X:%02X]\n",hi,lo);
|
||||
|
||||
if (hi>=0x10 && hi<=0x1e) {
|
||||
int ch = (hi<=0x17)? 1 : 2;
|
||||
if (current_field == 2)
|
||||
ch+=2;
|
||||
|
||||
file_report.cc_channels_608[ch - 1] = 1;
|
||||
}
|
||||
|
||||
if (hi >= 0x01 && hi <= 0x0E && (context == NULL || context->my_field == 2)) // XDS can only exist in field 2.
|
||||
{
|
||||
if (context)
|
||||
@ -1217,6 +1224,8 @@ void process608(const unsigned char *data, int length, struct s_context_cc608 *c
|
||||
ts_start_of_xds=get_fts();
|
||||
in_xds_mode=1;
|
||||
}
|
||||
|
||||
file_report.xds=1;
|
||||
}
|
||||
if (hi == 0x0F && in_xds_mode && (context == NULL || context->my_field == 2)) // End of XDS block
|
||||
{
|
||||
|
12
src/708.c
12
src/708.c
@ -1142,8 +1142,12 @@ void process_current_packet (void)
|
||||
pos = current_packet+len; // Move to end
|
||||
break;
|
||||
}
|
||||
if (service_number>0 && decoders[service_number-1].inited)
|
||||
process_service_block (&decoders[service_number-1], pos, block_length);
|
||||
|
||||
if (block_length != 0)
|
||||
file_report.services708[service_number] = 1;
|
||||
|
||||
if (service_number>0 && decoders[service_number-1].inited)
|
||||
process_service_block (&decoders[service_number-1], pos, block_length);
|
||||
|
||||
pos+=block_length; // Skip data
|
||||
}
|
||||
@ -1168,7 +1172,7 @@ void do_708 (const unsigned char *data, int datalength)
|
||||
1 byte for cc_valid
|
||||
1 byte for cc_type
|
||||
2 bytes for the actual data */
|
||||
if (!do_cea708)
|
||||
if (!do_cea708 && !ccx_options.print_file_reports)
|
||||
return;
|
||||
|
||||
for (int i=0;i<datalength;i+=4)
|
||||
@ -1214,7 +1218,7 @@ void do_708 (const unsigned char *data, int datalength)
|
||||
default:
|
||||
fatal (EXIT_BUG_BUG, "708: shouldn't be here - cc_type: %d\n", cc_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void init_708(void)
|
||||
|
@ -126,6 +126,7 @@ void init_options (struct ccx_s_options *options)
|
||||
options->sentence_cap_file=NULL; // Extra words file?
|
||||
options->live_stream=0; // 0 -> A regular file
|
||||
options->messages_target=1; // 1=stdout
|
||||
options->print_file_reports=0;
|
||||
/* Levenshtein's parameters, for string comparison */
|
||||
options->levdistmincnt=2; // Means 2 fails or less is "the same"...
|
||||
options->levdistmaxpct=10; // ...10% or less is also "the same"
|
||||
|
@ -42,6 +42,7 @@ struct ccx_s_options // Options from user parameters
|
||||
int nofontcolor;
|
||||
int notypesetting;
|
||||
struct ccx_boundary_time extraction_start, extraction_end; // Segment we actually process
|
||||
int print_file_reports;
|
||||
|
||||
/* subtitle codec type */
|
||||
enum cxx_code_type codec;
|
||||
@ -156,6 +157,22 @@ struct gop_time_code
|
||||
};
|
||||
|
||||
|
||||
/* Report information */
|
||||
#define SUB_STREAMS_CNT 10
|
||||
struct file_report_t
|
||||
{
|
||||
unsigned program_cnt;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
unsigned aspect_ratio;
|
||||
unsigned frame_rate;
|
||||
unsigned xds : 1;
|
||||
unsigned cc_channels_608[4];
|
||||
unsigned services708[63];
|
||||
unsigned dvb_sub_pid[SUB_STREAMS_CNT];
|
||||
unsigned tlt_sub_pid[SUB_STREAMS_CNT];
|
||||
} file_report;
|
||||
|
||||
|
||||
// Stuff for telcc.cpp
|
||||
struct ccx_s_teletext_config {
|
||||
@ -306,6 +323,7 @@ int processmp4 (char *file);
|
||||
|
||||
// params_dump.cpp
|
||||
void params_dump(void);
|
||||
void print_file_report(void);
|
||||
|
||||
// output.cpp
|
||||
void init_write (struct ccx_s_write *wb);
|
||||
@ -583,6 +601,9 @@ extern int timestamps_on_transcript;
|
||||
|
||||
extern unsigned teletext_mode;
|
||||
|
||||
#define MAX_TLT_PAGES 1000
|
||||
extern short int seen_sub_page[MAX_TLT_PAGES];
|
||||
|
||||
extern uint64_t utc_refvalue; // UTC referential value
|
||||
extern struct ccx_s_teletext_config tlt_config;
|
||||
extern uint32_t tlt_packet_counter;
|
||||
|
@ -398,6 +398,11 @@ static int sequence_header(struct bitstream *esstream)
|
||||
unsigned aspect_ratio = (unsigned) read_bits(esstream,4);
|
||||
unsigned frame_rate = (unsigned) read_bits(esstream,4);
|
||||
|
||||
file_report.width = hor_size;
|
||||
file_report.height = vert_size;
|
||||
file_report.aspect_ratio = aspect_ratio;
|
||||
file_report.frame_rate = frame_rate;
|
||||
|
||||
// Discard some information
|
||||
read_bits(esstream, 18+1+10+1);
|
||||
|
||||
|
@ -177,6 +177,9 @@ int switch_to_next_file (LLONG bytesinbuffer)
|
||||
/* Close current and make sure things are still sane */
|
||||
if (infd!=-1)
|
||||
{
|
||||
if (ccx_options.print_file_reports)
|
||||
print_file_report();
|
||||
|
||||
close_input_file ();
|
||||
if (inputsize>0 && ((past+bytesinbuffer) < inputsize) && !processed_enough)
|
||||
{
|
||||
|
20
src/params.c
20
src/params.c
@ -272,6 +272,12 @@ void set_output_format (const char *format)
|
||||
ccx_options.date_format=ODF_HHMMSSMS;
|
||||
timestamps_on_transcript=1;
|
||||
}
|
||||
else if (strcmp (format,"report")==0)
|
||||
{
|
||||
ccx_options.write_format=CCX_OF_NULL;
|
||||
ccx_options.messages_target=0;
|
||||
ccx_options.print_file_reports=1;
|
||||
}
|
||||
else if (strcmp (format,"raw")==0)
|
||||
ccx_options.write_format=CCX_OF_RAW;
|
||||
else if (strcmp (format, "smptett")==0)
|
||||
@ -396,11 +402,13 @@ void usage (void)
|
||||
mprint (" ttxt -> Timed Transcript (transcription with time\n");
|
||||
mprint (" info)\n");
|
||||
mprint (" smptett -> SMPTE Timed Text (W3C TTML) format.\n");
|
||||
mprint (" spupng -> Set of .xml and .png files for use with\n");
|
||||
mprint (" dvdauthor's spumux.\n");
|
||||
mprint (" See \"Notes on spupng output format\"\n");
|
||||
|
||||
mprint (" null -> Don't produce any file output\n\n");
|
||||
mprint (" spupng -> Set of .xml and .png files for use with\n");
|
||||
mprint (" dvdauthor's spumux.\n");
|
||||
mprint (" See \"Notes on spupng output format\"\n");
|
||||
mprint (" null -> Don't produce any file output\n");
|
||||
mprint (" report -> Prints to stdout information about captions");
|
||||
mprint (" in specified input. Don't produce any file");
|
||||
mprint (" output\n\n");
|
||||
mprint (" Note: Teletext output can only be srt, txt or ttxt for now.\n\n");
|
||||
|
||||
mprint ("Options that affect how input files will be processed.\n");
|
||||
@ -578,7 +586,7 @@ void usage (void)
|
||||
mprint (" If codec type is not selected then first elementry stream suitable for \n"
|
||||
" subtitle is selected, please consider -teletext -noteletext override this\n"
|
||||
" option.\n"
|
||||
" -cocdec dvbsub select the dvb subtitle from all elementry stream,\n"
|
||||
" -codec dvbsub select the dvb subtitle from all elementry stream,\n"
|
||||
" if stream of dvb subtitle type is not found then \n"
|
||||
" nothing is selected and no subtitle is generated\n"
|
||||
" -nocodec dvbsub ignore dvb subtitle and follow default behaviour\n"
|
||||
|
@ -200,3 +200,165 @@ void params_dump(void)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void print_file_report(void)
|
||||
{
|
||||
#define Y_N(cond) ((cond) ? "Yes" : "No")
|
||||
|
||||
printf("File: ");
|
||||
switch (ccx_options.input_source)
|
||||
{
|
||||
case CCX_DS_FILE:
|
||||
printf("%s\n", inputfile[current_file]);
|
||||
break;
|
||||
case CCX_DS_STDIN:
|
||||
printf("stdin\n");
|
||||
break;
|
||||
case CCX_DS_NETWORK:
|
||||
printf("network\n");
|
||||
break;
|
||||
}
|
||||
|
||||
printf("StreamMode: ");
|
||||
switch (stream_mode)
|
||||
{
|
||||
case CCX_SM_TRANSPORT:
|
||||
printf("transport_stream\n");
|
||||
|
||||
printf("ProgramCount: %d\n", file_report.program_cnt);
|
||||
|
||||
printf("ProgramNumbers: ");
|
||||
for (int i = 0; i < pmt_array_length; i++)
|
||||
{
|
||||
if (pmt_array[i].program_number == 0)
|
||||
continue;
|
||||
|
||||
printf("%u ", pmt_array[i].program_number);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
for (int i = 0; i < 65536; i++)
|
||||
{
|
||||
if (PIDs_programs[i] == 0)
|
||||
continue;
|
||||
|
||||
printf("PID: %u, Program: %u, ", i, PIDs_programs[i]->program_number);
|
||||
int j;
|
||||
for (j = 0; j < SUB_STREAMS_CNT; j++)
|
||||
{
|
||||
if (file_report.dvb_sub_pid[j] == i)
|
||||
{
|
||||
printf("DVB Subtitles\n");
|
||||
break;
|
||||
}
|
||||
if (file_report.tlt_sub_pid[j] == i)
|
||||
{
|
||||
printf("Teletext Subtitles\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == SUB_STREAMS_CNT)
|
||||
printf("%s\n", desc[PIDs_programs[i]->printable_stream_type]);
|
||||
}
|
||||
|
||||
break;
|
||||
case CCX_SM_PROGRAM:
|
||||
printf("program_stream\n");
|
||||
break;
|
||||
case CCX_SM_ASF:
|
||||
printf("ASF\n");
|
||||
break;
|
||||
case CCX_SM_WTV:
|
||||
printf("WTV\n");
|
||||
break;
|
||||
case CCX_SM_ELEMENTARY_OR_NOT_FOUND:
|
||||
printf("not_found\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (ccx_bufferdatatype == CCX_PES)
|
||||
{
|
||||
printf("Width: %u\n", file_report.width);
|
||||
printf("Height: %u\n", file_report.height);
|
||||
printf("AspectRatio: %s\n", aspect_ratio_types[file_report.aspect_ratio]);
|
||||
printf("FrameRate: %s\n", framerates_types[file_report.frame_rate]);
|
||||
}
|
||||
|
||||
if (file_report.program_cnt > 1)
|
||||
printf("//////// Program #%u: ////////\n", TS_program_number);
|
||||
|
||||
printf("DVB-Subtitles: ");
|
||||
int j;
|
||||
for (j = 0; j < SUB_STREAMS_CNT; j++)
|
||||
{
|
||||
unsigned pid = file_report.dvb_sub_pid[j];
|
||||
if (pid == 0)
|
||||
continue;
|
||||
if (PIDs_programs[pid]->program_number == TS_program_number)
|
||||
{
|
||||
printf("Yes\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == SUB_STREAMS_CNT)
|
||||
printf("No\n");
|
||||
|
||||
printf("Teletext: ");
|
||||
for (j = 0; j < SUB_STREAMS_CNT; j++)
|
||||
{
|
||||
unsigned pid = file_report.tlt_sub_pid[j];
|
||||
if (pid == 0)
|
||||
continue;
|
||||
if (PIDs_programs[pid]->program_number == TS_program_number)
|
||||
{
|
||||
printf("Yes\n");
|
||||
|
||||
printf("PagesWithSubtitles: ");
|
||||
for (int i = 0; i < MAX_TLT_PAGES; i++)
|
||||
{
|
||||
if (seen_sub_page[i] == 0)
|
||||
continue;
|
||||
|
||||
printf("%d ", i);
|
||||
}
|
||||
printf("\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == SUB_STREAMS_CNT)
|
||||
printf("No\n");
|
||||
|
||||
printf("EIA-608: %s\n", Y_N(cc_stats[0] > 0 || cc_stats[1] > 0));
|
||||
|
||||
if (cc_stats[0] > 0 || cc_stats[1] > 0)
|
||||
{
|
||||
printf("XDSPresent: %s\n", Y_N(file_report.xds));
|
||||
|
||||
printf("CC1: %s\n", Y_N(file_report.cc_channels_608[0]));
|
||||
printf("CC2: %s\n", Y_N(file_report.cc_channels_608[1]));
|
||||
printf("CC3: %s\n", Y_N(file_report.cc_channels_608[2]));
|
||||
printf("CC4: %s\n", Y_N(file_report.cc_channels_608[3]));
|
||||
}
|
||||
|
||||
printf("CEA-708: %s\n", Y_N(cc_stats[2] > 0 || cc_stats[3] > 0));
|
||||
|
||||
if (cc_stats[2] > 0 || cc_stats[3] > 0)
|
||||
{
|
||||
printf("Services: ");
|
||||
for (int i = 0; i < 63; i++)
|
||||
{
|
||||
if (file_report.services708[i] == 0)
|
||||
continue;
|
||||
printf("%d ", i);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("PrimaryLanguagePresent: %s\n", Y_N(file_report.services708[1]));
|
||||
|
||||
printf("SecondaryLanguagePresent: %s\n", Y_N(file_report.services708[2]));
|
||||
}
|
||||
|
||||
memset(&file_report, 0, sizeof (struct file_report_t));
|
||||
|
||||
#undef Y_N
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ static const char* TTXT_COLOURS[8] = {
|
||||
|
||||
#define MAX_TLT_PAGES 1000
|
||||
|
||||
static short int seen_sub_page[MAX_TLT_PAGES];
|
||||
short int seen_sub_page[MAX_TLT_PAGES];
|
||||
|
||||
// 1-byte alignment; just to be sure, this struct is being used for explicit type conversion
|
||||
// FIXME: remove explicit type conversion from buffer to structs
|
||||
|
@ -170,6 +170,65 @@ int parse_PMT (int pos)
|
||||
i += ES_info_length;
|
||||
}
|
||||
dbg_print(CCX_DMT_PMT, "---\n");
|
||||
|
||||
unsigned newcappid = 0;
|
||||
unsigned newcap_stream_type = 0;
|
||||
dbg_print(CCX_DMT_VERBOSE, "\nProgram map section (PMT)\n");
|
||||
|
||||
for (unsigned i=0; i < stream_data && (i+4)<payload_length; i+=5)
|
||||
{
|
||||
unsigned ccx_stream_type = payload_start[i];
|
||||
unsigned elementary_PID = (((payload_start[i+1] & 0x1F) << 8)
|
||||
| payload_start[i+2]);
|
||||
unsigned ES_info_length = (((payload_start[i+3] & 0x0F) << 8)
|
||||
| payload_start[i+4]);
|
||||
|
||||
if (!ccx_options.print_file_reports ||
|
||||
ccx_stream_type != CCX_STREAM_TYPE_PRIVATE_MPEG2 ||
|
||||
!ES_info_length)
|
||||
{
|
||||
i += ES_info_length;
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned char *es_info = payload_start + i + 5;
|
||||
for (desc_len = 0;(payload_start + i + 5 + ES_info_length) > es_info; es_info += desc_len)
|
||||
{
|
||||
enum ccx_mpeg_descriptor descriptor_tag = (enum ccx_mpeg_descriptor)(*es_info++);
|
||||
desc_len = (*es_info++);
|
||||
|
||||
if(descriptor_tag == CCX_MPEG_DSC_DVB_SUBTITLE)
|
||||
{
|
||||
int k = 0;
|
||||
for (int j = 0; j < SUB_STREAMS_CNT; j++) {
|
||||
if (file_report.dvb_sub_pid[i] == 0)
|
||||
k = j;
|
||||
if (file_report.dvb_sub_pid[i] == elementary_PID)
|
||||
{
|
||||
k = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
file_report.dvb_sub_pid[k] = elementary_PID;
|
||||
}
|
||||
if(IS_VALID_TELETEXT_DESC(descriptor_tag))
|
||||
{
|
||||
int k = 0;
|
||||
for (int j = 0; j < SUB_STREAMS_CNT; j++) {
|
||||
if (file_report.tlt_sub_pid[i] == 0)
|
||||
k = j;
|
||||
if (file_report.tlt_sub_pid[i] == elementary_PID)
|
||||
{
|
||||
k = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
file_report.tlt_sub_pid[k] = elementary_PID;
|
||||
}
|
||||
}
|
||||
i += ES_info_length;
|
||||
}
|
||||
|
||||
if (TS_program_number || !ccx_options.ts_autoprogram)
|
||||
{
|
||||
if( payload.pid != pmtpid)
|
||||
@ -188,10 +247,6 @@ int parse_PMT (int pos)
|
||||
}
|
||||
}
|
||||
|
||||
unsigned newcappid = 0;
|
||||
unsigned newcap_stream_type = 0;
|
||||
dbg_print(CCX_DMT_VERBOSE, "\nProgram map section (PMT)\n");
|
||||
|
||||
for( unsigned i=0; i < stream_data && (i+4)<payload_length; i+=5)
|
||||
{
|
||||
unsigned ccx_stream_type = payload_start[i];
|
||||
@ -216,7 +271,7 @@ int parse_PMT (int pos)
|
||||
ES_info_length )
|
||||
{
|
||||
unsigned char *es_info = payload_start + i + 5;
|
||||
for (desc_len = 0;(payload_start + i + 5 + ES_info_length) - es_info ;es_info += desc_len)
|
||||
for (desc_len = 0;(payload_start + i + 5 + ES_info_length) > es_info ;es_info += desc_len)
|
||||
{
|
||||
enum ccx_mpeg_descriptor descriptor_tag = (enum ccx_mpeg_descriptor)(*es_info++);
|
||||
desc_len = (*es_info++);
|
||||
@ -248,12 +303,12 @@ int parse_PMT (int pos)
|
||||
&& ES_info_length
|
||||
&& ccx_stream_type == CCX_STREAM_TYPE_PRIVATE_MPEG2) // MPEG-2 Packetized Elementary Stream packets containing private data
|
||||
{
|
||||
unsigned char *es_info = payload_start + i + 5;
|
||||
for (desc_len = 0;(payload_start + i + 5 + ES_info_length) - es_info ;es_info += desc_len)
|
||||
{
|
||||
enum ccx_mpeg_descriptor descriptor_tag = (enum ccx_mpeg_descriptor)(*es_info++);
|
||||
desc_len = (*es_info++);
|
||||
if(!IS_VALID_TELETEXT_DESC(descriptor_tag))
|
||||
unsigned char *es_info = payload_start + i + 5;
|
||||
for (desc_len = 0;(payload_start + i + 5 + ES_info_length) - es_info ;es_info += desc_len)
|
||||
{
|
||||
enum ccx_mpeg_descriptor descriptor_tag = (enum ccx_mpeg_descriptor)(*es_info++);
|
||||
desc_len = (*es_info++);
|
||||
if(!IS_VALID_TELETEXT_DESC(descriptor_tag))
|
||||
continue;
|
||||
telxcc_init();
|
||||
if (!ccx_options.ts_forced_cappid)
|
||||
@ -263,10 +318,11 @@ int parse_PMT (int pos)
|
||||
}
|
||||
ccx_options.teletext_mode =CCX_TXT_IN_USE;
|
||||
mprint ("VBI/teletext stream ID %u (0x%x) for SID %u (0x%x)\n",
|
||||
elementary_PID, elementary_PID, program_number, program_number);
|
||||
}
|
||||
elementary_PID, elementary_PID, program_number, program_number);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (ccx_options.teletext_mode==CCX_TXT_FORBIDDEN &&
|
||||
ccx_stream_type == CCX_STREAM_TYPE_PRIVATE_MPEG2) // MPEG-2 Packetized Elementary Stream packets containing private data
|
||||
{
|
||||
@ -452,19 +508,17 @@ int parse_PAT (void)
|
||||
unsigned ts_prog_map_pid = 0;
|
||||
dbg_print(CCX_DMT_PAT, "\nProgram association section (PAT)\n");
|
||||
|
||||
int temp=0;
|
||||
file_report.program_cnt=0;
|
||||
for( unsigned i=0; i < programm_data; i+=4)
|
||||
{
|
||||
unsigned program_number = ((payload_start[i] << 8)
|
||||
| payload_start[i+1]);
|
||||
if( !program_number )
|
||||
continue;
|
||||
temp++;
|
||||
if (temp>=2) // Found 2 programs, we don't need more
|
||||
break;
|
||||
file_report.program_cnt++;
|
||||
}
|
||||
|
||||
is_multiprogram = (temp>1);
|
||||
is_multiprogram = (file_report.program_cnt>1);
|
||||
|
||||
for( unsigned i=0; i < programm_data; i+=4)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user