{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Video Codec Unit (VCU) Demo Example: TRANSCODE -> STREAMOUT "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Introduction\n",
    "\n",
    "Video Codec Unit (VCU) in ZynqMP SOC is capable of encoding and decoding AVC/HEVC compressed video streams in real time. \n",
    "\n",
    "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. \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Implementation Details\n",
    "\n",
    "<img src=\"pictures/block-diagram-transcode-streamout.png\" align=\"center\" alt=\"Drawing\" style=\"width: 1000px; height: 200px\"/>\n",
    "\n",
    "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).\n",
    "\n",
    "__Note:__ This notebook needs to be run along with \"vcu-demo-streamin-decode-display.ipynb\". The configuration settings below are for Sever side pipeline. \n",
    "\n",
    "### Board Setup \n",
    "**Board-1 is used for transcode and stream-out (as a server)**\n",
    " 1. Connect serial cable to monitor logs on serial console.\n",
    " 2. If Board is connected to private network, then export proxy settings in /home/root/.bashrc file on board as below,\n",
    "    - create/open a bashrc file using \"vi ~/.bashrc\" \n",
    "        - Insert below line to bashrc file\n",
    "            - export http_proxy=\"< private network proxy address >\"\n",
    "            - export https_proxy=\"< private network proxy address >\"\n",
    "        - Save and close bashrc file. \n",
    " 3. Make sure input video file is copied to board-1 for streaming.\n",
    " 4. Connect two boards in the same network so that they can access each other using IP address.\n",
    " 5. Check server IP.\n",
    "    - root@zcu106-zynqmp:~#ifconfig\n",
    " 6. Check client IP on client board.\n",
    " 7. Check connectivity for board-1 & board-2.\n",
    "    - root@zcu106-zynqmp:~#ping <board-2's IP>\n",
    " 8. Provide client's board IP as Client IP parameters.\n",
    " 9. Run Transcode → stream-out on board-1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<script>\n",
       "code_show=true; \n",
       "function code_toggle() {\n",
       " if (code_show){\n",
       " $('div.input').hide();\n",
       " } else {\n",
       " $('div.input').show();\n",
       " }\n",
       " code_show = !code_show\n",
       "} \n",
       "$( document ).ready(code_toggle);\n",
       "</script>\n",
       "<form action=\"javascript:code_toggle()\"><input type=\"submit\" value=\"Click here to toggle on/off the raw code.\"></form>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from IPython.display import HTML\n",
    "\n",
    "HTML('''<script>\n",
    "code_show=true; \n",
    "function code_toggle() {\n",
    " if (code_show){\n",
    " $('div.input').hide();\n",
    " } else {\n",
    " $('div.input').show();\n",
    " }\n",
    " code_show = !code_show\n",
    "} \n",
    "$( document ).ready(code_toggle);\n",
    "</script>\n",
    "<form action=\"javascript:code_toggle()\"><input type=\"submit\" value=\"Click here to toggle on/off the raw code.\"></form>''')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Run the Demo"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from ipywidgets import interact\n",
    "import ipywidgets as widgets\n",
    "from common import common_vcu_demo_transcode_to_streamout\n",
    "import os\n",
    "from ipywidgets import HBox, VBox, Text, Layout"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Insert input file path and host IP"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "a5c1b70870b5430abf851ef09aad5fcd",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "HBox(children=(Text(value='', description='Input File:', placeholder='Insert file path'), Text(value='', descr…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "input_path=widgets.Text(value='',\n",
    "    placeholder='Insert file path',\n",
    "    description='Input File:',\n",
    "    #style={'description_width': 'initial'},\n",
    "    disabled=False)\n",
    "address_path=widgets.Text(value='',\n",
    "    placeholder='192.168.1.101 ',\n",
    "    description='Client IP:',\n",
    "    disabled=False)\n",
    "port_number=widgets.Text(value='',\n",
    "    placeholder='(optional) 50000',\n",
    "    description='Port No:',\n",
    "    disabled=False)\n",
    "HBox([input_path, address_path, port_number])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Output Format "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "4f464c4a9bf3420e84f5566b166b5dc7",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "RadioButtons(description='Video Codec:', options=('avc', 'hevc'), value='avc')"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "codec_type=widgets.RadioButtons(\n",
    "    options=['avc', 'hevc'],\n",
    "    description='Video Codec:',\n",
    "    disabled=False)\n",
    "codec_type"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Advanced options:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "85023be4d126407e9f9b68b8a93c73d1",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "HBox(children=(Text(value='', description='Periodicity Idr:', placeholder='(optional) 30, 40, 50', style=Descr…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "periodicity_idr=widgets.Text(value='',\n",
    "    placeholder='(optional) 30, 40, 50',\n",
    "    description='Periodicity Idr:',\n",
    "    style={'description_width': 'initial'},\n",
    "    #layout=Layout(width='35%', height='30px'),\n",
    "    disabled=False)\n",
    "cpb_size=widgets.Text(value='',\n",
    "    placeholder='(optional) 1000,2000',\n",
    "    description='CPB Size:',\n",
    "    #style={'description_width': 'initial'},\n",
    "    #layout=Layout(width='35%', height='30px'),\n",
    "    disabled=False)\n",
    "HBox([periodicity_idr, cpb_size])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "dc2a219e598e47778537836710cd5541",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "HBox(children=(Text(value='', description='Bit Rate(Kbps):', placeholder='(optional) 1000, 20000', style=Descr…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "gop_length=widgets.Text(value='',\n",
    "    placeholder='(optional) 30, 60',\n",
    "    description='Gop Length:',\n",
    "    disabled=False)\n",
    "bit_rate=widgets.Text(value='',\n",
    "    placeholder='(optional) 1000, 20000',\n",
    "    description='Bit Rate(Kbps):',\n",
    "    style={'description_width': 'initial'},\n",
    "    disabled=False)\n",
    "HBox([bit_rate, gop_length])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "3df12e97241c41faa594432f0f00d5ca",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "HBox(children=(Dropdown(description='Entropy Buffers Nos:', index=3, options=('2', '3', '4', '5', '6', '7', '8…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "entropy_buffers=widgets.Dropdown(\n",
    "    options=['2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15'],\n",
    "    value='5',\n",
    "    description='Entropy Buffers Nos:',\n",
    "    style={'description_width': 'initial'},\n",
    "    disabled=False,)\n",
    "entropy_buffers\n",
    "HBox([entropy_buffers])\n",
    "#HBox([port_number, optional])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "from IPython.display import clear_output\n",
    "from IPython.display import Javascript\n",
    "\n",
    "def run_all(ev):\n",
    "    display(Javascript('IPython.notebook.execute_cells_below()'))\n",
    "\n",
    "def clear_op(event):\n",
    "    clear_output(wait=True)\n",
    "    return\n",
    "\n",
    "button1 = widgets.Button(\n",
    "    description='Clear Output',\n",
    "    style= {'button_color':'lightgreen'},\n",
    "    #style= {'button_color':'lightgreen', 'description_width': 'initial'},\n",
    "    layout={'width': '300px'}\n",
    ")\n",
    "button2 = widgets.Button(\n",
    "    description='',\n",
    "    style= {'button_color':'white'},\n",
    "    #style= {'button_color':'lightgreen', 'description_width': 'initial'},\n",
    "    layout={'width': '82px'},\n",
    "    disabled=True\n",
    ")\n",
    "button1.on_click(run_all)\n",
    "button1.on_click(clear_op)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "e4bb1b3b6b1e431ca0e2d54a508ee3e1",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "HBox(children=(Button(description='click to start vcu-transcode-to-streamout demo', layout=Layout(width='300px…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "def start_demo(event):\n",
    "    #clear_output(wait=True)\n",
    "    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);\n",
    "    #!sh vcu-demo-transcode-to-streamout.sh $arg > logs.txt 2>&1\n",
    "    !sh vcu-demo-transcode-to-streamout.sh $arg\n",
    "    return\n",
    "\n",
    "button = widgets.Button(\n",
    "    description='click to start vcu-transcode-to-streamout demo',\n",
    "    style= {'button_color':'lightgreen'},\n",
    "    #style= {'button_color':'lightgreen', 'description_width': 'initial'},\n",
    "    layout={'width': '300px'}\n",
    ")\n",
    "button.on_click(start_demo)\n",
    "HBox([button, button2, button1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# References\n",
    "[1] https://xilinx-wiki.atlassian.net/wiki/spaces/A/pages/18842546/Xilinx+Video+Codec+Unit\n",
    "\n",
    "[2] https://www.xilinx.com/support.html#documentation (Refer to PG252)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
