ccextractor源码解析架构

ccextractor是一个字幕提取工具,可以从mpeg文件中提取字幕。它支持HDTV、DVD和电视,可以进行搜索,兼容几乎所有的字幕文件格式。

int main(int argc, char *argv[])
{
    struct lib_ccx_ctx *ctx;
    struct lib_cc_decode *dec_ctx = NULL;
    int ret = 0, tmp;
    enum ccx_stream_mode_enum stream_mode;

    init_options (&ccx_options); //初始化选项配置结构体;

    parse_configuration(&ccx_options);
    //解析文件ccextractor.cnf里面的配置
    ret = parse_parameters (&ccx_options, argc, argv);
    //解析附加的额外参数;
    //初始化用到的demux
    ctx = init_libraries(&ccx_options);
    .........
#ifdef WITH_LIBCURL
    curl_global_init(CURL_GLOBAL_ALL);

    /* get a curl handle */
    curl = curl_easy_init();
    if (!curl)
    {
        curl_global_cleanup(); // Must be done even on init fail
        fatal (EXIT_NOT_CLASSIFIED, "Unable to init curl.");
    }
#endif

    int show_myth_banner = 0;

    params_dump(ctx);

    // default teletext page
    if (tlt_config.page > 0) {
        // dec to BCD, magazine pages numbers are in BCD (ETSI 300 706)
        tlt_config.page = ((tlt_config.page / 100) << 8) | (((tlt_config.page / 10) % 10) << 4) | (tlt_config.page % 10);
    }

    if (ccx_options.transcript_settings.xds)
    {
        if (ccx_options.write_format != CCX_OF_TRANSCRIPT)
        {
            ccx_options.transcript_settings.xds = 0;
            mprint ("Warning: -xds ignored, XDS can only be exported to transcripts at this time.\n");
        }
    }


    time_t start, final;
    time(&start);

    if (ccx_options.binary_concat)
    {
        ctx->total_inputsize=get_total_file_size(ctx);
        if (ctx->total_inputsize < 0)
        {
            switch (ctx->total_inputsize)
            {
            case -1*ENOENT:
                fatal(EXIT_NO_INPUT_FILES, "Failed to open file: File does not exist.");
            case -1*EACCES:
                fatal(EXIT_READ_ERROR, "Failed to open file: Unable to access");
            case -1*EINVAL:
                fatal(EXIT_READ_ERROR, "Failed to open file: Invalid opening flag.");
            case -1*EMFILE:
                fatal(EXIT_TOO_MANY_INPUT_FILES, "Failed to open file: Too many files are open.");
            default:
                fatal(EXIT_READ_ERROR, "Failed to open file: Reason unknown");
            }
        }
    }
    .....................
    terminate_asap = 0;

#ifdef ENABLE_SHARING
    if (ccx_options.translate_enabled && ctx->num_input_files > 1)
    {
        mprint("[share] WARNING: simultaneous translation of several input files is not supported yet\n");
        ccx_options.translate_enabled = 0;
        ccx_options.sharing_enabled = 0;
    }
    if (ccx_options.translate_enabled)
    {
        mprint("[share] launching translate service\n");
        ccx_share_launch_translator(ccx_options.translate_langs, ccx_options.translate_key);
    }
#endif //ENABLE_SHARING
    ret = 0;
    while (switch_to_next_file(ctx, 0))
    {
        prepare_for_new_file(ctx);
#ifdef ENABLE_SHARING
        if (ccx_options.sharing_enabled)
            ccx_share_start(ctx->basefilename);
#endif //ENABLE_SHARING

        stream_mode = ctx->demux_ctx->get_stream_mode(ctx->demux_ctx);
        // Disable sync check for raw formats - they have the right timeline.
        // Also true for bin formats, but -nosync might have created a
        // broken timeline for debug purposes.
        // Disable too in MP4, specs doesn't say that there can't be a jump
        switch (stream_mode)
        {
            case CCX_SM_MCPOODLESRAW:
            case CCX_SM_RCWT:
            case CCX_SM_MP4:
#ifdef WTV_DEBUG
            case CCX_SM_HEX_DUMP:
#endif
                ccx_common_timing_settings.disable_sync_check = 1;
                break;
            default:
                break;
        }
        /* -----------------------------------------------------------------
        主循环
        ----------------------------------------------------------------- */
        switch (stream_mode)
        {
            case CCX_SM_ELEMENTARY_OR_NOT_FOUND:
                if (!ccx_options.use_gop_as_pts) // If !0 then the user selected something
                    ccx_options.use_gop_as_pts = 1; // Force GOP timing for ES
                ccx_common_timing_settings.is_elementary_stream = 1;
            case CCX_SM_TRANSPORT:
            case CCX_SM_PROGRAM:
            case CCX_SM_ASF:
            case CCX_SM_WTV:
            case CCX_SM_GXF:
#ifdef ENABLE_FFMPEG
            case CCX_SM_FFMPEG:
#endif
                if (!ccx_options.use_gop_as_pts) // If !0 then the user selected something
                    ccx_options.use_gop_as_pts = 0;
                if (ccx_options.ignore_pts_jumps)
                    ccx_common_timing_settings.disable_sync_check = 1;
                mprint ("\rAnalyzing data in general mode\n");
                tmp = general_loop(ctx);
                if (!ret) ret = tmp;
                break;
            case CCX_SM_MCPOODLESRAW:
                mprint ("\rAnalyzing data in McPoodle raw mode\n");
                tmp = raw_loop(ctx);
                if (!ret) ret = tmp;
                break;
            case CCX_SM_RCWT:
                mprint ("\rAnalyzing data in CCExtractor's binary format\n");
                tmp = rcwt_loop(ctx);
                if (!ret) ret = tmp;
                break;
            case CCX_SM_MYTH:
                mprint ("\rAnalyzing data in MythTV mode\n");
                show_myth_banner = 1;
                tmp = myth_loop(ctx);
                if (!ret) ret = tmp;
                break;
            case CCX_SM_MP4:
                mprint ("\rAnalyzing data with GPAC (MP4 library)\n");
                close_input_file(ctx); // No need to have it open. GPAC will do it for us
                if (ctx->current_file == -1) // We don't have a file to open, must be stdin, and GPAC is incompatible with stdin
                {
                    fatal (EXIT_INCOMPATIBLE_PARAMETERS, "MP4 requires an actual file, it's not possible to read from a stream, including stdin.\n");
                }
                if(ccx_options.extract_chapters)
                {
                    tmp = dumpchapters(ctx, &ctx->mp4_cfg, ctx->inputfile[ctx->current_file]);
                }
                else
                {
                    tmp = processmp4(ctx, &ctx->mp4_cfg, ctx->inputfile[ctx->current_file]);
                }
                if (ccx_options.print_file_reports)
                    print_file_report(ctx);
                if (!ret) ret = tmp;
                break;
#ifdef WTV_DEBUG
            case CCX_SM_HEX_DUMP:
                close_input_file(ctx); // process_hex will open it in text mode
                process_hex (ctx, ctx->inputfile[0]);
                break;
#endif
            case CCX_SM_AUTODETECT:
                fatal(CCX_COMMON_EXIT_BUG_BUG, "Cannot be reached!");
                break;
        }

    return EXIT_OK;
}


这里写图片描述

发布了38 篇原创文章 · 获赞 5 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/zhiyanzhai563/article/details/78543740
今日推荐