Пример #1
0
def parallel_playback(cfg,
                      fast=True,
                      segment_time=2.0,
                      constrained_timeranges=False):
    """
    Parallel media playback, flipping between the two sources.

    The fast version makes sure the textures continue to be updated even though
    they are not displayed. On the other hand, the slow version will update the
    textures only when needed to be displayed, causing potential seek in the
    underlying media, and thus undesired delays.
    """
    m1 = ngl.Media(cfg.medias[0].filename, label="media #1")
    m2 = ngl.Media(cfg.medias[0].filename, label="media #2")

    t1 = ngl.Texture2D(data_src=m1, label="texture #1")
    t2 = ngl.Texture2D(data_src=m2, label="texture #2")

    render1 = ngl.RenderTexture(t1)
    render2 = ngl.RenderTexture(t2)

    text_settings = {
        "box_corner": (-1, 1 - 0.2, 0),
        "box_height": (0, 0.2, 0),
        "aspect_ratio": cfg.aspect_ratio,
    }
    render1 = ngl.Group(children=(render1,
                                  ngl.Text("media #1", **text_settings)))
    render2 = ngl.Group(children=(render2,
                                  ngl.Text("media #2", **text_settings)))

    rf1 = ngl.TimeRangeFilter(render1)
    rf2 = ngl.TimeRangeFilter(render2)

    if constrained_timeranges:
        rf1.set_prefetch_time(segment_time / 3.0)
        rf2.set_prefetch_time(segment_time / 3.0)
        rf1.set_max_idle_time(segment_time / 2.0)
        rf2.set_max_idle_time(segment_time / 2.0)

    t = 0
    rr1 = []
    rr2 = []
    while t < cfg.duration:
        rr1.append(ngl.TimeRangeModeCont(t))
        rr1.append(ngl.TimeRangeModeNoop(t + segment_time))

        rr2.append(ngl.TimeRangeModeNoop(t))
        rr2.append(ngl.TimeRangeModeCont(t + segment_time))

        t += 2 * segment_time

    rf1.add_ranges(*rr1)
    rf2.add_ranges(*rr2)

    g = ngl.Group()
    g.add_children(rf1, rf2)
    if fast:
        g.add_children(t1, t2)
    return g
Пример #2
0
def simple_transition(cfg, transition_start=2, transition_duration=4):
    """Fading transition between two medias"""

    cfg.duration = transition_start * 2 + transition_duration

    vertex = cfg.get_vert("dual-tex")
    fragment = cfg.get_frag("tex-mix")

    q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    p1_2 = ngl.Program(vertex=vertex, fragment=fragment)
    p1_2.update_vert_out_vars(var_tex0_coord=ngl.IOVec2(),
                              var_tex1_coord=ngl.IOVec2())

    m1 = ngl.Media(cfg.medias[0].filename, label="media #1")
    m2 = ngl.Media(cfg.medias[1 % len(cfg.medias)].filename, label="media #2")

    animkf_m2 = [
        ngl.AnimKeyFrameFloat(transition_start, 0),
        ngl.AnimKeyFrameFloat(transition_start + cfg.duration, cfg.duration),
    ]
    m2.set_time_anim(ngl.AnimatedTime(animkf_m2))

    t1 = ngl.Texture2D(data_src=m1, label="texture #1")
    t2 = ngl.Texture2D(data_src=m2, label="texture #2")

    render1 = ngl.RenderTexture(t1, label="render #1")
    render2 = ngl.RenderTexture(t2, label="render #2")

    delta_animkf = [
        ngl.AnimKeyFrameFloat(transition_start, 1.0),
        ngl.AnimKeyFrameFloat(transition_start + transition_duration, 0.0),
    ]
    delta = ngl.AnimatedFloat(delta_animkf)

    render1_2 = ngl.Render(q, p1_2, label="transition")
    render1_2.update_frag_resources(tex0=t1, tex1=t2)
    render1_2.update_frag_resources(delta=delta)

    rr1 = []
    rr2 = []
    rr1_2 = []

    rr1.append(ngl.TimeRangeModeNoop(transition_start))

    rr2.append(ngl.TimeRangeModeNoop(0))
    rr2.append(ngl.TimeRangeModeCont(transition_start + transition_duration))

    rr1_2.append(ngl.TimeRangeModeNoop(0))
    rr1_2.append(ngl.TimeRangeModeCont(transition_start))
    rr1_2.append(ngl.TimeRangeModeNoop(transition_start + transition_duration))

    rf1 = ngl.TimeRangeFilter(render1, ranges=rr1)
    rf2 = ngl.TimeRangeFilter(render2, ranges=rr2)
    rf1_2 = ngl.TimeRangeFilter(render1_2, ranges=rr1_2)

    g = ngl.Group()
    g.add_children(rf1, rf1_2, rf2)

    return g
Пример #3
0
def simple_transition(cfg, transition_start=2, transition_duration=4):
    '''Fading transition between two medias'''

    cfg.duration = transition_start * 2 + transition_duration

    vertex = cfg.get_vert('dual-tex')
    fragment = cfg.get_frag('tex-mix')

    q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    p1_2 = ngl.Program(vertex=vertex, fragment=fragment)

    m1 = ngl.Media(cfg.medias[0].filename, label='media #1')
    m2 = ngl.Media(cfg.medias[1 % len(cfg.medias)].filename, label='media #2')

    animkf_m2 = [ngl.AnimKeyFrameFloat(transition_start, 0)]
    m2.set_time_anim(ngl.AnimatedTime(animkf_m2))

    t1 = ngl.Texture2D(data_src=m1, label='texture #1')
    t2 = ngl.Texture2D(data_src=m2, label='texture #2')

    program = ngl.Program(vertex=cfg.get_vert('texture'),
                          fragment=cfg.get_frag('texture'))
    render1 = ngl.Render(q, program, label='render #1')
    render1.update_textures(tex0=t1)
    render2 = ngl.Render(q, program, label='render #2')
    render2.update_textures(tex0=t2)

    delta_animkf = [
        ngl.AnimKeyFrameFloat(transition_start, 1.0),
        ngl.AnimKeyFrameFloat(transition_start + transition_duration, 0.0)
    ]
    delta = anim = ngl.AnimatedFloat(delta_animkf)

    render1_2 = ngl.Render(q, p1_2, label='transition')
    render1_2.update_textures(tex0=t1, tex1=t2)
    render1_2.update_uniforms(delta=delta)

    rr1 = []
    rr2 = []
    rr1_2 = []

    rr1.append(ngl.TimeRangeModeNoop(transition_start))

    rr2.append(ngl.TimeRangeModeNoop(0))
    rr2.append(ngl.TimeRangeModeCont(transition_start + transition_duration))

    rr1_2.append(ngl.TimeRangeModeNoop(0))
    rr1_2.append(ngl.TimeRangeModeCont(transition_start))
    rr1_2.append(ngl.TimeRangeModeNoop(transition_start + transition_duration))

    rf1 = ngl.TimeRangeFilter(render1, ranges=rr1)
    rf2 = ngl.TimeRangeFilter(render2, ranges=rr2)
    rf1_2 = ngl.TimeRangeFilter(render1_2, ranges=rr1_2)

    g = ngl.Group()
    g.add_children(rf1, rf1_2, rf2)

    return g
Пример #4
0
 def _get_scene(
     self,
     file0,
     file1,
     diff_mode=False,
     split=(0.5, 0.5),
     vertical_split=True,
     show_r=True,
     show_g=True,
     show_b=True,
     show_a=True,
     premultiplied=False,
     threshold=0.001,
 ):
     vert = pkgutil.get_data("pynodegl_utils.diff.shaders", "diff.vert")
     frag = pkgutil.get_data("pynodegl_utils.diff.shaders", "diff.frag")
     assert vert is not None and frag is not None
     quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
     prog = ngl.Program(vertex=vert.decode(), fragment=frag.decode())
     prog.update_vert_out_vars(
         uv=ngl.IOVec2(),
         tex0_coord=ngl.IOVec2(),
         tex1_coord=ngl.IOVec2(),
     )
     scene = ngl.Render(quad, prog)
     scene.update_frag_resources(
         tex0=ngl.Texture2D(data_src=ngl.Media(file0)),
         tex1=ngl.Texture2D(data_src=ngl.Media(file1)),
         split=ngl.UniformVec2(split, live_id="split"),
         diff_mode=ngl.UniformBool(diff_mode, live_id="diff_mode"),
         vertical_split=ngl.UniformBool(vertical_split,
                                        live_id="vertical_split"),
         show_r=ngl.UniformBool(show_r, live_id="show_r"),
         show_g=ngl.UniformBool(show_g, live_id="show_g"),
         show_b=ngl.UniformBool(show_b, live_id="show_b"),
         show_a=ngl.UniformBool(show_a, live_id="show_a"),
         premultiplied=ngl.UniformBool(premultiplied,
                                       live_id="premultiplied"),
         threshold=ngl.UniformFloat(threshold,
                                    live_id="threshold",
                                    live_max=0.1),
     )
     scene.update_vert_resources(
         reframing_scale=ngl.UniformFloat(
             self._reframing_scale,
             live_id="reframing_scale",
             live_min=self._MIN_SCALE,
             live_max=self._MAX_SCALE,
         ),
         reframing_off=ngl.UniformVec2(
             self._reframing_off,
             live_id="reframing_off",
             live_min=(-self._MAX_SCALE, -self._MAX_SCALE),
             live_max=(self._MAX_SCALE, self._MAX_SCALE),
         ),
     )
     return scene
Пример #5
0
def queued_medias(cfg, overlap_time=1.0, dim=3):
    """Queue of medias, mainly used as a demonstration for the prefetch/release mechanism"""
    nb_videos = dim * dim
    tqs = []

    ag = AutoGrid(range(nb_videos))
    for video_id, _, col, pos in ag:
        start = video_id * cfg.duration / nb_videos
        animkf = [
            ngl.AnimKeyFrameFloat(start, 0),
            ngl.AnimKeyFrameFloat(start + cfg.duration, cfg.duration),
        ]
        m = ngl.Media(cfg.medias[video_id % len(cfg.medias)].filename,
                      time_anim=ngl.AnimatedTime(animkf))
        m.set_label("media #%d" % video_id)

        t = ngl.Texture2D(data_src=m)

        render = ngl.RenderTexture(t)
        render.set_label("render #%d" % video_id)
        render = ag.place_node(render, (col, pos))

        rf = ngl.TimeRangeFilter(render)
        if start:
            rf.add_ranges(ngl.TimeRangeModeNoop(0))
        rf.add_ranges(
            ngl.TimeRangeModeCont(start),
            ngl.TimeRangeModeNoop(start + cfg.duration / nb_videos +
                                  overlap_time))

        tqs.append(rf)

    return ngl.Group(children=tqs)
Пример #6
0
def _get_time_scene(cfg):
    m0 = cfg.medias[0]

    media_seek = 10
    noop_duration = 2
    prefetch_duration = 2
    freeze_duration = 3
    playback_duration = 5

    range_start = noop_duration + prefetch_duration
    play_start = range_start + freeze_duration
    play_stop = play_start + playback_duration
    range_stop = play_stop + freeze_duration
    duration = range_stop + noop_duration

    cfg.duration = duration
    cfg.aspect_ratio = (m0.width, m0.height)

    media_animkf = [
        ngl.AnimKeyFrameFloat(play_start, media_seek),
        ngl.AnimKeyFrameFloat(play_stop, media_seek + playback_duration),
    ]

    m = ngl.Media(m0.filename, time_anim=ngl.AnimatedTime(media_animkf))
    t = ngl.Texture2D(data_src=m)
    r = ngl.RenderTexture(t)

    time_ranges = [
        ngl.TimeRangeModeNoop(0),
        ngl.TimeRangeModeCont(range_start),
        ngl.TimeRangeModeNoop(range_stop),
    ]
    rf = ngl.TimeRangeFilter(r, ranges=time_ranges, prefetch_time=prefetch_duration)

    return rf
Пример #7
0
def media_exposed_time(cfg):
    m0 = cfg.medias[0]
    cfg.duration = m0.duration
    cfg.aspect_ratio = (m0.width, m0.height)

    vert = textwrap.dedent(
        """\
        void main()
        {
            ngl_out_pos = ngl_projection_matrix * ngl_modelview_matrix * vec4(ngl_position, 1.0);
            uv = ngl_uvcoord;
        }
        """
    )

    frag = textwrap.dedent(
        """\
        void main()
        {
            ngl_out_color = vec4(vec3(step(0.0, tex0_ts/duration - uv.x)), 1.0);
        }
        """
    )

    quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    media = ngl.Media(m0.filename)
    texture = ngl.Texture2D(data_src=media)
    program = ngl.Program(vertex=vert, fragment=frag)
    program.update_vert_out_vars(uv=ngl.IOVec2())
    render = ngl.Render(quad, program)
    render.update_frag_resources(tex0=texture, duration=ngl.UniformFloat(cfg.duration))
    return render
Пример #8
0
def animated_uniform(cfg):
    '''Uniform mat4 animated with a transform chain'''
    m0 = cfg.medias[0]
    cfg.aspect_ratio = (m0.width, m0.height)

    q = ngl.Quad((-0.5, -0.5, 0), (1, 0, 0), (0, 1, 0))
    m = ngl.Media(m0.filename)
    t = ngl.Texture2D(data_src=m)
    p = ngl.Program(vertex=cfg.get_vert('texture'),
                    fragment=cfg.get_frag('matrix-transform'))
    ts = ngl.Render(q, p)
    ts.update_textures(tex0=t)

    scale_animkf = [
        ngl.AnimKeyFrameVec3(0, (1, 1, 1)),
        ngl.AnimKeyFrameVec3(cfg.duration, (0.1, 0.1, 0.1), 'quartic_out')
    ]
    s = ngl.Scale(ngl.Identity(), anim=ngl.AnimatedVec3(scale_animkf))

    rotate_animkf = [
        ngl.AnimKeyFrameFloat(0, 0),
        ngl.AnimKeyFrameFloat(cfg.duration, 360, 'exp_out')
    ]
    r = ngl.Rotate(s, axis=(0, 0, 1), anim=ngl.AnimatedFloat(rotate_animkf))

    u = ngl.UniformMat4(transform=r)
    ts.update_uniforms(matrix=u)

    return ts
Пример #9
0
def centered_media(cfg,
                   uv_corner_x=0,
                   uv_corner_y=0,
                   uv_width=1,
                   uv_height=1,
                   progress_bar=True):
    '''A simple centered media with an optional progress bar in the shader'''
    m0 = cfg.medias[0]
    cfg.duration = m0.duration
    cfg.aspect_ratio = (m0.width, m0.height)

    q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0), (uv_corner_x, uv_corner_y),
                 (uv_width, 0), (0, uv_height))
    m = ngl.Media(m0.filename)
    t = ngl.Texture2D(data_src=m)
    p = ngl.Program()
    render = ngl.Render(q, p)
    render.update_textures(tex0=t)

    if progress_bar:
        p.set_fragment(cfg.get_frag('progress-bar'))

        media_duration = ngl.UniformFloat(m0.duration)
        ar = ngl.UniformFloat(cfg.aspect_ratio_float)
        render.update_uniforms(media_duration=media_duration, ar=ar)
    return render
def quaternion(cfg):
    """Animated quaternion used to rotate a plane"""
    cfg.duration = 10.0
    step = cfg.duration / 5.0
    x = math.sqrt(0.5)
    quat_animkf = [
        ngl.AnimKeyFrameQuat(0 * step, (0, 0, 0, 1)),
        ngl.AnimKeyFrameQuat(1 * step, (0, 0, -x, x)),
        ngl.AnimKeyFrameQuat(2 * step, (0, 1, 0, 0)),
        ngl.AnimKeyFrameQuat(3 * step, (1, 0, 0, 0)),
        ngl.AnimKeyFrameQuat(4 * step, (x, 0, 0, x)),
        ngl.AnimKeyFrameQuat(5 * step, (0, 0, 0, 1)),
    ]
    quat = ngl.AnimatedQuat(quat_animkf, as_mat4=True)

    q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    m = ngl.Media(cfg.medias[0].filename)
    t = ngl.Texture2D(data_src=m)
    p = ngl.Program(vertex=cfg.get_vert("uniform-mat4"),
                    fragment=cfg.get_frag("texture"))
    p.update_vert_out_vars(var_normal=ngl.IOVec3(),
                           var_uvcoord=ngl.IOVec2(),
                           var_tex0_coord=ngl.IOVec2())
    render = ngl.Render(q, p)
    render.update_frag_resources(tex0=t)
    render.update_vert_resources(transformation_matrix=quat)

    camera = ngl.Camera(render)
    camera.set_eye(0.0, 0.0, 4.0)
    camera.set_center(0.0, 0.0, 0.0)
    camera.set_up(0.0, 1.0, 0.0)
    camera.set_perspective(45.0, cfg.aspect_ratio_float)
    camera.set_clipping(1.0, 10.0)

    return camera
Пример #11
0
def api_media_sharing_failure():
    ctx = ngl.Context()
    ret = ctx.configure(offscreen=1, width=16, height=16, backend=_backend)
    assert ret == 0
    m = ngl.Media("/dev/null")
    scene = ngl.Group(children=(ngl.Texture2D(data_src=m), ngl.Texture2D(data_src=m)))
    assert _ret_to_fourcc(ctx.set_scene(scene)) == "Eusg"  # Usage error
def lut3d(cfg, xsplit=0.3, trilinear=True):
    """Lookup Table 3D using a Texture3D"""
    level = 6
    level2 = level**2

    # Generated with `ffmpeg -f lavfi -i haldclutsrc=6,curves=vintage,format=rgba
    # -f rawvideo -frames:v 1 lut3d.raw`
    lut3d_filename = op.join(op.dirname(__file__), "data", "lut3d.raw")
    cfg.files.append(lut3d_filename)
    lut3d_buf = ngl.BufferUBVec4(filename=lut3d_filename)
    lut3d_tex = ngl.Texture3D(data_src=lut3d_buf,
                              width=level2,
                              height=level2,
                              depth=level2)
    if trilinear:
        lut3d_tex.set_min_filter("linear")
        lut3d_tex.set_mag_filter("linear")

    m0 = cfg.medias[0]
    cfg.duration = m0.duration
    cfg.aspect_ratio = (m0.width, m0.height)
    video = ngl.Media(m0.filename)
    video_tex = ngl.Texture2D(data_src=video)

    scene_tex = ngl.RenderTexture(video_tex)

    quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    prog_lut = ngl.Program(fragment=cfg.get_frag("lut3d"),
                           vertex=cfg.get_vert("lut3d"))
    prog_lut.update_vert_out_vars(var_uvcoord=ngl.IOVec2(),
                                  var_tex0_coord=ngl.IOVec2())
    scene_lut = ngl.Render(quad, prog_lut)
    scene_lut.update_frag_resources(tex0=video_tex, lut3d=lut3d_tex)

    return compare(cfg, scene_tex, scene_lut, xsplit)
Пример #13
0
def centered_media(cfg,
                   uv_corner=(0, 0),
                   uv_width=(1, 0),
                   uv_height=(0, 1),
                   progress_bar=True):
    '''A simple centered media with an optional progress bar in the shader'''
    m0 = cfg.medias[0]
    cfg.duration = m0.duration
    cfg.aspect_ratio = (m0.width, m0.height)

    q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0), uv_corner, uv_width,
                 uv_height)
    m = ngl.Media(m0.filename)
    t = ngl.Texture2D(data_src=m)
    p = ngl.Program(vertex=cfg.get_vert('texture'),
                    fragment=cfg.get_frag('texture'))
    p.update_vert_out_vars(var_tex0_coord=ngl.IOVec2(),
                           var_uvcoord=ngl.IOVec2())
    render = ngl.Render(q, p)
    render.update_frag_resources(tex0=t)

    if progress_bar:
        p.set_fragment(cfg.get_frag('progress-bar'))

        media_duration = ngl.UniformFloat(m0.duration)
        ar = ngl.UniformFloat(cfg.aspect_ratio_float)
        render.update_frag_resources(media_duration=media_duration, ar=ar)
    return render
Пример #14
0
def lut3d(cfg, xsplit=.3, trilinear=True):
    '''Lookup Table 3D using a Texture3D'''
    level = 6
    level2 = level**2

    # Generated with `ffmpeg -f lavfi -i haldclutsrc=6,curves=vintage,format=rgba
    # -f rawvideo -frames:v 1 lut3d.raw`
    lut3d_filename = op.join(op.dirname(__file__), 'data', 'lut3d.raw')
    cfg.files.append(lut3d_filename)
    lut3d_buf = ngl.BufferUBVec4(filename=lut3d_filename)
    lut3d_tex = ngl.Texture3D(data_src=lut3d_buf,
                              width=level2,
                              height=level2,
                              depth=level2)
    if trilinear:
        lut3d_tex.set_min_filter('linear')
        lut3d_tex.set_mag_filter('linear')

    m0 = cfg.medias[0]
    cfg.duration = m0.duration
    cfg.aspect_ratio = (m0.width, m0.height)
    video = ngl.Media(m0.filename)
    video_tex = ngl.Texture2D(data_src=video)

    prog = ngl.Program(fragment=cfg.get_frag('lut3d'),
                       vertex=cfg.get_vert('lut3d'))
    prog.update_vert_out_vars(var_uvcoord=ngl.IOVec2(),
                              var_tex0_coord=ngl.IOVec2())

    quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    render = ngl.Render(quad, prog)
    render.update_frag_resources(tex0=video_tex, lut3d=lut3d_tex)
    render.update_frag_resources(xsplit=ngl.UniformFloat(value=xsplit))

    return render
Пример #15
0
def quaternion(cfg):
    '''Animated quaternion used to rotate a plane'''
    cfg.duration = 10.
    step = cfg.duration / 5.
    x = math.sqrt(0.5)
    quat_animkf = [
        ngl.AnimKeyFrameQuat(0 * step, (0, 0, 0, 1)),
        ngl.AnimKeyFrameQuat(1 * step, (0, 0,-x, x)),
        ngl.AnimKeyFrameQuat(2 * step, (0, 1, 0, 0)),
        ngl.AnimKeyFrameQuat(3 * step, (1, 0, 0, 0)),
        ngl.AnimKeyFrameQuat(4 * step, (x, 0, 0, x)),
        ngl.AnimKeyFrameQuat(5 * step, (0, 0, 0, 1)),
    ]
    quat = ngl.AnimatedQuat(quat_animkf, as_mat4=True)

    q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    m = ngl.Media(cfg.medias[0].filename)
    t = ngl.Texture2D(data_src=m)
    p = ngl.Program(vertex=cfg.get_vert('uniform-mat4'))
    render = ngl.Render(q, p)
    render.update_textures(tex0=t)
    render.update_uniforms(transformation_matrix=quat)

    camera = ngl.Camera(render)
    camera.set_eye(0.0, 0.0, 4.0)
    camera.set_center(0.0, 0.0, 0.0)
    camera.set_up(0.0, 1.0, 0.0)
    camera.set_perspective(45.0, cfg.aspect_ratio_float)
    camera.set_clipping(1.0, 10.0)

    return camera
Пример #16
0
def animated_uniform(cfg):
    """Uniform mat4 animated with a transform chain"""
    m0 = cfg.medias[0]
    cfg.aspect_ratio = (m0.width, m0.height)

    q = ngl.Quad((-0.5, -0.5, 0), (1, 0, 0), (0, 1, 0))
    m = ngl.Media(m0.filename)
    t = ngl.Texture2D(data_src=m)
    p = ngl.Program(vertex=cfg.get_vert("texture"),
                    fragment=cfg.get_frag("matrix-transform"))
    p.update_vert_out_vars(var_uvcoord=ngl.IOVec2(),
                           var_tex0_coord=ngl.IOVec2())
    ts = ngl.Render(q, p)
    ts.update_frag_resources(tex0=t)

    scale_animkf = [
        ngl.AnimKeyFrameVec3(0, (1, 1, 1)),
        ngl.AnimKeyFrameVec3(cfg.duration, (0.1, 0.1, 0.1), "quartic_out"),
    ]
    s = ngl.Scale(ngl.Identity(), factors=ngl.AnimatedVec3(scale_animkf))

    rotate_animkf = [
        ngl.AnimKeyFrameFloat(0, 0),
        ngl.AnimKeyFrameFloat(cfg.duration, 360, "exp_out")
    ]
    r = ngl.Rotate(s, axis=(0, 0, 1), angle=ngl.AnimatedFloat(rotate_animkf))

    u = ngl.UniformMat4(transform=r)
    ts.update_frag_resources(matrix=u)

    return ts
Пример #17
0
def lut3d(cfg, xsplit=.3, trilinear=True):
    '''Lookup Table 3D using a Texture3D'''
    level = 6
    level2 = level**2

    # Generated with `ffmpeg -f lavfi -i haldclutsrc=6,curves=vintage -f
    # rawvideo -frames:v 1 lut3d.raw`
    lut3d_filename = op.join(op.dirname(__file__), 'data', 'lut3d.raw')
    cfg.files.append(lut3d_filename)
    lut3d_buf = ngl.BufferUBVec3(filename=lut3d_filename)
    lut3d_tex = ngl.Texture3D(data_src=lut3d_buf,
                              width=level2, height=level2, depth=level2)
    if trilinear:
        lut3d_tex.set_min_filter('linear')
        lut3d_tex.set_mag_filter('linear')

    m0 = cfg.medias[0]
    cfg.duration = m0.duration
    cfg.aspect_ratio = (m0.width, m0.height)
    video = ngl.Media(m0.filename)
    video_tex = ngl.Texture2D(data_src=video)

    shader_version = '300 es' if cfg.backend == 'gles' else '330'
    shader_header = '#version %s\n' % shader_version
    prog = ngl.Program(fragment=shader_header + cfg.get_frag('lut3d'),
                       vertex=shader_header + cfg.get_vert('lut3d'))

    quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    render = ngl.Render(quad, prog)
    render.update_textures(tex0=video_tex)
    render.update_textures(lut3d=lut3d_tex)
    render.update_uniforms(xsplit=ngl.UniformFloat(value=xsplit))

    return render
Пример #18
0
def queued_medias(cfg, overlap_time=1., dim=3):
    '''Queue of medias, mainly used as a demonstration for the prefetch/release mechanism'''
    nb_videos = dim * dim
    tqs = []
    q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))

    ag = AutoGrid(range(nb_videos))
    for video_id, _, col, pos in ag:
        start = video_id * cfg.duration / nb_videos
        animkf = [ngl.AnimKeyFrameFloat(start, 0)]
        m = ngl.Media(cfg.medias[video_id % len(cfg.medias)].filename, time_anim=ngl.AnimatedTime(animkf))
        m.set_label('media #%d' % video_id)

        t = ngl.Texture2D(data_src=m)

        program = ngl.Program(vertex=cfg.get_vert('texture'), fragment=cfg.get_frag('texture'))
        program.update_vert_out_vars(var_uvcoord=ngl.IOVec2(), var_tex0_coord=ngl.IOVec2())
        render = ngl.Render(q, program)
        render.set_label('render #%d' % video_id)
        render.update_frag_resources(tex0=t)
        render = ag.place_node(render, (col, pos))

        rf = ngl.TimeRangeFilter(render)
        if start:
            rf.add_ranges(ngl.TimeRangeModeNoop(0))
        rf.add_ranges(ngl.TimeRangeModeCont(start),
                      ngl.TimeRangeModeNoop(start + cfg.duration/nb_videos + overlap_time))

        tqs.append(rf)

    return ngl.Group(children=tqs)
Пример #19
0
def queued_medias(cfg, overlap_time=1., dim=3):
    '''Queue of medias, mainly used as a demonstration for the prefetch/release mechanism'''
    qw = qh = 2. / dim
    nb_videos = dim * dim
    tqs = []
    p = ngl.Program()
    for y in range(dim):
        for x in range(dim):
            video_id = y * dim + x
            start = video_id * cfg.duration / nb_videos
            animkf = [ngl.AnimKeyFrameFloat(start, 0)]
            m = ngl.Media(cfg.medias[video_id % len(cfg.medias)].filename,
                          time_anim=ngl.AnimatedTime(animkf))
            m.set_label('media #%d' % video_id)

            corner = (-1. + x * qw, 1. - (y + 1) * qh, 0)
            q = ngl.Quad(corner, (qw, 0, 0), (0, qh, 0))
            t = ngl.Texture2D(data_src=m)

            render = ngl.Render(q, p)
            render.set_label('render #%d' % video_id)
            render.update_textures(tex0=t)

            rf = ngl.TimeRangeFilter(render)
            if start:
                rf.add_ranges(ngl.TimeRangeModeNoop(0))
            rf.add_ranges(
                ngl.TimeRangeModeCont(start),
                ngl.TimeRangeModeNoop(start + cfg.duration / nb_videos +
                                      overlap_time))

            tqs.append(rf)

    return ngl.Group(children=tqs)
Пример #20
0
def cube(cfg, display_depth_buffer=False):
    '''
    Cube with a common media Texture but a different color tainting on each side.
    Also includes a depth map visualization.
    '''
    cube = ngl.Group(label='cube')

    frag_data = cfg.get_frag('tex-tint')
    program = ngl.Program(fragment=frag_data)

    texture = ngl.Texture2D(data_src=ngl.Media(cfg.medias[0].filename))
    children = [_get_cube_side(texture, program, qi[0], qi[1], qi[2], qi[3]) for qi in _get_cube_quads()]
    cube.add_children(*children)

    for i in range(3):
        rot_animkf = ngl.AnimatedFloat([ngl.AnimKeyFrameFloat(0,            0),
                                        ngl.AnimKeyFrameFloat(cfg.duration, 360 * (i + 1))])
        axis = [int(i == x) for x in range(3)]
        cube = ngl.Rotate(cube, axis=axis, anim=rot_animkf)

    config = ngl.GraphicConfig(cube, depth_test=True)

    camera = ngl.Camera(config)
    camera.set_eye(0.0, 0.0, 2.0)
    camera.set_center(0.0, 0.0, 0.0)
    camera.set_up(0.0, 1.0, 0.0)
    camera.set_perspective(45.0, cfg.aspect_ratio_float)
    camera.set_clipping(1.0, 10.0)

    if not display_depth_buffer:
        return camera
    else:
        group = ngl.Group()

        depth_texture = ngl.Texture2D()
        depth_texture.set_format('d16_unorm')
        depth_texture.set_width(640)
        depth_texture.set_height(480)

        texture = ngl.Texture2D()
        texture.set_width(640)
        texture.set_height(480)
        rtt = ngl.RenderToTexture(camera)
        rtt.add_color_textures(texture)
        rtt.set_depth_texture(depth_texture)

        quad = ngl.Quad((-1.0, -1.0, 0), (1, 0, 0), (0, 1, 0))
        program = ngl.Program()
        render = ngl.Render(quad, program)
        render.update_textures(tex0=texture)
        group.add_children(rtt, render)

        quad = ngl.Quad((0.0, 0.0, 0), (1, 0, 0), (0, 1, 0))
        program = ngl.Program()
        render = ngl.Render(quad, program)
        render.update_textures(tex0=depth_texture)
        group.add_children(rtt, render)

        return group
Пример #21
0
def animated_camera(cfg, rotate=True):
    '''Animated camera around a scene'''
    g = ngl.Group()

    q = ngl.Quad((-0.5, -0.5, 0), (1, 0, 0), (0, 1, 0))
    m = ngl.Media(cfg.medias[0].filename)
    t = ngl.Texture2D(data_src=m)
    program = ngl.Program(vertex=cfg.get_vert('texture'),
                          fragment=cfg.get_frag('texture'))
    program.update_vert_out_vars(var_uvcoord=ngl.IOVec2(),
                                 var_tex0_coord=ngl.IOVec2())
    node = ngl.Render(q, program)
    node.update_frag_resources(tex0=t)
    g.add_children(node)

    translate = ngl.Translate(node, vector=(-0.6, 0.8, -1))
    g.add_children(translate)

    translate = ngl.Translate(node, vector=(0.6, 0.8, -1))
    g.add_children(translate)

    translate = ngl.Translate(node, vector=(-0.6, -0.5, -1))
    g.add_children(translate)

    translate = ngl.Translate(node, vector=(0.6, -0.5, -1))
    g.add_children(translate)

    g = ngl.GraphicConfig(g, depth_test=True)
    camera = ngl.Camera(g)
    camera.set_eye(0, 0, 2)
    camera.set_center(0.0, 0.0, 0.0)
    camera.set_up(0.0, 1.0, 0.0)
    camera.set_perspective(45.0, cfg.aspect_ratio_float)
    camera.set_clipping(0.1, 10.0)

    tr_animkf = [
        ngl.AnimKeyFrameVec3(0, (0.0, 0.0, 0.0)),
        ngl.AnimKeyFrameVec3(10, (0.0, 0.0, 3.0), 'exp_out')
    ]
    node = ngl.Translate(ngl.Identity(), anim=ngl.AnimatedVec3(tr_animkf))

    if rotate:
        rot_animkf = [
            ngl.AnimKeyFrameFloat(0, 0),
            ngl.AnimKeyFrameFloat(cfg.duration, 360, 'exp_out')
        ]
        node = ngl.Rotate(node,
                          axis=(0, 1, 0),
                          anim=ngl.AnimatedFloat(rot_animkf))

    camera.set_eye_transform(node)

    fov_animkf = [
        ngl.AnimKeyFrameFloat(0.5, 60.0),
        ngl.AnimKeyFrameFloat(cfg.duration, 45.0, 'exp_out')
    ]
    camera.set_fov_anim(ngl.AnimatedFloat(fov_animkf))

    return camera
Пример #22
0
def api_media_sharing_failure():
    import struct
    ctx = ngl.Context()
    assert ctx.configure(offscreen=1, width=16, height=16,
                         backend=_backend) == 0
    m = ngl.Media('/dev/null')
    scene = ngl.Group(children=(m, m))
    assert _ret_to_fourcc(ctx.set_scene(scene)) == 'Eusg'  # Usage error
Пример #23
0
def media_clamp(cfg):
    m0 = cfg.medias[0]
    cfg.duration = m0.duration
    cfg.aspect_ratio = (m0.width, m0.height)

    media = ngl.Media(m0.filename)
    texture = ngl.Texture2D(data_src=media, clamp_video=True)
    return ngl.RenderTexture(texture)
Пример #24
0
def parallel_playback(cfg, fast=True, segment_time=2.):
    '''
    Parallel media playback, flipping between the two sources.

    The fast version makes sure the textures continue to be updated even though
    they are not displayed. On the other hand, the slow version will update the
    textures only when needed to be displayed, causing potential seek in the
    underlying media, and thus undesired delays.
    '''
    q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    p = ngl.Program()

    m1 = ngl.Media(cfg.medias[0].filename, label='media #1')
    m2 = ngl.Media(cfg.medias[0].filename, label='media #2')

    t1 = ngl.Texture2D(data_src=m1, label='texture #1')
    t2 = ngl.Texture2D(data_src=m2, label='texture #2')

    render1 = ngl.Render(q, p, label='render #1')
    render1.update_textures(tex0=t1)
    render2 = ngl.Render(q, p, label='render #2')
    render2.update_textures(tex0=t2)

    rf1 = ngl.TimeRangeFilter(render1)
    rf2 = ngl.TimeRangeFilter(render2)

    t = 0
    rr1 = []
    rr2 = []
    while t < cfg.duration:
        rr1.append(ngl.TimeRangeModeCont(t))
        rr1.append(ngl.TimeRangeModeNoop(t + segment_time))

        rr2.append(ngl.TimeRangeModeNoop(t))
        rr2.append(ngl.TimeRangeModeCont(t + segment_time))

        t += 2 * segment_time

    rf1.add_ranges(*rr1)
    rf2.add_ranges(*rr2)

    g = ngl.Group()
    g.add_children(rf1, rf2)
    if fast:
        g.add_children(t1, t2)
    return g
def histogram(cfg):
    """Histogram using compute shaders"""
    m0 = cfg.medias[0]
    cfg.duration = m0.duration
    cfg.aspect_ratio = (m0.width, m0.height)
    g = ngl.Group()

    m = ngl.Media(cfg.medias[0].filename)
    t = ngl.Texture2D(data_src=m)

    h = ngl.Block(label="histogram_block", layout="std430")
    h.add_fields(
        ngl.BufferUInt(256, label="r"),
        ngl.BufferUInt(256, label="g"),
        ngl.BufferUInt(256, label="b"),
        ngl.UniformUInt(label="maximum"),
    )

    r = ngl.RenderTexture(t)
    proxy_size = 128
    proxy = ngl.Texture2D(width=proxy_size, height=proxy_size)
    rtt = ngl.RenderToTexture(r)
    rtt.add_color_textures(proxy)
    g.add_children(rtt)

    compute_program = ngl.ComputeProgram(cfg.get_comp("histogram-clear"),
                                         workgroup_size=(1, 1, 1))
    compute_program.update_properties(hist=ngl.ResourceProps(writable=True))
    compute = ngl.Compute(workgroup_count=(256, 1, 1),
                          program=compute_program,
                          label="histogram-clear")
    compute.update_resources(hist=h)
    g.add_children(compute)

    local_size = 8
    group_size = proxy_size / local_size
    compute_program = ngl.ComputeProgram(cfg.get_comp("histogram-exec"),
                                         workgroup_size=(local_size,
                                                         local_size, 1))
    compute = ngl.Compute(workgroup_count=(group_size, group_size, 1),
                          program=compute_program,
                          label="histogram-exec")
    compute.update_resources(hist=h, source=proxy)
    compute_program.update_properties(hist=ngl.ResourceProps(writable=True))
    compute_program.update_properties(source=ngl.ResourceProps(as_image=True))
    g.add_children(compute)

    q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    p = ngl.Program(vertex=cfg.get_vert("histogram-display"),
                    fragment=cfg.get_frag("histogram-display"))
    p.update_vert_out_vars(var_uvcoord=ngl.IOVec2(),
                           var_tex0_coord=ngl.IOVec2())
    render = ngl.Render(q, p)
    render.update_frag_resources(tex0=t, hist=h)
    g.add_children(render)

    return g
Пример #26
0
def histogram(cfg):
    '''Histogram using compute shaders'''
    m0 = cfg.medias[0]
    cfg.duration = m0.duration
    cfg.aspect_ratio = (m0.width, m0.height)
    g = ngl.Group()

    m = ngl.Media(cfg.medias[0].filename)
    t = ngl.Texture2D(data_src=m)

    h = ngl.Block(label='histogram_block', layout='std430')
    h.add_fields(
        ngl.BufferUInt(256, label='r'),
        ngl.BufferUInt(256, label='g'),
        ngl.BufferUInt(256, label='b'),
        ngl.UniformInt(label='maximum'),
    )

    q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    r = ngl.Render(q)
    r.update_textures(tex0=t)
    proxy_size = 128
    proxy = ngl.Texture2D(width=proxy_size, height=proxy_size)
    rtt = ngl.RenderToTexture(r)
    rtt.add_color_textures(proxy)
    g.add_children(rtt)

    shader_version = '310 es' if cfg.backend == 'gles' else '430'
    shader_header = '#version %s\n' % shader_version
    if cfg.backend == 'gles' and cfg.system == 'Android':
        shader_header += '#extension GL_ANDROID_extension_pack_es31a: require\n'

    compute_program = ngl.ComputeProgram(shader_header + cfg.get_comp('histogram-clear'))
    compute = ngl.Compute(256, 1, 1, compute_program, label='histogram-clear')
    compute.update_blocks(histogram_buffer=h)
    g.add_children(compute)

    local_size = 8
    group_size = proxy_size / local_size
    compute_shader = cfg.get_comp('histogram-exec') % {'local_size': local_size}
    compute_program = ngl.ComputeProgram(shader_header + compute_shader)
    compute = ngl.Compute(group_size, group_size, 1, compute_program, label='histogram-exec')
    compute.update_blocks(histogram_buffer=h)
    compute.update_textures(source=proxy)
    g.add_children(compute)

    q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    p = ngl.Program(vertex=shader_header + cfg.get_vert('histogram-display'),
                    fragment=shader_header + cfg.get_frag('histogram-display'))
    render = ngl.Render(q, p)
    render.update_textures(tex0=t)
    render.update_blocks(histogram_buffer=h)
    g.add_children(render)

    return g
Пример #27
0
def animated_camera(cfg, rotate=True):
    """Animated camera around a scene"""
    g = ngl.Group()

    q = ngl.Quad((-0.5, -0.5, 0), (1, 0, 0), (0, 1, 0))
    m = ngl.Media(cfg.medias[0].filename)
    t = ngl.Texture2D(data_src=m)
    node = ngl.RenderTexture(t, geometry=q)
    g.add_children(node)

    translate = ngl.Translate(node, vector=(-0.6, 0.8, -1))
    g.add_children(translate)

    translate = ngl.Translate(node, vector=(0.6, 0.8, -1))
    g.add_children(translate)

    translate = ngl.Translate(node, vector=(-0.6, -0.5, -1))
    g.add_children(translate)

    translate = ngl.Translate(node, vector=(0.6, -0.5, -1))
    g.add_children(translate)

    g = ngl.GraphicConfig(g, depth_test=True)
    camera = ngl.Camera(g)
    camera.set_eye(0, 0, 2)
    camera.set_center(0.0, 0.0, 0.0)
    camera.set_up(0.0, 1.0, 0.0)
    camera.set_clipping(0.1, 10.0)

    tr_animkf = [
        ngl.AnimKeyFrameVec3(0, (0.0, 0.0, 0.0)),
        ngl.AnimKeyFrameVec3(10, (0.0, 0.0, 3.0), "exp_out")
    ]
    node = ngl.Translate(ngl.Identity(), vector=ngl.AnimatedVec3(tr_animkf))

    if rotate:
        rot_animkf = [
            ngl.AnimKeyFrameFloat(0, 0),
            ngl.AnimKeyFrameFloat(cfg.duration, 360, "exp_out")
        ]
        node = ngl.Rotate(node,
                          axis=(0, 1, 0),
                          angle=ngl.AnimatedFloat(rot_animkf))

    camera.set_eye_transform(node)

    perspective_animkf = [
        ngl.AnimKeyFrameVec2(0.5, (60.0, cfg.aspect_ratio_float)),
        ngl.AnimKeyFrameVec2(cfg.duration, (45.0, cfg.aspect_ratio_float),
                             "exp_out"),
    ]
    camera.set_perspective(ngl.AnimatedVec2(perspective_animkf))

    return camera
Пример #28
0
def cropboard(cfg, dim=15):
    '''Divided media using instancing draw and UV coords offsetting from a buffer'''
    m0 = cfg.medias[0]
    random.seed(0)
    cfg.duration = 10
    cfg.aspect_ratio = (m0.width, m0.height)

    kw = kh = 1. / dim
    qw = qh = 2. / dim

    p = ngl.Program(vertex=cfg.get_vert('cropboard'),
                    fragment=cfg.get_frag('texture'))
    p.update_vert_out_vars(var_tex0_coord=ngl.IOVec2(),
                           var_uvcoord=ngl.IOVec2())
    m = ngl.Media(m0.filename)
    t = ngl.Texture2D(data_src=m)

    uv_offset_buffer = array.array('f')
    translate_a_buffer = array.array('f')
    translate_b_buffer = array.array('f')

    q = ngl.Quad(corner=(0, 0, 0),
                 width=(qw, 0, 0),
                 height=(0, qh, 0),
                 uv_corner=(0, 0),
                 uv_width=(kw, 0),
                 uv_height=(0, kh))

    for y in range(dim):
        for x in range(dim):
            uv_offset = [x * kw, (y + 1.) * kh - 1.]
            src = [random.uniform(-2, 2), random.uniform(-2, 2)]
            dst = [x * qw - 1., 1. - (y + 1.) * qh]

            uv_offset_buffer.extend(uv_offset)
            translate_a_buffer.extend(src)
            translate_b_buffer.extend(dst)

    utime_animkf = [
        ngl.AnimKeyFrameFloat(0, 0),
        ngl.AnimKeyFrameFloat(cfg.duration * 2 / 3., 1, 'exp_out')
    ]
    utime = ngl.AnimatedFloat(utime_animkf)

    render = ngl.Render(q, p, nb_instances=dim**2)
    render.update_frag_resources(tex0=t)
    render.update_vert_resources(time=utime)
    render.update_instance_attributes(
        uv_offset=ngl.BufferVec2(data=uv_offset_buffer),
        translate_a=ngl.BufferVec2(data=translate_a_buffer),
        translate_b=ngl.BufferVec2(data=translate_b_buffer),
    )
    return render
Пример #29
0
def media_flat_remap(cfg):
    m0 = cfg.medias[0]
    cfg.duration = m0.duration
    cfg.aspect_ratio = (m0.width, m0.height)

    media_animkf = [
        ngl.AnimKeyFrameFloat(cfg.duration / 2, 1.833),
    ]

    m = ngl.Media(m0.filename, time_anim=ngl.AnimatedTime(media_animkf))
    t = ngl.Texture2D(data_src=m)
    return ngl.RenderTexture(t)
Пример #30
0
def audiotex(cfg, freq_precision=7, overlay=0.6):
    '''FFT/Waves audio texture of the audio stream blended on top of the video stream'''
    media = cfg.medias[0]
    cfg.duration = media.duration
    cfg.aspect_ratio = (media.width, media.height)

    q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))

    audio_m = ngl.Media(media.filename, audio_tex=1)
    audio_tex = ngl.Texture2D(data_src=audio_m)

    video_m = ngl.Media(media.filename)
    video_tex = ngl.Texture2D(data_src=video_m)

    p = ngl.Program(vertex=cfg.get_vert('dual-tex'),
                    fragment=cfg.get_frag('audiotex'))
    render = ngl.Render(q, p)
    render.update_textures(tex0=audio_tex, tex1=video_tex)
    render.update_uniforms(overlay=ngl.UniformFloat(overlay))
    render.update_uniforms(freq_precision=ngl.UniformInt(freq_precision))
    return render