diff --git a/src/lib_ccx/ccx_demuxer.c b/src/lib_ccx/ccx_demuxer.c index a6c79b63..315d70f4 100644 --- a/src/lib_ccx/ccx_demuxer.c +++ b/src/lib_ccx/ccx_demuxer.c @@ -302,6 +302,13 @@ struct ccx_demuxer *init_demuxer(void *parent, struct demuxer_cfg *cfg) ctx->nb_program = 0; ctx->multi_stream_per_prog = 0; + for (int i = 0; i < MAX_PROGRAM; i++) + { + ctx->pinfo[i].has_all_min_pts = 0; + memset(ctx->pinfo[i].got_important_streams_min_pts, UINT64_MAX, COUNT * sizeof(uint64_t)); + ctx->pinfo[i].initialized_ocr = 0; + } + if(cfg->ts_forced_program != -1) { ctx->pinfo[ctx->nb_program].pid = CCX_UNKNOWN; diff --git a/src/lib_ccx/ccx_demuxer.h b/src/lib_ccx/ccx_demuxer.h index 9acfe234..01a5df79 100644 --- a/src/lib_ccx/ccx_demuxer.h +++ b/src/lib_ccx/ccx_demuxer.h @@ -35,6 +35,7 @@ struct program_info { int pid; int program_number; + int initialized_ocr; // Avoid initializing the OCR more than once uint8_t analysed_PMT_once:1; uint8_t version; uint8_t saved_section[1021]; diff --git a/src/lib_ccx/dvb_subtitle_decoder.c b/src/lib_ccx/dvb_subtitle_decoder.c index e4f6d3a2..e00adbe6 100644 --- a/src/lib_ccx/dvb_subtitle_decoder.c +++ b/src/lib_ccx/dvb_subtitle_decoder.c @@ -86,99 +86,6 @@ const uint8_t crop_tab[256 + 2 * MAX_NEG_CROP] = { times256(0x00), 0x00, 0x01, #define cm (crop_tab + MAX_NEG_CROP) - -static __inline unsigned int bytestream_get_byte(const uint8_t **b) -{ - (*b) += 1; - return ((const uint8_t*) (*b - 1))[0]; -} - -static __inline unsigned int bytestream_get_be16(const uint8_t **b) -{ - (*b) += 2; - return RB16(*b - 2); -} -typedef struct GetBitContext -{ - const uint8_t *buffer, *buffer_end; - int index; - int size_in_bits; - int size_in_bits_plus8; -} GetBitContext; - -/** - * Initialize GetBitContext. - * @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes - * larger than the actual read bits because some optimized bitstream - * readers read 32 or 64 bit at once and could read over the end - * @param bit_size the size of the buffer in bits - * @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow. - */ -static __inline int init_get_bits(GetBitContext *s, const uint8_t *buffer, - int bit_size) -{ - int buffer_size; - int ret = 0; - - if (bit_size >= INT_MAX - 7 || bit_size < 0 || !buffer) - { - buffer_size = bit_size = 0; - buffer = NULL; - ret = -1; - errno = EINVAL; - } - - buffer_size = (bit_size + 7) >> 3; - - s->buffer = buffer; - s->size_in_bits = bit_size; - s->size_in_bits_plus8 = bit_size + 8; - s->buffer_end = buffer + buffer_size; - s->index = 0; - - return ret; -} - -static __inline int get_bits_count(const GetBitContext *s) -{ - return s->index; -} - -static __inline unsigned int get_bits(GetBitContext *s, int n) -{ - register int tmp; - unsigned int re_index = s->index; - unsigned int re_cache = 0; - unsigned int re_size_plus8 = s->size_in_bits_plus8; - - if (n <= 0 || n > 25) - return -1; - re_cache = RB32( s->buffer + (re_index >> 3 )) << (re_index & 7); - - tmp = ((uint32_t) re_cache) >> (32 - n); - - re_index = ( - (re_size_plus8 < re_index + (n)) ? - (re_size_plus8) : (re_index + (n))); - - s->index = re_index; - return tmp; -} -static __inline unsigned int get_bits1(GetBitContext *s) -{ - unsigned int index = s->index; - uint8_t result = s->buffer[index >> 3]; - - result <<= index & 7; - result >>= 8 - 1; - - if (s->index < s->size_in_bits_plus8) - index++; - s->index = index; - - return result; -} - #define RGBA(r,g,b,a) (((unsigned)(a) << 24) | ((r) << 16) | ((g) << 8) | (b)) typedef struct DVBSubCLUT @@ -284,6 +191,100 @@ typedef struct DVBSubContext DVBSubDisplayDefinition *display_definition; } DVBSubContext; +static __inline unsigned int bytestream_get_byte(const uint8_t **b) +{ + (*b) += 1; + return ((const uint8_t*) (*b - 1))[0]; +} + +static __inline unsigned int bytestream_get_be16(const uint8_t **b) +{ + (*b) += 2; + return RB16(*b - 2); +} +typedef struct GetBitContext +{ + const uint8_t *buffer, *buffer_end; + int index; + int size_in_bits; + int size_in_bits_plus8; +} GetBitContext; + +/** + * Initialize GetBitContext. + * @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes + * larger than the actual read bits because some optimized bitstream + * readers read 32 or 64 bit at once and could read over the end + * @param bit_size the size of the buffer in bits + * @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow. + */ +static __inline int init_get_bits(GetBitContext *s, const uint8_t *buffer, + int bit_size) +{ + int buffer_size; + int ret = 0; + + if (bit_size >= INT_MAX - 7 || bit_size < 0 || !buffer) + { + buffer_size = bit_size = 0; + buffer = NULL; + ret = -1; + errno = EINVAL; + } + + buffer_size = (bit_size + 7) >> 3; + + s->buffer = buffer; + s->size_in_bits = bit_size; + s->size_in_bits_plus8 = bit_size + 8; + s->buffer_end = buffer + buffer_size; + s->index = 0; + + return ret; +} + +static __inline int get_bits_count(const GetBitContext *s) +{ + return s->index; +} + +static __inline unsigned int get_bits(GetBitContext *s, int n) +{ + register int tmp; + unsigned int re_index = s->index; + unsigned int re_cache = 0; + unsigned int re_size_plus8 = s->size_in_bits_plus8; + + if (n <= 0 || n > 25) + return -1; + re_cache = RB32( s->buffer + (re_index >> 3 )) << (re_index & 7); + + tmp = ((uint32_t) re_cache) >> (32 - n); + + re_index = ( + (re_size_plus8 < re_index + (n)) ? + (re_size_plus8) : (re_index + (n))); + + s->index = re_index; + return tmp; +} +static __inline unsigned int get_bits1(GetBitContext *s) +{ + unsigned int index = s->index; + uint8_t result = s->buffer[index >> 3]; + + result <<= index & 7; + result >>= 8 - 1; + + if (s->index < s->size_in_bits_plus8) + index++; + s->index = index; + + return result; +} + + + static DVBSubObject* get_object(DVBSubContext *ctx, int object_id) { DVBSubObject *ptr = ctx->object_list; @@ -423,7 +424,7 @@ static void delete_regions(DVBSubContext *ctx) * @return DVB context kept as void* for abstraction * */ -void* dvbsub_init_decoder(struct dvb_config* cfg) +void* dvbsub_init_decoder(struct dvb_config* cfg, int initialized_ocr) { int i, r, g, b, a = 0; DVBSubContext *ctx = (DVBSubContext*) malloc(sizeof(DVBSubContext)); @@ -443,7 +444,8 @@ void* dvbsub_init_decoder(struct dvb_config* cfg) } #ifdef ENABLE_OCR - ctx->ocr_ctx = init_ocr(ctx->lang_index); + if (!initialized_ocr) + ctx->ocr_ctx = init_ocr(ctx->lang_index); #endif ctx->version = -1; diff --git a/src/lib_ccx/dvb_subtitle_decoder.h b/src/lib_ccx/dvb_subtitle_decoder.h index 4cdf9a34..6996abf7 100644 --- a/src/lib_ccx/dvb_subtitle_decoder.h +++ b/src/lib_ccx/dvb_subtitle_decoder.h @@ -1,17 +1,17 @@ /* - * DVB subtitle decoding - * Copyright (c) 2014 Anshul - * License: LGPL - * - * This file is part of CCEXtractor - * You should have received a copy of the GNU Lesser General Public - * License along with CCExtractor; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ +* DVB subtitle decoding +* Copyright (c) 2014 Anshul +* License: LGPL +* +* This file is part of CCEXtractor +* You should have received a copy of the GNU Lesser General Public +* License along with CCExtractor; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +*/ /** - * @file dvbsub.c - */ +* @file dvbsub.c +*/ #ifndef DVBSUBDEC_H #define DVBSUBDEC_H @@ -24,64 +24,64 @@ extern "C" { #endif -struct dvb_config -{ - unsigned char n_language; - unsigned int lang_index[MAX_LANGUAGE_PER_DESC]; - /* subtitle type */ - unsigned char sub_type[MAX_LANGUAGE_PER_DESC]; - /* composition page id */ - unsigned short composition_id[MAX_LANGUAGE_PER_DESC]; - /* ancillary_page_id */ - unsigned short ancillary_id[MAX_LANGUAGE_PER_DESC]; -}; + struct dvb_config + { + unsigned char n_language; + unsigned int lang_index[MAX_LANGUAGE_PER_DESC]; + /* subtitle type */ + unsigned char sub_type[MAX_LANGUAGE_PER_DESC]; + /* composition page id */ + unsigned short composition_id[MAX_LANGUAGE_PER_DESC]; + /* ancillary_page_id */ + unsigned short ancillary_id[MAX_LANGUAGE_PER_DESC]; + }; -/** - * @param cfg Structure containg configuration - * - * @return DVB context kept as void* for abstraction - * - */ -void* dvbsub_init_decoder(struct dvb_config* cfg); + /** + * @param cfg Structure containg configuration + * + * @return DVB context kept as void* for abstraction + * + */ + void* dvbsub_init_decoder(struct dvb_config* cfg, int initialized_ocr); -int dvbsub_close_decoder(void **dvb_ctx); + int dvbsub_close_decoder(void **dvb_ctx); -/** - * @param dvb_ctx PreInitialized DVB context using DVB - * @param buf buffer containing segment data, first sync byte need to 0x0f. - * does not include data_identifier and subtitle_stream_id. - * @param buf_size size of buf buffer - * @param sub output subtitle data - * - * @return -1 on error - */ -int dvbsub_decode(struct encoder_ctx *enc_ctx, struct lib_cc_decode *dec_ctx, const unsigned char *buf, int buf_size, struct cc_subtitle *sub); + /** + * @param dvb_ctx PreInitialized DVB context using DVB + * @param buf buffer containing segment data, first sync byte need to 0x0f. + * does not include data_identifier and subtitle_stream_id. + * @param buf_size size of buf buffer + * @param sub output subtitle data + * + * @return -1 on error + */ + int dvbsub_decode(struct encoder_ctx *enc_ctx, struct lib_cc_decode *dec_ctx, const unsigned char *buf, int buf_size, struct cc_subtitle *sub); -/** - * @func parse_dvb_description - * - * data pointer to this function should be after description length and description tag is parsed - * - * @param cfg preallocated dvb_config structure where parsed description will be stored,Not to be NULL - * - * @return return -1 if invalid data found other wise 0 if everything goes well - * errno is set is to EINVAL if invalid data is found - */ -int parse_dvb_description(struct dvb_config* cfg, unsigned char*data, + /** + * @func parse_dvb_description + * + * data pointer to this function should be after description length and description tag is parsed + * + * @param cfg preallocated dvb_config structure where parsed description will be stored,Not to be NULL + * + * @return return -1 if invalid data found other wise 0 if everything goes well + * errno is set is to EINVAL if invalid data is found + */ + int parse_dvb_description(struct dvb_config* cfg, unsigned char*data, unsigned int len); -/* - * @func dvbsub_set_write the output structure in dvb - * set ccx_s_write structure in dvb_ctx - * - * @param dvb_ctx context of dvb which was returned by dvbsub_init_decoder - * - * @param out output context returned by init_write - * - */ -void dvbsub_set_write(void *dvb_ctx, struct ccx_s_write *out); + /* + * @func dvbsub_set_write the output structure in dvb + * set ccx_s_write structure in dvb_ctx + * + * @param dvb_ctx context of dvb which was returned by dvbsub_init_decoder + * + * @param out output context returned by init_write + * + */ + void dvbsub_set_write(void *dvb_ctx, struct ccx_s_write *out); #ifdef __cplusplus } #endif -#endif +#endif \ No newline at end of file diff --git a/src/lib_ccx/ts_info.c b/src/lib_ccx/ts_info.c index bf7d4766..add97742 100644 --- a/src/lib_ccx/ts_info.c +++ b/src/lib_ccx/ts_info.c @@ -159,7 +159,7 @@ static void* init_private_data(enum ccx_code_type codec) case CCX_CODEC_TELETEXT: return telxcc_init(); case CCX_CODEC_DVB: - return dvbsub_init_decoder(NULL); + return dvbsub_init_decoder(NULL, 0); default: return NULL; } diff --git a/src/lib_ccx/ts_tables.c b/src/lib_ccx/ts_tables.c index 3639bed4..1057f103 100644 --- a/src/lib_ccx/ts_tables.c +++ b/src/lib_ccx/ts_tables.c @@ -351,7 +351,9 @@ int parse_PMT (struct ccx_demuxer *ctx, unsigned char *buf, int len, struct pro ret = parse_dvb_description(&cnf,es_info,desc_len); if(ret < 0) break; - ptr = dvbsub_init_decoder(&cnf); + ptr = dvbsub_init_decoder(&cnf, pinfo->initialized_ocr); + if(!pinfo->initialized_ocr) + pinfo->initialized_ocr = 1; if (ptr == NULL) break; update_capinfo(ctx, elementary_PID, stream_type, CCX_CODEC_DVB, program_number, ptr); @@ -574,9 +576,9 @@ int parse_PAT (struct ccx_demuxer *ctx) /* fatal(CCX_COMMON_EXIT_BUG_BUG, "Sorry, long PATs not yet supported!\n"); */ } - + if (ctx->last_pat_payload != NULL && payload_length == ctx->last_pat_length && - !memcmp (payload_start, ctx->last_pat_payload, payload_length)) + !memcmp(payload_start, ctx->last_pat_payload, payload_length)) { // dbg_print(CCX_DMT_PAT, "PAT hasn't changed, skipping.\n"); return CCX_OK;