Video Codec Unit (VCU) Demo Example: TRANSCODE -> STREAMOUT

Introduction

Video Codec Unit (VCU) in ZynqMP SOC is capable of encoding and decoding AVC/HEVC compressed video streams in real time.

This notebook example shows File streaming use case using 2 ZCU106 boards wherein board-1(that acts as server) does video transcode and stream the encoded data over ethernet, board-2 (that acts as client) receives data, decode the data received and renders it on DP/HDMI monitor.

Implementation Details

This example requires two boards, board-1 is used for transcode and stream-out (as a server) and board 2 is used for streaming-in and decode purpose (as a client) or VLC player on the host machine can be used as client instead of board-2 (More details regarding Test Setup for board-2 can be found in stream-in → Decode Example).

Note: This notebook needs to be run along with "vcu-demo-streamin-decode-display.ipynb". The configuration settings below are for Sever side pipeline.

Board Setup

Board-1 is used for transcode and stream-out (as a server)

  1. Connect serial cable to monitor logs on serial console.
  2. If Board is connected to private network, then export proxy settings in /home/root/.bashrc file on board as below,
    • create/open a bashrc file using "vi ~/.bashrc"
      • Insert below line to bashrc file
        • export http_proxy="< private network proxy address >"
        • export https_proxy="< private network proxy address >"
      • Save and close bashrc file.
  3. Make sure input video file is copied to board-1 for streaming.
  4. Connect two boards in the same network so that they can access each other using IP address.
  5. Check server IP.
    • root@zcu106-zynqmp:~#ifconfig
  6. Check client IP on client board.
  7. Check connectivity for board-1 & board-2.
    • root@zcu106-zynqmp:~#ping <board-2's IP>
  8. Provide client's board IP as Client IP parameters.
  9. Run Transcode → stream-out on board-1

In [1]:
from IPython.display import HTML

HTML('''<script>
code_show=true; 
function code_toggle() {
 if (code_show){
 $('div.input').hide();
 } else {
 $('div.input').show();
 }
 code_show = !code_show
} 
$( document ).ready(code_toggle);
</script>
<form action="javascript:code_toggle()"><input type="submit" value="Click here to toggle on/off the raw code."></form>''')


Out[1]:

Run the Demo


In [2]:
from ipywidgets import interact
import ipywidgets as widgets
from common import common_vcu_demo_transcode_to_streamout
import os
from ipywidgets import HBox, VBox, Text, Layout

Insert input file path and host IP


In [3]:
input_path=widgets.Text(value='',
    placeholder='Insert file path',
    description='Input File:',
    #style={'description_width': 'initial'},
    disabled=False)
address_path=widgets.Text(value='',
    placeholder='192.168.1.101 ',
    description='Client IP:',
    disabled=False)
port_number=widgets.Text(value='',
    placeholder='(optional) 50000',
    description='Port No:',
    disabled=False)
HBox([input_path, address_path, port_number])


Output Format


In [4]:
codec_type=widgets.RadioButtons(
    options=['avc', 'hevc'],
    description='Video Codec:',
    disabled=False)
codec_type


Advanced options:


In [5]:
periodicity_idr=widgets.Text(value='',
    placeholder='(optional) 30, 40, 50',
    description='Periodicity Idr:',
    style={'description_width': 'initial'},
    #layout=Layout(width='35%', height='30px'),
    disabled=False)
cpb_size=widgets.Text(value='',
    placeholder='(optional) 1000,2000',
    description='CPB Size:',
    #style={'description_width': 'initial'},
    #layout=Layout(width='35%', height='30px'),
    disabled=False)
HBox([periodicity_idr, cpb_size])



In [6]:
gop_length=widgets.Text(value='',
    placeholder='(optional) 30, 60',
    description='Gop Length:',
    disabled=False)
bit_rate=widgets.Text(value='',
    placeholder='(optional) 1000, 20000',
    description='Bit Rate(Kbps):',
    style={'description_width': 'initial'},
    disabled=False)
HBox([bit_rate, gop_length])



In [7]:
entropy_buffers=widgets.Dropdown(
    options=['2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15'],
    value='5',
    description='Entropy Buffers Nos:',
    style={'description_width': 'initial'},
    disabled=False,)
entropy_buffers
HBox([entropy_buffers])
#HBox([port_number, optional])



In [8]:
from IPython.display import clear_output
from IPython.display import Javascript

def run_all(ev):
    display(Javascript('IPython.notebook.execute_cells_below()'))

def clear_op(event):
    clear_output(wait=True)
    return

button1 = widgets.Button(
    description='Clear Output',
    style= {'button_color':'lightgreen'},
    #style= {'button_color':'lightgreen', 'description_width': 'initial'},
    layout={'width': '300px'}
)
button2 = widgets.Button(
    description='',
    style= {'button_color':'white'},
    #style= {'button_color':'lightgreen', 'description_width': 'initial'},
    layout={'width': '82px'},
    disabled=True
)
button1.on_click(run_all)
button1.on_click(clear_op)

In [9]:
def start_demo(event):
    #clear_output(wait=True)
    arg = common_vcu_demo_transcode_to_streamout.cmd_line_args_generator(input_path.value, bit_rate.value, codec_type.value, address_path.value, port_number.value, entropy_buffers.value, gop_length.value, periodicity_idr.value, cpb_size.value);
    #!sh vcu-demo-transcode-to-streamout.sh $arg > logs.txt 2>&1
    !sh vcu-demo-transcode-to-streamout.sh $arg
    return

button = widgets.Button(
    description='click to start vcu-transcode-to-streamout demo',
    style= {'button_color':'lightgreen'},
    #style= {'button_color':'lightgreen', 'description_width': 'initial'},
    layout={'width': '300px'}
)
button.on_click(start_demo)
HBox([button, button2, button1])