The following prorgram shows how to feed data into FFMPEG and get data from FFMPEG and display it. The program is based on Windows Python. Here are the features:
|
import numpy as np import cv2 import subprocess as sp import threading import sys import re import time class VidDecCtx(): FFMPEG_CMD = [ \ 'c:\\Program Files (x86)\\WinFF\\ffmpeg.exe', '-i', 'pipe:', \ '-f', 'rawvideo', '-pix_fmt', 'bgr24', '-an', '-sn', 'pipe:' \ ] DEFAULT_STOP_CNT = 100 READ_BUF_SIZE = 1024 READ_DECODE_BUF_SIZE = 100*1024 def __init__(self): self.process = None self.pthread = None self.buf = bytearray() self.fp = None self.toStopRunCnt = 0 self.isRunning = False def openVidFile(self, vFile): try: self.fp = open(vFile, 'rb') except Exception as e: self.fp = None return False return True def writer(self, toBuffer): while self.isRunning: if not toBuffer and len(self.buf)>0: time.sleep(0) byte_s = self.buf[0:VidDecCtx.READ_BUF_SIZE] self.buf = self.buf[VidDecCtx.READ_BUF_SIZE:] else: byte_s = self.fp.read(VidDecCtx.READ_BUF_SIZE) if toBuffer: self.buf += bytearray(byte_s) if not byte_s: break self.process.stdin.write(byte_s) self.toStopRunCnt = (self.toStopRunCnt-1) if self.toStopRunCnt>0 else 0 if self.toStopRunCnt==1: break self.process.stdin.close() self.toStopRunCnt = 0 self.isRunning = False def prepareGetDim(self): self.process = sp.Popen(VidDecCtx.FFMPEG_CMD, stdin=sp.PIPE, stderr=sp.STDOUT, \ stdout=sp.PIPE, bufsize=VidDecCtx.READ_DECODE_BUF_SIZE) self.isRunning = True self.pthread = threading.Thread(target=self.writer, args=[True]) self.pthread.start() def prepareDecode(self): self.process = sp.Popen(VidDecCtx.FFMPEG_CMD, stdin=sp.PIPE, stderr=sp.DEVNULL, \ stdout=sp.PIPE, bufsize=VidDecCtx.READ_BUF_SIZE) self.isRunning = True self.pthread = threading.Thread(target=self.writer, args=[False]) self.pthread.start() def stopThread(self): # need to continue to feed some data so that can quit gracefully self.toStopRunCnt = VidDecCtx.DEFAULT_STOP_CNT def cleanupThread(self): if self.pthread is not None: self.pthread.join() self.pthread=None if self.process is not None: try: self.process.wait(0.1) except (sp.TimeoutExpired): self.process.kill() self.process = None def finish(self): if self.fp is not None: self.fp.close() self.fp = None class LineBuffer(): def __init__(self): self.strBuf = bytearray() self.prevStrBufSearchIdx = 0 def feedBytes(self, byte_s): # Extract printable characters, and process line bye line tmp = filter(lambda x: x==0xa or x==0xd or (x>=0x20 and x<=0x7f), byte_s) self.strBuf += bytearray(tmp) def getLine(self): tmp=self.strBuf.find(0xa, self.prevStrBufSearchIdx) if tmp==-1: self.prevStrBufSearchIdx = len(self.strBuf) return None else: # do something to self.strBuf[:tmp] tmpStr=self.strBuf[:tmp].decode() self.strBuf = self.strBuf[tmp+1:] self.prevStrBufSearchIdx=0 return tmpStr if __name__ == "__main__": if len(sys.argv)!=2: print("Usage: c:\Python\python37\python %s vFile"%sys.argv[0], file=sys.stderr) sys.exit() vDCtx = VidDecCtx() lineBuf = LineBuffer() if not vDCtx.openVidFile(sys.argv[1]): print("Failed to open %s"%sys.argv[1], file=sys.stderr) sys.exit() width = None height = None bufSize = 1024 dimRegEx = re.compile(' *?Stream #.*?Video:.*?, *(\d+)x(\d+),') ######################################### # get dimension vDCtx.prepareGetDim() while vDCtx.isRunning: in_bytes = vDCtx.process.stdout.read(bufSize) if not in_bytes: break; if width is None: lineBuf.feedBytes(in_bytes) while True: tmpStr=lineBuf.getLine() if tmpStr is None: break tmpMatch=dimRegEx.match(tmpStr) if tmpMatch is not None: width=int(tmpMatch.group(1)) height=int(tmpMatch.group(2)) vDCtx.stopThread() break vDCtx.cleanupThread() if width is None: print("Failed to get the dimension of video", file=sys.stderr) sys.exit() print("Video dimension: (%d,%d)"%(width, height), file=sys.stderr) print("Buffered video data: %d"%(len(vDCtx.buf)), file=sys.stderr) ######################################### # decoding bufSize=width*height*3 vDCtx.prepareDecode() while vDCtx.isRunning: in_bytes = vDCtx.process.stdout.read(bufSize) if not in_bytes: break; # Transform the byte read into a NumPy array in_frame = (np.frombuffer(in_bytes, np.uint8).reshape([height, width, 3])) # Display the frame (for testing) cv2.imshow('in_frame', in_frame) if cv2.waitKey(1) & 0xFF == ord('q'): vDCtx.stopThread() vDCtx.cleanupThread() vDCtx.finish() |
歪林網誌
本來這個blog是記錄開發輸入法的點滴的,後來越來越雜,現在什麼都記錄了。
2020年8月23日 星期日
How to use ffmpeg to convert and display video in Python (Windows)?
2018年12月28日 星期五
How to run a standalone GUI program without any desktop in Raspberry Pi (Raspbian Lite)?
How to run a standalone GUI program without any desktop in Raspberry Pi (Raspbian
Lite)?
[1]: http://xpt.sourceforge.net/techdocs/nix/x/general/xwin03-WinManagerdesktopsChoosing/ar01s04.html
- Install Raspbian Lite into Raspberry Pi
- Upgrade the Raspbian Lite:
sudo apt-get install update - Install lightdm and xinit
sudo apt-get install lightdm xinit - Depends on whether you need user to login or not, set it in:
sudo raspi-config > Boot Options > Desktop / CLI
- Now when you reboot, you will see the desktop with Xterm launched.
- According to [1], this is why the xterm is launched:
- /etc/X11/xinitrc
- which runs . /etc/X11/Xsessions
- which runs all scripts in /etc/X11/Xsession.d
- which runs /etc/X11/Xsession.d/99x11-common_start
- which runs $STARTUP
- if ~/.xsession is defined, then $STARTUP is ~/.xsession
- To launch other program, create ~/.xsession, added content like:
chromium-browser --start-fullscreen - In 201x, Google introduces the No Tofu font. To install it: sudo apt-get install fonts-noto
[1]: http://xpt.sourceforge.net/techdocs/nix/x/general/xwin03-WinManagerdesktopsChoosing/ar01s04.html
2018年4月30日 星期一
如何從荃灣步行到青衣
2016年1月5日 星期二
Cross compile subversion server (svnserve) from scratch for openwrt:
Unfortunately svnserve is not likely to be availabe in the chaos calmer (15.05) version of of openwrt.
This article describes how to cross compile svnserve (with very basic funtionality) from scratch with the toolchain.
It assumed the "mvebu" toolchain for the router Linksys WRT1200AC / WRT1900AC, but the procedures are similar for other routers.
(Reference: https://forum.openwrt.org/viewtopic.php?id=11693)
mkdir /tmp/svn_repos
svnadmin create --fs-type fsfs /tmp/svn_repos
Added 3 lines to setup svn password:
In /tmp/svn_repos/conf/svnserve.conf, uncomment the folowing 3 lines
anon-access = read
auth-access = write
password-db = passwd
Add in /tmp/svn_repos/conf/passwd, password for "yylam"
To restart svn server is in /etc/rc.local
/usr/bin/svnserve -d -r /tmp/svn_repos
From OpenWrt forum: Looks like the same SVN package from the OpenWRT old_packages git repository. To reactivate the old_packages, add the following line to your feeds.conf file.
This article describes how to cross compile svnserve (with very basic funtionality) from scratch with the toolchain.
It assumed the "mvebu" toolchain for the router Linksys WRT1200AC / WRT1900AC, but the procedures are similar for other routers.
- Download the toolchain for WRT1200AC OpenWrt-Toolchain-mvebu_gcc-5.2.0_musl-1.1.11_eabi.Linux-x86_64.tar.bz2
- Download subversion-1.6.23.tar.gz.
- Download apr-1.2.12.tar.bz2
- Download apr-util-1.2.12.tar.bz2
- Download sqlite-amalgamation-3.6.13.tar.gz
- Download zlib-1.2.8.tar.gz
- Assume working directory is: /home/dev/svn_wrt1200ac.
Put all source files above in /home/dev/svn_wrt1200ac/archive.
cd /home/dev/svn_wrt1200ac - Add cross compiler in PATH.
tar xjvf archive/OpenWrt-Toolchain-mvebu_gcc-5.2.0_musl-1.1.11_eabi.Linux-x86_64.tar.bz2
export PATH=$PATH:/home/dev/svn_wrt1200ac/OpenWrt-Toolchain-mvebu_gcc-5.2.0_musl-1.1.11_eabi.Linux-x86_64/toolchain-arm_cortex-a9+vfpv3_gcc-5.2.0_musl-1.1.11_eabi/bin/
Run arm-openwrt-linux-gcc to see if you can run the executable
- Decompress the sources files in the right positions:
tar xzvf archive/subversion-1.6.23.tar.gz
tar xjvf archive/apr-1.2.12.tar.bz2
tar xjvf archive/apr-util-1.2.12.tar.bz2
tar xzvf archive/zlib-1.2.8.tar.gz
tar xzvf archive/sqlite-amalgamation-3.6.13.tar.gz
cd subversion-1.6.23
ln -s ../sqlite-3.6.13/ sqlite-amalgamation
- Compile zlib first
cd ../zlib-1.2.8
CC=arm-openwrt-linux-gcc ./configure --prefix=/home/dev/svn_wrt1200ac/finalBins/usr
make install
- Compile apr
cd ../apr-1.2.12/
./configure --host=arm-openwrt-linux \
ac_cv_file__dev_zero="yes" \
ac_cv_func_setpgrp_void="yes" \
apr_cv_process_shared_works="yes" \
apr_cv_mutex_robust_shared="no" \
apr_cv_tcp_nodelay_with_cork="no" \
ac_cv_sizeof_struct_iovec="8" \
apr_cv_mutex_recursive="yes" \
--prefix=/home/dev/svn_wrt1200ac/finalBins/usr
patch -p 0 include/apr.h
Copy and paste the following, and then press Ctrl+D
@@ -355,10 +355,10 @@
* to find the logic for this definition search for "ssize_t_fmt" in
* configure.in.
*/
-#error Can not determine the proper size for ssize_t
+#define APR_SSIZE_T_FMT "d"
/* And APR_SIZE_T_FMT */
-#error Can not determine the proper size for size_t
+#define APR_SIZE_T_FMT "d"
/* And APR_OFF_T_FMT */
#define APR_OFF_T_FMT APR_INT64_T_FMT
Start compile.
make install
-
Compile apr-util
cd ../apr-util-1.2.12/
cd xml/expat
./configure --host=arm-openwrt-linux --prefix=/home/dev/svn_wrt1200ac/finalBins/usr
make install
cd ../../
./configure --host=arm-openwrt-linux --with-apr=/home/dev/svn_wrt1200ac/finalBins/usr \
--with-expat=/home/dev/svn_wrt1200ac/finalBins/usr \
--prefix=/home/dev/svn_wrt1200ac/finalBins/usr
make install
- Compile subversion
cd ../subversion-1.6.23
./configure --host=arm-openwrt-linux \
--with-zlib=/home/dev/svn_wrt1200ac/finalBins/usr \
--with-apr=/home/dev/svn_wrt1200ac/finalBins/usr \
--with-apr-util=/home/dev/svn_wrt1200ac/finalBins/usr \
--prefix=/home/dev/svn_wrt1200ac/finalBins/usr \
--without-berkeley-db
make install
- Making tarball and transfer to router.
cd ../finalBins
tar -czvf svn1.6.23_wrt1200ac_finalBins.tar.gz usr/lib/lib*so* usr/bin
Transfer the svn1.6.23_wrt1200ac_finalBins.tar.gz to router. Assume /tmp/svn_wrt1200ac_finalBins.tar.gz. e.g.:
scp svn1.6.23_wrt1200ac_finalBins.tar.gz root@192.168.1.1:/tmp/
In router, decompress:
cd /
tar -xzvf /tmp/svn1.6.23_wrt1200ac_finalBins.tar.gz
(Reference: https://forum.openwrt.org/viewtopic.php?id=11693)
mkdir /tmp/svn_repos
svnadmin create --fs-type fsfs /tmp/svn_repos
Added 3 lines to setup svn password:
In /tmp/svn_repos/conf/svnserve.conf, uncomment the folowing 3 lines
anon-access = read
auth-access = write
password-db = passwd
Add in /tmp/svn_repos/conf/passwd, password for "yylam"
To restart svn server is in /etc/rc.local
/usr/bin/svnserve -d -r /tmp/svn_repos
From OpenWrt forum: Looks like the same SVN package from the OpenWRT old_packages git repository. To reactivate the old_packages, add the following line to your feeds.conf file.
src-git old_packages git://git.openwrt.org/packages.githen, once you run scripts/feeds update old_packages; scripts/feeds install -a -p old_packages to update your OpenWRT, execute make menuconfig and enable the subversion package under Network --> Version Control Systems and then recompile your OpenWRT. If you don't like to add the old_packages, then either port the subversion package from the old_repository to OpenWRT GitHUB or wait for someone else to do this for you.
2015年1月18日 星期日
How to install cygwin ssh server and ensure auto login (using RSA public key)
How to install cygwin ssh server and ensure auto login (using RSA public key)
(based on http://techtorials.me/cygwin/sshd-configuration/)- In case you want to uninstall a previously installed CYGWIN ssh server:
(based on http://superuser.com/questions/110726/how-to-uninstall-reinstall-cygwin-to-use-the-sshd)
In a Cygwin terminal, type the following:# Remove sshd service
cygrunsrv --stop sshd
cygrunsrv --remove sshd
# Delete any sshd or related users (such as cyg_server) from /etc/passwd
# (use your favorite editor)
# Delete any sshd or relaged users (such as cyg_server) from the system
net user sshd /delete
net user cyg_server /delete - Make sure your windows has a administrator login. Example used is "ylam".
- Install CYGWIN or reinstall CYGWIN to have openssh and rsync.
- Run Cygwin Terminal
- Change the account settings of "ylam" for CYGWIN:
chmod +r /etc/passwd
chmod u+w /etc/passwd
chmod +r /etc/group
chmod u+w /etc/group
chmod 755 /var
touch /var/log/sshd.log
chmod 664 /var/log/sshd.log
editrights -l -u ylam
editrights -a SeAssignPrimaryTokenPrivilege -u ylam
editrights -a SeCreateTokenPrivilege -u ylam
editrights -a SeTcbPrivilege -u ylam
editrights -a SeServiceLogonRight -u ylam
editrights -l -u ylam - Run ssh-host-config. Type the parts in red below.
$ ssh-host-config
*** Info: Generating missing SSH host keys
*** Info: Creating default /etc/ssh_config file
*** Info: Creating default /etc/sshd_config file
*** Info: StrictModes is set to 'yes' by default.
*** Info: This is the recommended setting, but it requires that the POSIX
*** Info: permissions of the user's home directory, the user's .ssh
*** Info: directory, and the user's ssh key files are tight so that
*** Info: only the user has write permissions.
*** Info: On the other hand, StrictModes don't work well with default
*** Info: Windows permissions of a home directory mounted with the
*** Info: 'noacl' option, and they don't work at all if the home
*** Info: directory is on a FAT or FAT32 partition.
*** Query: Should StrictModes be used? (yes/no) yes
*** Info: Privilege separation is set to 'sandbox' by default since
*** Info: OpenSSH 6.1. This is unsupported by Cygwin and has to be set
*** Info: to 'yes' or 'no'.
*** Info: However, using privilege separation requires a non-privileged account
*** Info: called 'sshd'.
*** Info: For more info on privilege separation read /usr/share/doc/openssh/READ
ME.privsep.
*** Query: Should privilege separation be used? (yes/no) yes
*** Info: Updating /etc/sshd_config file
*** Query: Do you want to install sshd as a service?
*** Query: (Say "no" if it is already installed as a service) (yes/no) yes
*** Query: Enter the value of CYGWIN for the daemon: [] (Press Enter)
*** Info: On Windows Server 2003, Windows Vista, and above, the
*** Info: SYSTEM account cannot setuid to other users -- a capability
*** Info: sshd requires. You need to have or to create a privileged
*** Info: account. This script will help you do so.
*** Info: It's not possible to use the LocalSystem account for services
*** Info: that can change the user id without an explicit password
*** Info: (such as passwordless logins [e.g. public key authentication]
*** Info: via sshd) when having to create the user token from scratch.
*** Info: For more information on this requirement, see
*** Info: https://cygwin.com/cygwin-ug-net/ntsec.html#ntsec-nopasswd1
*** Info: If you want to enable that functionality, it's required to create
*** Info: a new account with special privileges (unless such an account
*** Info: already exists). This account is then used to run these special
*** Info: servers.
*** Info: Note that creating a new user requires that the current account
*** Info: have Administrator privileges itself.
*** Info: No privileged account could be found.
*** Info: This script plans to use 'cyg_server'.
*** Info: 'cyg_server' will only be used by registered services.
*** Query: Do you want to use a different name? (yes/no) yes
*** Query: Enter the new user name: ylam
*** Query: Reenter: ylam
*** Query: Please enter the password for user 'ylam': ylam's Window's password
*** Query: Reenter: renter
*** Info: The sshd service has been installed under the 'sshd'
*** Info: account. To start the service now, call `net start sshd' or
*** Info: `cygrunsrv -S sshd'. Otherwise, it will start automatically
*** Info: after the next reboot.
*** Info: Host configuration finished. Have fun! - Start the ssh server by:
net start sshd
- Modify Windows firewall to allow port 22 traffic.
(http://diddy.boot-land.net/ssh/files/firewall.htm)
Control Panel -> Windows Firewall -> Advanced settings -> Inbound Rules (right click) -> New rule
... Select TCP and enter 22 ....
- Test the connection:
ssh -v ylam@localhost
(Note: "ylam" should be replaced with your login. And a password is prompted)
- For login without password, at the remote site (For testing, use local site should also be fine), type:
a) ssh-keygen -t rsa (press enter for everything)
b) ssh-copy-id -i ~/.ssh/id_rsa.pub abc@localhost
c) try login again: ssh abc@localhost. You will not need any password.
Labels:
cygwin ssh server,
id_rsa.pub,
rsa,
ssh-host-config,
ssh-keygen
訂閱:
文章 (Atom)