0
点赞
收藏
分享

微信扫一扫

libass分析8-源码分析-libass处理event中{}的逻辑

犹大之窗 03-23 15:30 阅读 2
Author: wencoo
Blog:https://wencoo.blog.csdn.net/
Date: 22/03/2024
Email: jianwen056@aliyun.com
Wechat:wencoo824
QQ:1419440391
Details:

在这里插入图片描述

文章目录

目录

正文 或 背景

语法示例

Dialogue: 0,0:00:02.31,0:00:03.31,,Default,0,0,0,,{\fnAlibaba_PuHuiTi_2.0_75_SemiBold_75_SemiBold.ttf\fs250\an7\bord5\xshad5\yshad-5\3c&5151e4&\4c&3131ab&\fade(00,ff,00,3000,6000,7000,8000)\move(0,0,500,500,3000,8000)}测试测试

这个在最后文字前加{}内容来改变参数的逻辑在下面的函数中

parse_events

实现

// Parse event text. 解析事件文本。
// Fill render_priv->text_info. 填补render_priv - > text_info。
static bool parse_events(RenderContext *state, ASS_Event *event)
{
    TextInfo *text_info = state->text_info;
    ASS_Renderer *render_priv = state->renderer;

    char *p = event->Text, *q;

    // Event parsing. 事件解析。
    while (true) {
        ASS_StringView drawing_text = {NULL, 0};

        // get next char, executing style override 获取下一个字符,执行样式重写
        // this affects render_context 这影响render_context
        unsigned code = 0;
        while (*p) {
            if ((*p == '{') && (q = strchr(p, '}'))) {
                p = ass_parse_tags(state, p, q, 1., false);
                assert(*p == '}');
                p++;
            } else if (state->drawing_scale) {
                q = p;
                if (*p == '{')
                    q++;
                while ((*q != '{') && (*q != 0))
                    q++;
                drawing_text.str = p;
                drawing_text.len = q - p;
                code = 0xfffc; // object replacement character  对象替换字符
                p = q;
                break;
            } else {
                code = ass_get_next_char(state, &p);
                break;
            }
        }

        if (code == 0)
            break;

        // face could have been changed in get_next_char  Face可以在get_next_char中更改
        if (!state->font)
            goto fail;

        if (text_info->length >= text_info->max_glyphs) {
            // Raise maximum number of glyphs  提高字形的最大数量
            int new_max = 2 * FFMIN(FFMAX(text_info->max_glyphs, text_info->length / 2 + 1),
                                    INT_MAX / 2);
            if (text_info->length >= new_max)
                goto fail;
            if (!ASS_REALLOC_ARRAY(text_info->glyphs, new_max) ||
                    !ASS_REALLOC_ARRAY(text_info->event_text, new_max) ||
                    !ASS_REALLOC_ARRAY(text_info->breaks, new_max))
                goto fail;
            text_info->max_glyphs = new_max;
        }

        GlyphInfo *info = &text_info->glyphs[text_info->length];

        // Clear current GlyphInfo  清除当前的GlyphInfo
        memset(info, 0, sizeof(GlyphInfo));

        // Parse drawing 解析图
        if (drawing_text.str) {
            info->drawing_text = drawing_text;
            info->drawing_scale = state->drawing_scale;
            info->drawing_pbo = state->pbo;
        }

        // Fill glyph information  填写字形信息
        info->symbol = code;
        info->font = state->font;
        if (!drawing_text.str)
            ass_cache_inc_ref(info->font);
        for (int i = 0; i < 4; i++) {
            uint32_t clr = state->c[i];
            info->a_pre_fade[i] = _a(clr);
            ass_apply_fade(&clr, state->fade);
            info->c[i] = clr;
        }

        info->effect_type = state->effect_type;
        info->effect_timing = state->effect_timing;
        info->effect_skip_timing = state->effect_skip_timing;
        info->reset_effect = state->reset_effect;
        // VSFilter compatibility: font glyphs use PlayResY scaling in both dimensions  VSFilter兼容性:字体在两个维度上都使用PlayResY缩放
        info->font_size =
            fabs(state->font_size * state->screen_scale_y);
        info->be = state->be;
        info->blur = state->blur;
        info->shadow_x = state->shadow_x;
        info->shadow_y = state->shadow_y;
        info->scale_x = state->scale_x;
        info->scale_y = state->scale_y;
        info->border_style = state->border_style;
        info->border_x = state->border_x;
        info->border_y = state->border_y;
        info->hspacing = state->hspacing;
        info->bold = state->bold;
        info->italic = state->italic;
        info->flags = state->flags;
        if (info->font->desc.vertical && code >= VERTICAL_LOWER_BOUND)
            info->flags |= DECO_ROTATE;
        info->frx = state->frx;
        info->fry = state->fry;
        info->frz = state->frz;
        info->fax = state->fax;
        info->fay = state->fay;
        info->fade = state->fade;

        info->hspacing_scaled = 0;
        info->scale_fix = 1;

        if (!drawing_text.str) {
            info->hspacing_scaled = double_to_d6(info->hspacing *
                    state->screen_scale_x / render_priv->par_scale_x *
                    info->scale_x);
            fix_glyph_scaling(render_priv, info);
        }

        text_info->length++;

        state->effect_type = EF_NONE;
        state->effect_timing = 0;
        state->effect_skip_timing = 0;
        state->reset_effect = false;
    }

    return true;

fail:
    free_render_context(state);
    return false;
}

参考

由于笔者的水平有限, 加之编写的同时还要参与开发工作,文中难免会出现一些错误或者不准确的地方,恳请读者批评指正。如果读者有任何宝贵意见,可以加我微信 wencoo824。QQ:1419440391。

技术交流

欢迎加微信,搜索"wencoo824",进行技术交流,备注”博客音视频技术交流“

音视频领域其他技术文章的链接

opengl相关文章

  • opengl日记7-ubuntu20.04开发环境opengl拓展glfw和glad环境搭建
  • opengl日记8-opengl创建三角形
  • opengl日记9-opengl使用纹理示例
  • opengl日记10-opengl使用多个纹理示例
  • opengl日记11-opengl的transformtions变换示例
  • opengl日记12-opengl坐标系统
  • opengl日记19-opengl文字渲染-教程示例
  • opengl日记23-opengl文字渲染-渐变色-教程示例
  • opengl日记25-opengl文字渲染-渲染中文渐变色动画-直线线性运动-教程示例
  • opengl日记26-opengl文字渲染-渲染中文渐变色动画-贝塞尔运动-教程示例
  • opengl日记27-opengl报错ERROR::SHADER::PROGRAM::LINKING_FAILED
  • opengl日记28-opengl之c语言版本的glm库cglm编译使用教程

ffmpeg相关文章

  • ffmpeg学习日记1-ffmpeg的基本介绍(相关概念理解,资料收集)

  • ffmpeg学习日记2-新建工程打印ffmpeg版本

  • ffmpeg学习日记3-视频格式和视频编码的关系

  • ffmpeg学习日记4-使用ffmpeg获取视频文件属性值

  • ffmpeg学习日记5-使用ffmpeg进行h264解码

  • ffmpeg学习日记8-YUV的几个知识点

  • ffmpeg学习日记11-使用ffmpeg将视频格式转换为视频编码h264格式

  • ffmpeg学习日记17-获取MP4视频流的帧率

  • ffmpeg学习日记19-判断AVPacket中的一帧数据是否为关键帧

  • ffmpeg学习日记21-缓存AVPacket数据

  • ffmpeg学习日记22-内存读取avio_alloc_context函数的内存释放问题

  • ffmpeg学习日记29-使用vscode调试ffmpeg源码

  • ffmpeg学习日记101-视频-MP4提取YUV数据,每一帧保存为pgm图片

  • ffmpeg学习日记121-视频-各种图片转yuv

  • ffmpeg学习日记122-视频-获取视频的解码器,yuv格式名称,理解编码格式,封装格式,yuv格式的关系

  • ffmpeg学习日记122-视频-获取视频的解码器,yuv格式名称,理解编码格式,封装格式,yuv格式的关系

  • ffmpeg日记1011-过滤器-语法高阶,逻辑,函数使用

ffmpeg原理相关文章

  • ffmpeg日记4001-原理介绍-视频切割原理

ffmpeg源码分析相关文章

  • ffmpeg学习日记501-源码-parse_loglevel()函数
  • ffmpeg学习日记502-源码-ffmpeg_parse_options()函数分析
  • ffmpeg学习日记503-源码-transcode()函数分析
  • ffmpeg学习日记504-源码-readme汉化
  • ffmpeg学习日记506-源码-av_image_copy()函数分析及功能
  • ffmpeg学习日记508-源码-ffmpeg --help 汉化
  • ffmpeg学习日记509-源码-从ffmpeg 源码提取编码的流程分析
  • ffmpeg学习日记512-源码-ubuntu20.04下源码编译
  • ffmpeg学习日记513-源码-configure_filtergraph()函数分析及功能

ffmpeg指令相关文章

  • ffmpeg学习日记601-指令-视频裁剪,添加bgm合成mp4
  • ffmpeg学习日记602-指令-转换视频的分辨率
  • ffmpeg学习日记603-指令-获取视频分辨率
  • ffmpeg学习日记604-指令-将视频格式转为H264格式
  • ffmpeg学习日记605-指令-获取视频的总帧数
  • ffmpeg学习日记606-指令-将视频转为全I帧
  • ffmpeg学习日记607-指令-将mp4视频转yuv
  • ffmpeg学习日记612-指令-转换视频格式
  • ffmpeg学习日记612-指令-转换视频格式
  • ffmpeg学习日记614-指令-获取文件时长
  • ffmpeg学习日记619-指令-透明通道视频相关指令

ffmpeg报错相关文章

  • ffmpeg学习日记701-报错-co located POCs unavailable
  • ffmpeg学习日记702-报错-包含‘PRId64‘的报错

c/c++相关文章

  • c/c++专栏

linux相关文章

  • linux专栏

后面都是一些废话,不用看,刷分的

推广一个AI学习网站

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。

中国软件行业倡议书

精简软件开发,电脑性能越来越好,打出的程序安装包越来越大,磁盘,内存越吃越多,这不是好现象,大家觉得呢,欢迎发表看法,各抒己见。

作者有话说

个人简介:多年工作工程经验,擅长linux下软件开发,qt,ffmpeg音视频二次开发。

欢迎各位叨扰作者,如果有什么项目合作,创业合伙需要研发,网站推广等等,尽管来联系,对于能挣钱的事,作者可是很感兴趣的哦。

关于内卷

劝大家一句,不要内卷,内卷只能害了别人,害了自己。

举报

相关推荐

0 条评论