Exemplo n.º 1
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)
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)
Exemplo n.º 3
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)
Exemplo n.º 4
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
Exemplo n.º 5
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
Exemplo n.º 6
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
Exemplo n.º 7
0
def _get_random_layer(cfg, rng, t0, t1, enable_computes, layer=4):
    nb_elems = rng.randint(2, 5)
    children = []
    sub_layers = rng.sample(range(nb_elems), 2)
    for i in range(nb_elems):
        if i in sub_layers and layer != 0:
            # Recursively create another layer
            child = _get_random_layer(cfg,
                                      rng,
                                      t0,
                                      t1,
                                      enable_computes,
                                      layer=layer - 1)
            child = _get_random_transform(rng, t0, t1, child)
            child.set_label(f"layer={layer}")

            # Create a (small) RTT of the children
            rtt_tex = ngl.Texture2D(
                width=rng.randint(50, 90),
                height=rng.randint(15, 70),
            )
            rtt = ngl.RenderToTexture(
                child,
                clear_color=_get_random_color(rng) + (1, ),
            )
            rtt.add_color_textures(rtt_tex)
            rtt_render = ngl.RenderTexture(
                rtt_tex,
                geometry=_get_random_geometry(rng),
                blending="src_over",
            )
            rtt_render = _get_random_transform(rng, t0, t1, rtt_render)
            t_start, t_end = _get_random_time_range(rng, t0, t1)
            rtt_group = ngl.Group(children=(rtt, rtt_render))
            t_filter = ngl.TimeRangeFilter(rtt_group)
            t_filter.add_ranges(
                ngl.TimeRangeModeNoop(0),
                ngl.TimeRangeModeCont(t_start),
                ngl.TimeRangeModeNoop(t_end),
            )

            # Draw both the children and the rendered texture
            child = ngl.Group(children=(t_filter, child))

        else:
            # We are at a leaf (last layer) so we create a random render
            t_start, t_end = _get_random_time_range(rng, t0, t1)
            child = _get_random_render(cfg, rng, t_start, t_end,
                                       enable_computes)
            if rng.random() < 1 / 3:
                child = _get_random_transform(rng, t_start, t_end, child)
            child = ngl.TimeRangeFilter(child)
            child.add_ranges(
                ngl.TimeRangeModeNoop(0),
                ngl.TimeRangeModeCont(t_start),
                ngl.TimeRangeModeNoop(t_end),
            )
        children.append(child)
    return ngl.Group(children=children)
Exemplo n.º 8
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
Exemplo n.º 9
0
def media_timeranges_rtt(cfg):
    m0 = cfg.medias[0]
    cfg.duration = d = 10
    cfg.aspect_ratio = (m0.width, m0.height)

    # Use a media/texture as leaf to exercise its prefetch/release mechanism
    media = ngl.Media(m0.filename)
    texture = ngl.Texture2D(data_src=media)

    # Diamond tree on the same media texture
    render0 = ngl.RenderTexture(texture, label="leaf 0")
    render1 = ngl.RenderTexture(texture, label="leaf 1")

    # Create intermediate RTT "proxy" to exercise prefetch/release at this
    # level as well
    dst_tex0 = ngl.Texture2D(width=m0.width, height=m0.height)
    dst_tex1 = ngl.Texture2D(width=m0.width, height=m0.height)
    rtt0 = ngl.RenderToTexture(render0, [dst_tex0])
    rtt1 = ngl.RenderToTexture(render1, [dst_tex1])

    # Render the 2 RTTs vertically split (one half content each)
    quad0 = ngl.Quad((-1, -1, 0), (1, 0, 0), (0, 2, 0), uv_corner=(0, 0), uv_width=(0.5, 0))
    quad1 = ngl.Quad((0, -1, 0), (1, 0, 0), (0, 2, 0), uv_corner=(0.5, 0), uv_width=(0.5, 0))
    rtt_render0 = ngl.RenderTexture(dst_tex0, geometry=quad0, label="render RTT 0")
    rtt_render1 = ngl.RenderTexture(dst_tex1, geometry=quad1, label="render RTT 1")
    proxy0 = ngl.Group(children=(rtt0, rtt_render0), label="proxy 0")
    proxy1 = ngl.Group(children=(rtt1, rtt_render1), label="proxy 1")

    # We want to make sure the idle times are enough to exercise the
    # prefetch/release mechanism
    prefetch_time = 1
    assert prefetch_time < d / 5

    # Split the presentation in 5 segments such that there are inactive times,
    # prefetch times and both overlapping and non-overlapping times for the
    # RTTs
    ranges0 = (
        ngl.TimeRangeModeNoop(0),
        ngl.TimeRangeModeCont(1 / 5 * d),
        ngl.TimeRangeModeNoop(3 / 5 * d),
    )
    ranges1 = (
        ngl.TimeRangeModeNoop(0),
        ngl.TimeRangeModeCont(2 / 5 * d),
        ngl.TimeRangeModeNoop(4 / 5 * d),
    )
    trange0 = ngl.TimeRangeFilter(proxy0, ranges=ranges0, prefetch_time=prefetch_time, label="left")
    trange1 = ngl.TimeRangeFilter(proxy1, ranges=ranges1, prefetch_time=prefetch_time, label="right")

    return ngl.Group(children=(trange0, trange1))
Exemplo n.º 10
0
def autogrid_queue(scenes, duration, overlap_time):
    ag = AutoGrid(scenes)
    g = ngl.Group()
    for scene, scene_id, col, row in ag:
        if duration is not None:
            assert overlap_time is not None
            scene = ngl.TimeRangeFilter(scene)
            start = scene_id * duration / ag.nb
            if start:
                scene.add_ranges(ngl.TimeRangeModeNoop(0))
            scene.add_ranges(
                ngl.TimeRangeModeCont(start),
                ngl.TimeRangeModeNoop(start + duration / ag.nb + overlap_time))
        scene = ag.place_node(scene, (col, row))
        g.add_children(scene)
    return g
Exemplo n.º 11
0
def rtt_clear_attachment_with_timeranges(cfg):
    cfg.aspect_ratio = (1, 1)

    # Time-disabled full screen white quad
    render = ngl.RenderColor(COLORS.white)

    time_range_filter = ngl.TimeRangeFilter(render)
    time_range_filter.add_ranges(ngl.TimeRangeModeNoop(0))

    # Intermediate no-op RTT to force the use of a different render pass internally
    texture = ngl.Texture2D(width=32, height=32)
    rtt_noop = ngl.RenderToTexture(ngl.Identity(), [texture])

    # Centered rotating quad
    quad = ngl.Quad((-0.5, -0.5, 0), (1, 0, 0), (0, 1, 0))
    render = ngl.RenderColor(COLORS.orange, geometry=quad)

    animkf = [ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, -360)]
    render = ngl.Rotate(render, angle=ngl.AnimatedFloat(animkf))

    group = ngl.Group(children=(time_range_filter, rtt_noop, render))

    # Root RTT
    texture = ngl.Texture2D(width=512, height=512)
    rtt = ngl.RenderToTexture(group, [texture])

    # Full screen render of the root RTT result
    render = ngl.RenderTexture(texture)

    return ngl.Group(children=(rtt, render))
Exemplo n.º 12
0
def text(cfg,
         demo_str='Hello World!\n\nThis is a multi-line\ntext demonstration.',
         time_unit=0.05):
    '''Demonstrate the text node features (colors, scale, alignment, fitting, ...)'''

    random.seed(0)

    group = ngl.Group()

    cfg.duration = time_unit * 2 * len(demo_str)

    nb_chars = len(demo_str)
    for i in range(nb_chars):
        ascii_text = ngl.Text(demo_str[:i + 1],
                              aspect_ratio=cfg.aspect_ratio,
                              bg_color=(0.15, 0.15, 0.15, 1),
                              font_scale=1 / 2.)
        start = i * time_unit
        text_range = [ngl.TimeRangeModeNoop(0), ngl.TimeRangeModeCont(start)]
        if i != nb_chars - 1:
            end = (i + 1) * time_unit
            text_range.append(ngl.TimeRangeModeNoop(end))
        text_range_filter = ngl.TimeRangeFilter(ascii_text, ranges=text_range)
        group.add_children(text_range_filter)

    for valign in ('top', 'center', 'bottom'):
        for halign in ('left', 'center', 'right'):
            if (valign, halign) == ('center', 'center'):
                continue
            fg_color = list(colorsys.hls_to_rgb(random.uniform(0, 1), 0.5,
                                                1.0)) + [1]
            aligned_text = ngl.Text('%s-%s' % (valign, halign),
                                    valign=valign,
                                    halign=halign,
                                    aspect_ratio=cfg.aspect_ratio,
                                    fg_color=fg_color,
                                    bg_color=(0, 0, 0, 0),
                                    font_scale=1 / 5.)
            group.add_children(aligned_text)

    return ngl.GraphicConfig(group,
                             blend=True,
                             blend_src_factor='src_alpha',
                             blend_dst_factor='one_minus_src_alpha',
                             blend_src_factor_a='zero',
                             blend_dst_factor_a='one')
Exemplo n.º 13
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
Exemplo n.º 14
0
def time_remapping(cfg):
    '''
    Time remapping in the following order:
    - nothing displayed for a while (but media prefetch happening in background)
    - first frame displayed for a while
    - normal playback
    - last frame displayed for a while (even though the media is closed)
    - nothing again until the end
    '''
    m0 = cfg.medias[0]

    media_seek = 10
    noop_duration = 1
    prefetch_duration = 2
    freeze_duration = 1
    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),
    ]

    q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    m = ngl.Media(m0.filename, time_anim=ngl.AnimatedFloat(media_animkf))
    t = ngl.Texture2D(data_src=m)
    r = ngl.Render(q)
    r.update_textures(tex0=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
Exemplo n.º 15
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),
    ]

    q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    m = ngl.Media(m0.filename, time_anim=ngl.AnimatedTime(media_animkf))
    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())
    r = ngl.Render(q, p)
    r.update_frag_resources(tex0=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
Exemplo n.º 16
0
def text(cfg,
         demo_str="Hello World!\n\nThis is a multi-line\ntext demonstration.",
         time_unit=0.05):
    """Demonstrate the text node features (colors, scale, alignment, fitting, ...)"""

    group = ngl.Group()

    cfg.duration = time_unit * 2 * len(demo_str)

    nb_chars = len(demo_str)
    for i in range(nb_chars):
        ascii_text = ngl.Text(
            demo_str[:i + 1],
            aspect_ratio=cfg.aspect_ratio,
            bg_color=(0.15, 0.15, 0.15),
            bg_opacity=1,
            font_scale=1 / 2.0,
        )
        start = i * time_unit
        text_range = [ngl.TimeRangeModeNoop(0), ngl.TimeRangeModeCont(start)]
        if i != nb_chars - 1:
            end = (i + 1) * time_unit
            text_range.append(ngl.TimeRangeModeNoop(end))
        text_range_filter = ngl.TimeRangeFilter(ascii_text, ranges=text_range)
        group.add_children(text_range_filter)

    for valign in ("top", "center", "bottom"):
        for halign in ("left", "center", "right"):
            if (valign, halign) == ("center", "center"):
                continue
            fg_color = colorsys.hls_to_rgb(cfg.rng.uniform(0, 1), 0.5, 1.0)
            aligned_text = ngl.Text(
                f"{valign}-{halign}",
                valign=valign,
                halign=halign,
                aspect_ratio=cfg.aspect_ratio,
                fg_color=fg_color,
                bg_opacity=0,
                font_scale=1 / 5.0,
            )
            group.add_children(aligned_text)

    return group
Exemplo n.º 17
0
def media_queue(cfg, overlap_time=7.0, dim=3):
    cfg.duration = 10
    cfg.aspect_ratio = (1, 1)

    nb_medias = dim * dim

    medias = [
        m.filename for m in cfg.medias if m.filename.endswith(("mp4", "jpg"))
    ]

    queued_medias = []
    ag = AutoGrid(range(nb_medias))
    for video_id, _, col, pos in ag:
        start = video_id * cfg.duration / nb_medias
        animkf = [
            ngl.AnimKeyFrameFloat(start, 0),
            ngl.AnimKeyFrameFloat(start + cfg.duration, cfg.duration),
        ]
        media = ngl.Media(medias[video_id % len(medias)],
                          time_anim=ngl.AnimatedTime(animkf))

        texture = ngl.Texture2D(data_src=media,
                                min_filter="linear",
                                mag_filter="linear")
        render = ngl.RenderTexture(texture)
        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_medias +
                                  overlap_time))

        queued_medias.append(rf)

    return ngl.Group(children=queued_medias)
Exemplo n.º 18
0
def rtt_clear_attachment_with_timeranges(cfg):
    cfg.aspect_ratio = (1, 1)

    # Time-disabled full screen white quad
    quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    program = ngl.Program(vertex=cfg.get_vert('color'),
                          fragment=cfg.get_frag('color'))
    program.update_vert_out_vars(var_tex0_coord=ngl.IOVec2(),
                                 var_uvcoord=ngl.IOVec2())
    render = ngl.Render(quad, program)
    render.update_frag_resources(color=ngl.UniformVec4(value=COLORS['white']))
    time_range_filter = ngl.TimeRangeFilter(render)
    time_range_filter.add_ranges(ngl.TimeRangeModeNoop(0))

    # Intermediate no-op RTT to force the use of a different render pass internally
    texture = ngl.Texture2D(width=32, height=32)
    rtt_noop = ngl.RenderToTexture(ngl.Identity(), [texture])

    # Centered rotating quad
    quad = ngl.Quad((-0.5, -0.5, 0), (1, 0, 0), (0, 1, 0))
    program = ngl.Program(vertex=cfg.get_vert('color'),
                          fragment=cfg.get_frag('color'))
    program.update_vert_out_vars(var_tex0_coord=ngl.IOVec2(),
                                 var_uvcoord=ngl.IOVec2())
    render = ngl.Render(quad, program)
    render.update_frag_resources(color=ngl.UniformVec4(value=COLORS['orange']))
    animkf = [
        ngl.AnimKeyFrameFloat(0, 0),
        ngl.AnimKeyFrameFloat(cfg.duration, -360)
    ]
    render = ngl.Rotate(render, anim=ngl.AnimatedFloat(animkf))

    group = ngl.Group(children=(time_range_filter, rtt_noop, render))

    # Root RTT
    texture = ngl.Texture2D(width=512, height=512)
    rtt = ngl.RenderToTexture(group, [texture])

    # Full screen render of the root RTT result
    quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    program = ngl.Program(vertex=cfg.get_vert('texture'),
                          fragment=cfg.get_frag('texture'))
    program.update_vert_out_vars(var_tex0_coord=ngl.IOVec2(),
                                 var_uvcoord=ngl.IOVec2())
    render = ngl.Render(quad, program)
    render.update_frag_resources(tex0=texture)

    return ngl.Group(children=(rtt, render))
Exemplo n.º 19
0
def time_remapping(cfg):
    '''
    Time remapping in the following order:
    - nothing displayed for a while (but media prefetch happening in background)
    - first frame displayed for a while
    - normal playback
    - last frame displayed for a while (even though the media is closed)
    - nothing again until the end
    '''
    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),
    ]

    q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    m = ngl.Media(m0.filename, time_anim=ngl.AnimatedTime(media_animkf))
    m.set_sxplayer_min_level('verbose')
    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())
    r = ngl.Render(q, p)
    r.update_frag_resources(tex0=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)

    base_string = 'media time: %2g to %2g\nscene time: %2g to %2g\ntime range: %2g to %2g' % (
        media_seek, media_seek + playback_duration, play_start, play_stop,
        range_start, range_stop)
    text = ngl.Text(base_string,
                    box_height=(0, 0.3, 0),
                    box_corner=(-1, 1 - 0.3, 0),
                    aspect_ratio=cfg.aspect_ratio,
                    halign='left')

    group = ngl.Group()
    group.add_children(rf, text)

    steps = (
        ('default color, nothing yet', 0, noop_duration),
        ('default color, media prefetched', noop_duration, range_start),
        ('first frame', range_start, play_start),
        ('normal playback', play_start, play_stop),
        ('last frame', play_stop, range_stop),
        ('default color, media released', range_stop, duration),
    )

    for i, (description, start_time, end_time) in enumerate(steps):
        text = ngl.Text('%g to %g: %s' % (start_time, end_time, description),
                        aspect_ratio=cfg.aspect_ratio,
                        box_height=(0, 0.2, 0))
        text_tr = (
            ngl.TimeRangeModeNoop(0),
            ngl.TimeRangeModeCont(start_time),
            ngl.TimeRangeModeNoop(end_time),
        )
        text_rf = ngl.TimeRangeFilter(text,
                                      ranges=text_tr,
                                      label='text-step-%d' % i)
        group.add_children(text_rf)

    return ngl.GraphicConfig(group,
                             blend=True,
                             blend_src_factor='src_alpha',
                             blend_dst_factor='one_minus_src_alpha',
                             blend_src_factor_a='zero',
                             blend_dst_factor_a='one')
def time_remapping(cfg):
    """
    Time remapping in the following order:
    - nothing displayed for a while (but media prefetch happening in background)
    - first frame displayed for a while
    - normal playback
    - last frame displayed for a while (even though the media is closed)
    - nothing again until the end
    """
    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))
    m.set_sxplayer_min_level("verbose")
    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)

    base_string = "media time: {:2g} to {:2g}\nscene time: {:2g} to {:2g}\ntime range: {:2g} to {:2g}".format(
        media_seek, media_seek + playback_duration, play_start, play_stop, range_start, range_stop
    )
    text = ngl.Text(
        base_string, box_height=(0, 0.3, 0), box_corner=(-1, 1 - 0.3, 0), aspect_ratio=cfg.aspect_ratio, halign="left"
    )

    group = ngl.Group()
    group.add_children(rf, text)

    steps = (
        ("default color, nothing yet", 0, noop_duration),
        ("default color, media prefetched", noop_duration, range_start),
        ("first frame", range_start, play_start),
        ("normal playback", play_start, play_stop),
        ("last frame", play_stop, range_stop),
        ("default color, media released", range_stop, duration),
    )

    for i, (description, start_time, end_time) in enumerate(steps):
        text = ngl.Text(
            f"{start_time:g} to {end_time:g}: {description}", aspect_ratio=cfg.aspect_ratio, box_height=(0, 0.2, 0)
        )
        text_tr = (
            ngl.TimeRangeModeNoop(0),
            ngl.TimeRangeModeCont(start_time),
            ngl.TimeRangeModeNoop(end_time),
        )
        text_rf = ngl.TimeRangeFilter(text, ranges=text_tr, label="text-step-%d" % i)
        group.add_children(text_rf)

    return group
Exemplo n.º 21
0
def parallel_playback(cfg, fast=True, segment_time=2., 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.
    '''
    q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))

    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')

    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())
    render1 = ngl.Render(q, program, label='render #1')
    render1.update_frag_resources(tex0=t1)
    render2 = ngl.Render(q, program, label='render #2')
    render2.update_frag_resources(tex0=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.)
        rf2.set_prefetch_time(segment_time / 3.)
        rf1.set_max_idle_time(segment_time / 2.)
        rf2.set_max_idle_time(segment_time / 2.)

    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