-
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Very first draft of the WebUI, preliminary support for hisi-gen1, new…
… toolchain options
- Loading branch information
Showing
17 changed files
with
3,112 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,243 @@ | ||
<html> | ||
<head> | ||
<title>Divinus</title> | ||
<style> | ||
*{box-sizing:border-box}*+*{margin:.5em 0}pre{overflow:auto}@media(min-width:35em){.col{display:table-cell}.\31{width:5%}.\33{width:22%}.\34{width:30%}.\35{width:40%}.\32{width:15%}.\36{width:50%}.row{display:table;border-spacing:1em 0}}.row,.w-100{width:100%}.card:focus,hr{outline:0;border:solid #fa0}.card,pre{padding:1em;border:solid #eee}.btn:hover,a:hover{opacity:.6}.c{padding:1em;margin:auto;font:1em/1.6 sans-serif}h6{font:400 1em sans-serif}h5{font:400 1.2em sans-serif}h3{font:400 2em sans-serif}h4{font:400 1.5em sans-serif}h2{font:400 2.2em sans-serif}h1{font:400 2.5em sans-serif}a{color:#fa0;text-decoration:none}.btn.primary{color:#fff;background:#fa0;border:solid #fa0}td,th{padding:1em;text-align:left;border-bottom:solid #eee}.btn{padding:1em;text-transform:uppercase;background:#fff;border:solid;font:.7em sans-serif}a.btn{display:inline-block}input,select{font-family:sans-serif} | ||
.white{color:#fff}.bg-white{background-color:#fff}.b-white{border-color:#fff}.gray{color:#ccc}.bg-gray{background-color:#ccc}.b-gray{border-color:#ccc}.black{color:#000}.bg-black{background-color:#000}.b-black{border-color:#000}.accent{color:#fa0}.bg-accent{background-color:#fa0}.b-accent{border-color:#fa0}.warning{color:#ffd600}.bg-warning{background-color:#ffd600}.b-warning{border-color:#ffd600}.error{color:#d50000}.bg-error{background-color:#d50000}.b-error{border-color:#d50000}.success{color:#00c853}.bg-success{background-color:#00c853}.b-success{border-color:#00c853}.info{color:#2962ff}.bg-info{background-color:#2962ff}.b-info{border-color:#2962ff}.m0{margin:0}.m1{margin:.5em}.m2{margin:1em}.m3{margin:2em}.m4{margin:4em}.mt0{margin-top:0}.mt1{margin-top:.5em}.mt2{margin-top:1em}.mt3{margin-top:2em}.mt4{margin-top:4em}.mr0{margin-right:0}.mr1{margin-right:.5em}.mr2{margin-right:1em}.mr3{margin-right:2em}.mr4{margin-right:4em}.mb0{margin-bottom:0}.mb1{margin-bottom:.5em}.mb2{margin-bottom:1em}.mb3{margin-bottom:2em}.mb4{margin-bottom:4em}.ml0{margin-left:0}.ml1{margin-left:.5em}.ml2{margin-left:1em}.ml3{margin-left:2em}.ml4{margin-left:4em}.p0{padding:0}.p1{padding:.5em}.p2{padding:1em}.p3{padding:2em}.p4{padding:4em}.pv0{padding-top:0;padding-bottom:0}.pv1{padding-top:.5em;padding-bottom:.5em}.pv2{padding-top:1em;padding-bottom:1em}.pv3{padding-top:2em;padding-bottom:2em}.pv4{padding-top:4em;padding-bottom:4em}.ph0{padding-right:0;padding-left:0}.ph1{padding-right:.5em;padding-left:.5em}.ph2{padding-right:1em;padding-left:1em}.ph3{padding-right:2em;padding-left:2em}.ph4{padding-right:4em;padding-left:4em}.gapless{border-spacing:0}.vc{position:relative;top:40%;transform:perspective(1px) translateY(-45%)}.pill{border-radius:9999px}.rounded{border-radius:4px}.tc{text-align:center}.mega{font-size:3.5em}.large{font-size:1.5em}.small{font-size:.7em}.caps{text-transform:uppercase}.tracked{letter-spacing:.1em}.vh-100{height:100vh}.inline{display:inline-block}.bold{font-weight:700}.normal{font-weight:400}.light{font-weight:300}.dim{opacity:1;transition:opacity .15s ease-in}.dim:focus,.dim:hover{opacity:.5;transition:opacity .15s ease-in} | ||
dialog{display:block;border:0;padding:0!important}dialog:not(:target):not([open]){display:none}.hid{display:none} | ||
</style> | ||
<script> | ||
var ua = window.navigator.userAgent; | ||
var isIe = ua.indexOf('MSIE ') > -1 || ua.indexOf('Trident/') > -1; | ||
|
||
function apiApply(endp) { | ||
var dest = "/api/"+endp+"?", req = new XMLHttpRequest(); | ||
var elems = document.getElementsByTagName('*'); | ||
for (var i = 0; i < elems.length; i++) { | ||
if (!elems[i].name || elems[i].name.lastIndexOf(endp + '_', 0)) continue; | ||
dest += elems[i].name.substring(endp.length + 1) + '=' + elems[i].value + '&'; | ||
} | ||
dest = dest.slice(0, -1); | ||
req.open('GET', dest); | ||
req.send(); | ||
} | ||
|
||
function apiRead(endp) { | ||
var req = new XMLHttpRequest(); | ||
req.onreadystatechange = function() { | ||
if (this.readyState != 4 || this.status != 200) return; | ||
var dec = JSON.parse(req.responseText); | ||
for (var key in dec) { | ||
if (!dec.hasOwnProperty(key)) continue; | ||
var elem = document.getElementById(endp + '_' + key); | ||
if (!elem) continue; | ||
elem.value = dec[key]; | ||
} | ||
} | ||
req.open('GET', '/api/'+endp); | ||
req.send(); | ||
} | ||
|
||
function logout() { | ||
if (isIe) | ||
document.execCommand('ClearAuthenticationCache', 'false'); | ||
else | ||
window.location = window.location.href.replace('://', '://log:out@'); | ||
} | ||
|
||
function setSource(id, src) { | ||
var frame = document.getElementById(id), ext = ".mp4"; | ||
if (frame.firstChild) frame.firstChild.src = "#"; | ||
if (src.indexOf(ext, src.length - ext.length) > -1) | ||
frame.innerHTML = '<video id="player" src="'+src+'" width="100%" autoplay controls>'; | ||
else if (src) | ||
frame.innerHTML = '<img src="'+src+'" width="100%">'; | ||
else | ||
while (frame.firstChild) frame.removeChild(frame.firstChild); | ||
} | ||
|
||
function onLoad() { | ||
apiRead('audio'); | ||
apiRead('mp4'); | ||
apiRead('mjpeg'); | ||
apiRead('jpeg'); | ||
apiRead('night'); | ||
} | ||
</script> | ||
</head> | ||
<body class="m0" onload="onLoad()"> | ||
<noscript> | ||
<div class="tc vh-100 bg-info"> | ||
<div class="vc c white"> | ||
<h1 class="mega mb0">Divinus</h1> | ||
<p class="large mb2">Error: JavaScript is required to access this page!</p> | ||
</div> | ||
</div> | ||
</noscript> | ||
<dialog id="live" class="c vh-100 w-100"> | ||
<div class="c bg-black pv2 row"> | ||
<div class="col"> | ||
<b><a href="./" class="white ph2">Divinus</a></b> | ||
<span class="ph2 gray">Live</span> | ||
<a href="javascript:setSource('preview', 'video.mp4')" class="ph2">MP4</a> | ||
<a href="javascript:setSource('preview', 'mjpeg')" class="ph2">MJPEG</a> | ||
<a href="javascript:setSource('preview', '')" class="ph2">Stop</a> | ||
</div> | ||
<div class="1 col"> | ||
<a class="btn primary" href="#!">Close</a> | ||
</div> | ||
</div> | ||
<div id="preview" width="100%"> | ||
</dialog> | ||
<dialog id="media" class="c vh-100 w-100"> | ||
<div class="c bg-black pv2 row"> | ||
<div class="col"> | ||
<b><a href="./" class="white ph2">Divinus</a></b> | ||
<span class="ph2 gray">Media</span> | ||
</div> | ||
<div class="1 col"> | ||
<a class="btn primary" href="#!">Close</a> | ||
</div> | ||
</div> | ||
<div class="c row"> | ||
<fieldset> | ||
<legend>Audio</legend> | ||
<table> | ||
<tr> | ||
<td><label for="audio_bitrate">Bitrate (kbps)</label></td> | ||
<td><input type="number" id="audio_bitrate" name="audio_bitrate"></td> | ||
</tr> | ||
<tr> | ||
<td><label for="audio_srate">Sample rate (Hz)</label></td> | ||
<td><input type="number" id="audio_srate" name="audio_srate"></td> | ||
</tr> | ||
</table> | ||
<a href="javascript:apiApply('audio')" class="btn">Apply</a> | ||
</fieldset> | ||
</div> | ||
<div class="c row"> | ||
<fieldset> | ||
<legend>MP4</legend> | ||
<table> | ||
<tr> | ||
<td><label for="mp4_width">Width</label></td> | ||
<td><input type="number" id="mp4_width" name="mp4_width"></td> | ||
</tr> | ||
<tr> | ||
<td><label for="mp4_height">Height</label> | ||
<td><input type="number" id="mp4_height" name="mp4_height"></td> | ||
</tr> | ||
<tr> | ||
<td><label for="mp4_fps">Framerate</label></td> | ||
<td><input type="number" id="mp4_fps" name="mp4_fps"></td> | ||
</tr> | ||
<tr> | ||
<td><label for="mp4_bitrate">Bitrate (kbps)</label></td> | ||
<td><input type="number" id="mp4_bitrate" name="mp4_bitrate"></td> | ||
</tr> | ||
<tr> | ||
<td><label for="mp4_h265">Codec</label></td> | ||
<td><select id="mp4_h265" name="mp4_h265"> | ||
<option value="false">H.264</option> | ||
<option value="true">H.265</option> | ||
</select></td> | ||
</tr> | ||
<tr> | ||
<td><label for="mp4_mode">Rate control</label></td> | ||
<td><select id="mp4_mode" name="mp4_mode"> | ||
<option value="CBR">CBR</option> | ||
<option value="VBR">VBR</option> | ||
<option value="QP">QP</option> | ||
<option value="ABR">ABR</option> | ||
<option value="AVBR">AVBR</option> | ||
</select></td> | ||
</tr> | ||
<tr> | ||
<td><label for="mp4_profile">Profile</label></td> | ||
<td><select id="mp4_profile" name="mp4_profile"> | ||
<option value="BP">Baseline</option> | ||
<option value="MP">Main</option> | ||
<option value="HP">High</option> | ||
</select></td> | ||
</tr> | ||
</table> | ||
<a href="javascript:apiApply('mp4')" class="btn">Apply</a> | ||
</fieldset> | ||
</div> | ||
<div class="c row"> | ||
<fieldset> | ||
<legend>MJPEG</legend> | ||
<table> | ||
<tr> | ||
<td><label for="mjpeg_width">Width</label></td> | ||
<td><input type="number" id="mjpeg_width" name="mjpeg_width"></td> | ||
</tr> | ||
<tr> | ||
<td><label for="mjpeg_height">Height</label></td> | ||
<td><input type="number" id="mjpeg_height" name="mjpeg_height"></td> | ||
</tr> | ||
<tr> | ||
<td><label for="mjpeg_fps">Framerate</label></td> | ||
<td><input type="number" id="mjpeg_fps" name="mjpeg_fps"></td> | ||
</tr> | ||
<tr> | ||
<td><label for="mjpeg_mode">Rate control</label></td> | ||
<td><select id="mjpeg_mode" name="mjpeg_mode"> | ||
<option value="CBR">CBR</option> | ||
<option value="VBR">VBR</option> | ||
<option value="QP">QP</option> | ||
</select></td> | ||
</tr> | ||
</table> | ||
<a href="javascript:apiApply('mjpeg')" class="btn">Apply</a> | ||
</fieldset> | ||
</div> | ||
<div class="c row"> | ||
<fieldset> | ||
<legend>JPEG</legend> | ||
<table> | ||
<tr> | ||
<td><label for="jpeg_width">Width</label></td> | ||
<td><input type="number" id="jpeg_width" name="jpeg_width"></td> | ||
</tr> | ||
<tr> | ||
<td><label for="jpeg_height">Height</label></td> | ||
<td><input type="number" id="jpeg_height" name="jpeg_height"></td> | ||
</tr> | ||
<tr> | ||
<td><label for="jpeg_qfactor">Quality (%)</label></td> | ||
<td><input type="number" id="jpeg_qfactor" name="jpeg_qfactor"></td> | ||
</tr> | ||
</table> | ||
<a href="javascript:apiApply('jpeg')" class="btn">Apply</a> | ||
</fieldset> | ||
</div> | ||
<div class="c row"> | ||
<fieldset> | ||
<legend>Night</legend> | ||
<table> | ||
<tr> | ||
<td><label for="night_active">Manual</label></td> | ||
<td><select id="night_active" name="night_active"> | ||
<option value="false">OFF</option> | ||
<option value="true">ON</option> | ||
</select></td> | ||
</tr> | ||
</table> | ||
<a href="javascript:apiApply('night')" class="btn">Apply</a> | ||
</fieldset> | ||
</div> | ||
</dialog> | ||
<div class="c bg-black pv2 row"> | ||
<div class="col"> | ||
<b><a href="./" class="ph2 white">Divinus</a></b> | ||
<a href="#live" class="ph2 white">Live</a> | ||
<a href="#media" class="ph2 white">Media</a> | ||
<a href="image.jpg" class="ph2 white" target="_blank">Snapshot</a> | ||
</div> | ||
<div class="1 col"> | ||
<a href="javascript:logout()" class="btn ph2 black">Logout</a> | ||
</div> | ||
</div> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
#pragma once | ||
|
||
#include "v1_common.h" | ||
|
||
#define V1_AUD_CHN_NUM 2 | ||
|
||
typedef enum { | ||
V1_AUD_BIT_8, | ||
V1_AUD_BIT_16, | ||
V1_AUD_BIT_24 | ||
} v1_aud_bit; | ||
|
||
typedef enum { | ||
V1_AUD_INTF_I2S_MASTER, | ||
V1_AUD_INTF_I2S_SLAVE, | ||
V1_AUD_INTF_PCM_SLAVE_STD, | ||
V1_AUD_INTF_PCM_SLAVE_NSTD, | ||
V1_AUD_INTF_PCM_MASTER_STD, | ||
V1_AUD_INTF_PCM_MASTER_NSTD, | ||
V1_AUD_INTF_END | ||
} v1_aud_intf; | ||
|
||
typedef struct { | ||
// Accept industry standards from | ||
// 8000 to 96000Hz, plus 64000Hz | ||
int rate; | ||
v1_aud_bit bit; | ||
v1_aud_intf intf; | ||
int stereoOn; | ||
// 8-to-16 bit, expand mode | ||
unsigned int expandOn; | ||
unsigned int frmNum; | ||
unsigned int packNumPerFrm; | ||
unsigned int chnNum; | ||
unsigned int syncRxClkOn; | ||
} v1_aud_cnf; | ||
|
||
typedef struct { | ||
v1_aud_bit bit; | ||
int stereoOn; | ||
void *addr[2]; | ||
unsigned int phy[2]; | ||
unsigned long long timestamp; | ||
unsigned int sequence; | ||
unsigned int length; | ||
unsigned int poolId[2]; | ||
} v1_aud_frm; | ||
|
||
typedef struct { | ||
v1_aud_frm frame; | ||
char isValid; | ||
char isSysBound; | ||
} v1_aud_efrm; | ||
|
||
typedef struct { | ||
void *handle; | ||
|
||
int (*fnDisableDevice)(int device); | ||
int (*fnEnableDevice)(int device); | ||
int (*fnSetDeviceConfig)(int device, v1_aud_cnf *config); | ||
|
||
int (*fnDisableChannel)(int device, int channel); | ||
int (*fnEnableChannel)(int device, int channel); | ||
|
||
int (*fnFreeFrame)(int device, int channel, v1_aud_frm *frame, v1_aud_efrm *encFrame); | ||
int (*fnGetFrame)(int device, int channel, v1_aud_frm *frame, v1_aud_efrm *encFrame, int millis); | ||
} v1_aud_impl; | ||
|
||
static int v1_aud_load(v1_aud_impl *aud_lib) { | ||
if (!(aud_lib->handle = dlopen("libmpi.so", RTLD_LAZY | RTLD_GLOBAL))) | ||
HAL_ERROR("v1_aud", "Failed to load library!\nError: %s\n", dlerror()); | ||
|
||
if (!(aud_lib->fnDisableDevice = (int(*)(int device)) | ||
hal_symbol_load("v1_aud", aud_lib->handle, "HI_MPI_AI_Disable"))) | ||
return EXIT_FAILURE; | ||
|
||
if (!(aud_lib->fnEnableDevice = (int(*)(int device)) | ||
hal_symbol_load("v1_aud", aud_lib->handle, "HI_MPI_AI_Enable"))) | ||
return EXIT_FAILURE; | ||
|
||
if (!(aud_lib->fnSetDeviceConfig = (int(*)(int device, v1_aud_cnf *config)) | ||
hal_symbol_load("v1_aud", aud_lib->handle, "HI_MPI_AI_SetPubAttr"))) | ||
return EXIT_FAILURE; | ||
|
||
if (!(aud_lib->fnDisableChannel = (int(*)(int device, int channel)) | ||
hal_symbol_load("v1_aud", aud_lib->handle, "HI_MPI_AI_DisableChn"))) | ||
return EXIT_FAILURE; | ||
|
||
if (!(aud_lib->fnEnableChannel = (int(*)(int device, int channel)) | ||
hal_symbol_load("v1_aud", aud_lib->handle, "HI_MPI_AI_EnableChn"))) | ||
return EXIT_FAILURE; | ||
|
||
if (!(aud_lib->fnFreeFrame = (int(*)(int device, int channel, v1_aud_frm *frame, v1_aud_efrm *encFrame)) | ||
hal_symbol_load("v1_aud", aud_lib->handle, "HI_MPI_AI_ReleaseFrame"))) | ||
return EXIT_FAILURE; | ||
|
||
if (!(aud_lib->fnGetFrame = (int(*)(int device, int channel, v1_aud_frm *frame, v1_aud_efrm *encFrame, int millis)) | ||
hal_symbol_load("v1_aud", aud_lib->handle, "HI_MPI_AI_GetFrame"))) | ||
return EXIT_FAILURE; | ||
|
||
return EXIT_SUCCESS; | ||
} | ||
|
||
static void v1_aud_unload(v1_aud_impl *aud_lib) { | ||
if (aud_lib->handle) dlclose(aud_lib->handle); | ||
aud_lib->handle = NULL; | ||
memset(aud_lib, 0, sizeof(*aud_lib)); | ||
} |
Oops, something went wrong.