USB摄像头视频相关ffmpeg,rtp,mjpg-streamer
2012-09-04 10:48
483 查看
USB摄像头视频相关ffmpeg,rtp,mjpg-streamer
一个哥们的思路,不错,值得参考:http://blog.csdn.net/sg131971/article/details/6932237
但觉得移植apche太大了,lite http比较适合。
Mini2440Activity.java
[java]
view plaincopyprint?
package sg131971.mini2440;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
public class Mini2440Activity extends Activity {
private static int Connect_flag = 0;
private static int AutoRefresh_flag = 0;
private static int LED_flag[] = new int[4];
private Bitmap m_Bitmap;
private ImageView myImageView;
private Handler m_Handler = new Handler();
private String Board_IP;
private EditText myEditText;
private Button myButtonConnect;
private Button myButton0;
private Button myButton1;
private Button myButton2;
private Button myButton3;
private Button myButtonStatus;
private Button autoButton;
private Button manualButton;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myEditText = (EditText) findViewById(R.id.editText);
myButtonConnect = (Button) findViewById(R.id.myButtonConnect);
myButtonConnect.setOnClickListener(new ConnectListener());
myImageView = (ImageView) findViewById(R.id.imageView);
autoButton = (Button) findViewById(R.id.autoButton);
manualButton = (Button) findViewById(R.id.manualButton);
myButton0 = (Button) findViewById(R.id.myButton0);
myButton1 = (Button) findViewById(R.id.myButton1);
myButton2 = (Button) findViewById(R.id.myButton2);
myButton3 = (Button) findViewById(R.id.myButton3);
myButtonStatus = (Button) findViewById(R.id.myButtonStatus);
StopService();
}
public boolean onKeyDown(int keyCode, KeyEvent msg) {
if (keyCode == KeyEvent.KEYCODE_BACK)
{
finish();
System.exit(0);
}
return false;
}
private void StartService() {
// TODO Auto-generated method stub
m_Handler.postDelayed(m_RefreshImage, 0);
myButton0.setOnClickListener(new LED0Listener());
myButton1.setOnClickListener(new LED1Listener());
myButton2.setOnClickListener(new LED2Listener());
myButton3.setOnClickListener(new LED3Listener());
myButtonStatus.setOnClickListener(new StatusListener());
autoButton.setOnClickListener(new AutoRefresh());
manualButton.setOnClickListener(new ManualRefresh());
}
private void StopService() {
// TODO Auto-generated method stub
m_Handler.removeCallbacks(m_RefreshImage);
myImageView.setImageResource(R.drawable.first);
myButton0.setOnClickListener(new DefaultListener());
myButton1.setOnClickListener(new DefaultListener());
myButton2.setOnClickListener(new DefaultListener());
myButton3.setOnClickListener(new DefaultListener());
myButtonStatus.setOnClickListener(new DefaultListener());
autoButton.setOnClickListener(new DefaultListener());
manualButton.setOnClickListener(new DefaultListener());
}
public class ConnectListener implements OnClickListener {
public void onClick(View v) {
// TODO Auto-generated method stub
Board_IP = myEditText.getText().toString();
if (Connect_flag == 0) {
Connect_flag = 1;
StartService();
myButtonConnect.setText("Disconnect");
showMessage("已连接:" + Board_IP);
} else {
Connect_flag = 0;
AutoRefresh_flag = 0;
StopService();
myButtonConnect.setText("Connect");
showMessage("已断开:" + Board_IP);
}
}
}
public class DefaultListener implements OnClickListener {
public void onClick(View v) {
// TODO Auto-generated method stub
showMessage("请先连接ARM板!");
}
}
public class ManualRefresh implements OnClickListener {
public void onClick(View v) {
// TODO Auto-generated method stub
if (AutoRefresh_flag == 1)
AutoRefresh_flag = 0;
m_Handler.postDelayed(m_RefreshImage, 0);
showMessage("手动刷新成功!");
}
}
public class AutoRefresh implements OnClickListener {
public void onClick(View v) {
// TODO Auto-generated method stub
if (AutoRefresh_flag == 0)
AutoRefresh_flag = 1;
m_Handler.postDelayed(m_RefreshImage, 0);
showMessage("自动刷新设置成功!");
}
}
private Runnable m_RefreshImage = new Runnable() {
public void run() {
// TODO Auto-generated method stub
RefreshImage();
if (AutoRefresh_flag == 1)
m_Handler.postDelayed(m_RefreshImage, 100);
else
m_Handler.removeCallbacks(m_RefreshImage);
}
private void RefreshImage() {
// TODO Auto-generated method stub
try {
URL m_URL = new URL("http://" + Board_IP
+ ":8080/?action=snapshot");
URLConnection m_URL_Connection = m_URL.openConnection();
m_URL_Connection.connect();
InputStream m_InputStream = m_URL_Connection.getInputStream();
m_Bitmap = BitmapFactory.decodeStream(m_InputStream);
myImageView.setImageBitmap(m_Bitmap);
m_InputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
public class LED0Listener implements OnClickListener {
public void onClick(View arg0) {
// TODO Auto-generated method stub
LED_flag[0]++;
if (LED_flag[0] % 2 == 1) {
HttpSendCmd("58400F01");
showMessage("LED0已打开!");
} else {
HttpSendCmd("58400F00");
showMessage("LED0已关闭!");
}
}
}
public class LED1Listener implements OnClickListener {
public void onClick(View v) {
// TODO Auto-generated method stub
LED_flag[1]++;
if (LED_flag[1] % 2 == 1) {
HttpSendCmd("58401F01");
showMessage("LED1已打开!");
} else {
HttpSendCmd("58401F00");
showMessage("LED1已关闭!");
}
}
}
public class LED2Listener implements OnClickListener {
public void onClick(View v) {
// TODO Auto-generated method stub
LED_flag[2]++;
if (LED_flag[2] % 2 == 1) {
HttpSendCmd("58402F01");
showMessage("LED2已打开!");
} else {
HttpSendCmd("58402F00");
showMessage("LED2已关闭!");
}
}
}
public class LED3Listener implements OnClickListener {
public void onClick(View v) {
// TODO Auto-generated method stub
LED_flag[3]++;
if (LED_flag[3] % 2 == 1) {
HttpSendCmd("58403F01");
showMessage("LED3已打开!");
} else {
HttpSendCmd("58403F00");
showMessage("LED3已关闭!");
}
}
}
public class StatusListener implements OnClickListener {
public void onClick(View v) {
// TODO Auto-generated method stub
String display_info = "";
// 以后此处可以通过发送http请求查询硬件状态
HttpSendCmd("5840FFFF");
if (LED_flag[0] % 2 == 1)
display_info += "LED0:开";
else
display_info += "LED0:关";
display_info += " ";
if (LED_flag[1] % 2 == 1)
display_info += "LED1:开";
else
display_info += "LED1:关";
display_info += " ";
if (LED_flag[2] % 2 == 1)
display_info += "LED2:开";
else
display_info += "LED2:关";
display_info += " ";
if (LED_flag[3] % 2 == 1)
display_info += "LED3:开";
else
display_info += "LED3:关";
showMessage(display_info);
}
}
public void HttpSendCmd(String cmd) {
// TODO Auto-generated method stub
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://" + Board_IP
+ "/mjpg-streamer/post_data.php");
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(3);
nameValuePairs.add(new BasicNameValuePair("user", "root"));
nameValuePairs.add(new BasicNameValuePair("passwd", "shiguang"));
nameValuePairs.add(new BasicNameValuePair("para", cmd));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
String tmpString = EntityUtils.toString(response.getEntity());
System.out.println(tmpString);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void showMessage(String str) {
Toast toast = Toast.makeText(this, str, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.TOP, 0, 550);
toast.show();
}
}
最终效果图:
/nfsroot/rootfs/usr/local/apache_arm/htdocs/mjpg-streamer/post_data.php
[php]
view plaincopyprint?
<?php @header("content-type:text/html; charset=utf-8"); error_reporting(E_ALL); set_time_limit(0); $user = $_REQUEST['user']; $passed = $_REQUEST['passwd']; $para = $_REQUEST['para']; $service_port = 9090; $address = "192.168.1.97"; $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if ($socket < 0) { echo "socket_create() failed: reason: " . socket_strerror($socket) . "\n"; } $result = socket_connect($socket, $address, $service_port); if ($result < 0) { echo "socket_connect() failed: reason: " . socket_strerror($result) . "\n"; } $in = $user . $passed . $para; $result = socket_write($socket, $in, strlen($in)) ; if(!$result) { echo "socket_write() failed: reason: " . socket_strerror($socket) . "\n"; } /* while($out = socket_read($socket,256)) { echo $out; break; } */ socket_close($socket); ?>
OK!
现在,基本通路已经打通,剩下的就是简单的指令转换和设备控制了!
转一篇文章:/article/2021691.html
USB 设备,是我刚刚开始学习的,完全搞不懂,玩这个USB摄像头淘宝上买的杂牌子,我在xp 下测试了一下,只能保证芯片是芯片是ZC0301PL。 其它都未知。
现在开始正文:( 博文来自CSDN Acanoe 的博客:http://blog.csdn.net/ACanoe
我的操作环境是、主机:xp + VMware ubuntu 10.10 。 开发板:OK6410 A板。 使用内核:Linux 2.6.36.2 。 使用软件: mjpg-streamer
1、配置内核支持 中微星的 ZC3XX 摄像头。
Device Drivers ->
Multimedia devices->
<*>video for linux
[*]video capture adapters->
[*]V4l USB devices ->
<*>USB video class (UVC)
[*] UVC input events device support
<*>GSPCA based webcams ->
<*>ZC3XX USB Camera Driver
配置好了以后编译内核,下载到开发板。
2、查看USB 摄像头接入开发板的打印信息,当然你的开发板首先需要先支持 USB-Host 。我的开发板串口打印信息是:
[root@FORLINX6410]# usb 1-1: new full speed USB device using s3c2410-ohci and ad
dress 4
usb 1-1: New USB device found, idVendor=0ac8, idProduct=301b
usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
usb 1-1: Product: PC Camera
usb 1-1: Manufacturer: Vimicro Corp.
gspca: probing 0ac8:301b
zc3xx: probe sensor -> 000a
zc3xx: Find Sensor PB0330. Chip revision 0
input: zc3xx as /class/input/input2
gspca: video0 created
[root@FORLINX6410]#
释放 USB 摄像头 的打印信息是:
[root@FORLINX6410]# usb 1-1: USB disconnect, address 4
gspca: video0 disconnect
gspca: video0 released
[root@FORLINX6410]#
3、编译安装:mjpg-streamer
移植参考了百度文库的
主要步骤,自己总结为:
3.1 : 下载 mjgp-streamer 源码包
http://mjpg-streamer.svn.sourceforge.net/viewvc/mjpg-streamer.tar.gz?view=tar
解压后进入 mjgp-streamer 目录 修改顶层 Makefile ,将 CC=gcc 修改为 CC=arm-linux-gcc。 或者直接使用 make CC=arm-linux-gcc 可以直接编译。
3.2 : make 后在 mjpg-streamer 目录下会生成 *.so 和 mjpt-streamer 可执行文件 ,其中 input_uvc.so 和 output_http.so 是我们需要的测试文件
3.3 : 测试准备,你可以直接将我们编译好的 mjpg-streamer 的整个目录 copy 到你的文件系统根目录下,也可以只copy mjpg-streamer , input_uvc.so
和 output_http.so 这三个文件。 不过我是将真个目录copy 到我的文件系统根目录下的。(我是用的是yaffs2 文件系统)。测试前先用网线联通你的主机
和 开发板,我是用虚拟机上的 火狐浏览器测试的。(使用viewer.exe 和 XP 下的IE 浏览器都不成功),要保证你的虚拟机能 ping 通你的开发板。
3.4 :进入你的文件系统,进入你已经copy 好了的mjpg-streamer 目录,我mjpg-streamer 下的文件有:
[root@FORLINX6410]# ls
CHANGELOG mjpg-streamer plugins
LICENSE mjpg_streamer scripts
Makefile mjpg_streamer.c start.sh
README mjpg_streamer.h utils.c
TODO mjpg_streamer.o utils.h
input_file.so output_file.so utils.o
input_testpicture.so output_http.so www
input_uvc.so output_udp.so
[root@FORLINX6410]#
然后输入命令:
./mjpg_streamer -i "./input_uvc.so" -o "./output_http.so -w ./www"
输入完命令后我开发板串口的打印信息是:
MJPG Streamer Version: svn rev:
i: Using V4L2 device.: /dev/video0
i: Desired Resolution: 640 x 480
i: Frames Per Second.: 5
i: Format............: MJPEG
Adding control for Pan (relative)
UVCIOC_CTRL_ADD - Error: Invalid argument
Adding control for Tilt (relative)
UVCIOC_CTRL_ADD - Error: Invalid argument
Adding control for Pan Reset
UVCIOC_CTRL_ADD - Error: Invalid argument
Adding control for Tilt Reset
UVCIOC_CTRL_ADD - Error: Invalid argument
Adding control for Pan/tilt Reset
UVCIOC_CTRL_ADD - Error: Invalid argument
Adding control for Focus (absolute)
UVCIOC_CTRL_ADD - Error: Invalid argument
mapping control for Pan (relative)
UVCIOC_CTRL_MAP - Error: Invalid argument
mapping control for Tilt (relative)
UVCIOC_CTRL_MAP - Error: Invalid argument
mapping control for Pan Reset
UVCIOC_CTRL_MAP - Error: Invalid argument
mapping control for Tilt Reset
UVCIOC_CTRL_MAP - Error: Invalid argument
mapping control for Pan/tilt Reset
UVCIOC_CTRL_MAP - Error: Invalid argument
mapping control for Focus (absolute)
UVCIOC_CTRL_MAP - Error: Invalid argument
mapping control for LED1 Mode
UVCIOC_CTRL_MAP - Error: Invalid argument
mapping control for LED1 Frequency
UVCIOC_CTRL_MAP - Error: Invalid argument
mapping control for Disable video processing
UVCIOC_CTRL_MAP - Error: Invalid argument
mapping control for Raw bits per pixel
UVCIOC_CTRL_MAP - Error: Invalid argument
o: www-folder-path...: ./www/
o: HTTP TCP port.....: 8080
o: username:password.: disabled
o: commands..........: enabled
我这里显然有报错信息, 上次也是,这此我就没管它,然后进入ubuntu 虚拟机进行测试。
在火狐浏览器里面输入:
192.168.0.232:8080/?action=stream
就可以看到流畅的视频流了。
很想给大家上传我的视频截图,可是我学校用的网络客户端很垃圾,总是和 CSDN 有冲突,不能上传图片,也不能进个人主页。
呵呵:想看图的点这里:
http://hi.baidu.com/%D2%A1%D2%B7%B5%C4%B4%B0%C7%B0%D1%A9/album/linux%20uvc%20%C9%E3%CF%F1%CD%B7
哈:这是我用外网上传的图片:
主机环境 :ubuntu 10.10
目标机 :FS2410(S3C2410)
主机工具链 :gcc-4.4.5
交叉工具链 :arm-none-linux-gnueabi-gcc-4.3.2
摄像头 :ZC301
二、移植过程
1、配置内核是内核支持芯片为ZC301的摄像头
Make menuconfig
Device Drivers --->
<*> Multimedia support --->
<*> Video For Linux
[*] Enable Video For Linux API 1 (DEPRECATED) (NEW)
[*] Video capture adapters (NEW) --->
[*] V4L USB devices (NEW) --->
<*> USB Video Class (UVC)
[*] UVC input events device support (NEW)
<*> USB ZC0301[P] webcam support (DEPRECATED)
2、重新编译内核
make zImage
通过上面两个步骤就可以驱动我们的摄像头了。但是这个驱动是基于V4l2的。以前基于 V4L的一些上层应用就不能用了,或需要做大量的修改!这里我们要实现网络视频的功能,以前都是用servfox这个网络视频服务器,但是这个服务器就是 基于V4L的,我们如果想用的话就得对servfox的源码进行修改。这里我们选用另外一种方案mjpg-stream。
3、mjpg-stream的移植
关于mjpg-stream的资料大家可以在下面这个网址查看:http://sourceforge.net/apps/mediawiki/mjpg-streamer/index.php?title=Main_Page
mjpg-stream的移植需要jpeg的库,所以我们先移植jpeg的库
(1)jpeg库的移植
1)jpeg源码包通过下面这个网址下载
http://www.ijg.org/files/jpegsrc.v8b.tar.gz
2)解压源码包
tar xvf jpegsrc.v8b.tar.gz
3)配置源码
cd jpeg-8b
./configure --prefix=/home/linux/s3c2410-2.6.35/video/jpeg --host=arm-none-linux-gnueabi
4)编译
make
5)安装
make install
6)拷贝库到文件系统中
cp //home/linux/s3c2410-2.6.35/video/jpeg /lib/libjpeg.so.8 /source/rootfs/lib
(2)mjpg-stream的移植
1)mjpg-stream源码包通过下面这个网址下载
http://sourceforge.net/projects/mjpg-streamer/
2)解压源码
tar xvf mjpg-streamer-r63.tar.gz
3)修改源码
cd mjpg-streamer-r63
修改顶层makefile及plugins目录中的各级makefile将所有
CC=gcc
修改为
CC=arm-none-linux-gnueabi-gcc
修改plugins/input_uvc/Makfile
修改
CFLAGS += -O2 -DLINUX -D_GNU_SOURCE -Wall -shared -fPIC
为
CFLAGS += -O2 -DLINUX -D_GNU_SOURCE -Wall -shared -fPIC -I/home/linux/s3c2410-2.6.35/video/jpeg/include
修改
$(CC) $(CFLAGS) -ljpeg -o $@ input_uvc.c v4l2uvc.lo jpeg_utils.lo dynctrl.lo
为
$(CC) $(CFLAGS) -ljpeg -L/home/linux/s3c2410-2.6.35/video/jpeg/lib -o $@ input_uvc.c v4l2uvc.lo jpeg_utils.lo dynctrl.lo
jpeg_utils.c:27: fatal error: jpeglib.h: No such file or directory
4)编译
make
5)测试
mkdir /source/rootfs/mjpg
cp *.so /source/rootfs/mjpg
cp mjpg-stream /source/rootfs/bin
打开开开发板运行
mjpg_streamer -i "/mjpg/input_uvc.so" -o "/mjpg/output_http.so -w /www"
在源码目录下有start.sh,这个脚本里有一些mjpg-stream的使用方法及说明
打开一个网页输入下面地址就能够看到一个视频(开发板的IP为192.168.1.202):
http://192.168.1.202:8080/?action=stream
打开一个网页输入下面地址就能够看到一个静态图片:
http://192.168.1.202:8080/?action=snapshot
6)在mjpg源码下有一个www的目录,这个一个网络使用mjpg的实例,结合web服务器(boa)可以实现一些其他相关功能。
FFMPEG库裁剪
经过长期模式,测试,可以用以下方法缩小,在configure的时候加上类似如下的参数:
--disable-encoders --disable-decoders --enable-decoder=h264
解释
--disable-encoders 屏蔽所有编码器
--disable-decoders 屏蔽所有解码器
--enable-decoder=h264 启用h264解码器
由上面可以看出编码器也可以先屏蔽所有编码器,再启用某些编码器。
这样编译出来的 avcodec.dll就会变成 700多K左右,另外几个 avutil.dll、swscale.dll 等等,大小
不会变。它们也没有多大。
一个哥们的思路,不错,值得参考:http://blog.csdn.net/sg131971/article/details/6932237
但觉得移植apche太大了,lite http比较适合。
Android + Mini2440 无线网络视频监控系统(五)Android客户端程序
http://blog.csdn.net/sg131971/article/details/6932742Mini2440Activity.java
[java]
view plaincopyprint?
package sg131971.mini2440;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
public class Mini2440Activity extends Activity {
private static int Connect_flag = 0;
private static int AutoRefresh_flag = 0;
private static int LED_flag[] = new int[4];
private Bitmap m_Bitmap;
private ImageView myImageView;
private Handler m_Handler = new Handler();
private String Board_IP;
private EditText myEditText;
private Button myButtonConnect;
private Button myButton0;
private Button myButton1;
private Button myButton2;
private Button myButton3;
private Button myButtonStatus;
private Button autoButton;
private Button manualButton;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myEditText = (EditText) findViewById(R.id.editText);
myButtonConnect = (Button) findViewById(R.id.myButtonConnect);
myButtonConnect.setOnClickListener(new ConnectListener());
myImageView = (ImageView) findViewById(R.id.imageView);
autoButton = (Button) findViewById(R.id.autoButton);
manualButton = (Button) findViewById(R.id.manualButton);
myButton0 = (Button) findViewById(R.id.myButton0);
myButton1 = (Button) findViewById(R.id.myButton1);
myButton2 = (Button) findViewById(R.id.myButton2);
myButton3 = (Button) findViewById(R.id.myButton3);
myButtonStatus = (Button) findViewById(R.id.myButtonStatus);
StopService();
}
public boolean onKeyDown(int keyCode, KeyEvent msg) {
if (keyCode == KeyEvent.KEYCODE_BACK)
{
finish();
System.exit(0);
}
return false;
}
private void StartService() {
// TODO Auto-generated method stub
m_Handler.postDelayed(m_RefreshImage, 0);
myButton0.setOnClickListener(new LED0Listener());
myButton1.setOnClickListener(new LED1Listener());
myButton2.setOnClickListener(new LED2Listener());
myButton3.setOnClickListener(new LED3Listener());
myButtonStatus.setOnClickListener(new StatusListener());
autoButton.setOnClickListener(new AutoRefresh());
manualButton.setOnClickListener(new ManualRefresh());
}
private void StopService() {
// TODO Auto-generated method stub
m_Handler.removeCallbacks(m_RefreshImage);
myImageView.setImageResource(R.drawable.first);
myButton0.setOnClickListener(new DefaultListener());
myButton1.setOnClickListener(new DefaultListener());
myButton2.setOnClickListener(new DefaultListener());
myButton3.setOnClickListener(new DefaultListener());
myButtonStatus.setOnClickListener(new DefaultListener());
autoButton.setOnClickListener(new DefaultListener());
manualButton.setOnClickListener(new DefaultListener());
}
public class ConnectListener implements OnClickListener {
public void onClick(View v) {
// TODO Auto-generated method stub
Board_IP = myEditText.getText().toString();
if (Connect_flag == 0) {
Connect_flag = 1;
StartService();
myButtonConnect.setText("Disconnect");
showMessage("已连接:" + Board_IP);
} else {
Connect_flag = 0;
AutoRefresh_flag = 0;
StopService();
myButtonConnect.setText("Connect");
showMessage("已断开:" + Board_IP);
}
}
}
public class DefaultListener implements OnClickListener {
public void onClick(View v) {
// TODO Auto-generated method stub
showMessage("请先连接ARM板!");
}
}
public class ManualRefresh implements OnClickListener {
public void onClick(View v) {
// TODO Auto-generated method stub
if (AutoRefresh_flag == 1)
AutoRefresh_flag = 0;
m_Handler.postDelayed(m_RefreshImage, 0);
showMessage("手动刷新成功!");
}
}
public class AutoRefresh implements OnClickListener {
public void onClick(View v) {
// TODO Auto-generated method stub
if (AutoRefresh_flag == 0)
AutoRefresh_flag = 1;
m_Handler.postDelayed(m_RefreshImage, 0);
showMessage("自动刷新设置成功!");
}
}
private Runnable m_RefreshImage = new Runnable() {
public void run() {
// TODO Auto-generated method stub
RefreshImage();
if (AutoRefresh_flag == 1)
m_Handler.postDelayed(m_RefreshImage, 100);
else
m_Handler.removeCallbacks(m_RefreshImage);
}
private void RefreshImage() {
// TODO Auto-generated method stub
try {
URL m_URL = new URL("http://" + Board_IP
+ ":8080/?action=snapshot");
URLConnection m_URL_Connection = m_URL.openConnection();
m_URL_Connection.connect();
InputStream m_InputStream = m_URL_Connection.getInputStream();
m_Bitmap = BitmapFactory.decodeStream(m_InputStream);
myImageView.setImageBitmap(m_Bitmap);
m_InputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
public class LED0Listener implements OnClickListener {
public void onClick(View arg0) {
// TODO Auto-generated method stub
LED_flag[0]++;
if (LED_flag[0] % 2 == 1) {
HttpSendCmd("58400F01");
showMessage("LED0已打开!");
} else {
HttpSendCmd("58400F00");
showMessage("LED0已关闭!");
}
}
}
public class LED1Listener implements OnClickListener {
public void onClick(View v) {
// TODO Auto-generated method stub
LED_flag[1]++;
if (LED_flag[1] % 2 == 1) {
HttpSendCmd("58401F01");
showMessage("LED1已打开!");
} else {
HttpSendCmd("58401F00");
showMessage("LED1已关闭!");
}
}
}
public class LED2Listener implements OnClickListener {
public void onClick(View v) {
// TODO Auto-generated method stub
LED_flag[2]++;
if (LED_flag[2] % 2 == 1) {
HttpSendCmd("58402F01");
showMessage("LED2已打开!");
} else {
HttpSendCmd("58402F00");
showMessage("LED2已关闭!");
}
}
}
public class LED3Listener implements OnClickListener {
public void onClick(View v) {
// TODO Auto-generated method stub
LED_flag[3]++;
if (LED_flag[3] % 2 == 1) {
HttpSendCmd("58403F01");
showMessage("LED3已打开!");
} else {
HttpSendCmd("58403F00");
showMessage("LED3已关闭!");
}
}
}
public class StatusListener implements OnClickListener {
public void onClick(View v) {
// TODO Auto-generated method stub
String display_info = "";
// 以后此处可以通过发送http请求查询硬件状态
HttpSendCmd("5840FFFF");
if (LED_flag[0] % 2 == 1)
display_info += "LED0:开";
else
display_info += "LED0:关";
display_info += " ";
if (LED_flag[1] % 2 == 1)
display_info += "LED1:开";
else
display_info += "LED1:关";
display_info += " ";
if (LED_flag[2] % 2 == 1)
display_info += "LED2:开";
else
display_info += "LED2:关";
display_info += " ";
if (LED_flag[3] % 2 == 1)
display_info += "LED3:开";
else
display_info += "LED3:关";
showMessage(display_info);
}
}
public void HttpSendCmd(String cmd) {
// TODO Auto-generated method stub
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://" + Board_IP
+ "/mjpg-streamer/post_data.php");
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(3);
nameValuePairs.add(new BasicNameValuePair("user", "root"));
nameValuePairs.add(new BasicNameValuePair("passwd", "shiguang"));
nameValuePairs.add(new BasicNameValuePair("para", cmd));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
String tmpString = EntityUtils.toString(response.getEntity());
System.out.println(tmpString);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void showMessage(String str) {
Toast toast = Toast.makeText(this, str, Toast.LENGTH_SHORT);
toast.setGravity(Gravity.TOP, 0, 550);
toast.show();
}
}
package sg131971.mini2440; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import java.util.List; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.os.Handler; import android.view.Gravity; import android.view.KeyEvent; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.Toast; public class Mini2440Activity extends Activity { private static int Connect_flag = 0; private static int AutoRefresh_flag = 0; private static int LED_flag[] = new int[4]; private Bitmap m_Bitmap; private ImageView myImageView; private Handler m_Handler = new Handler(); private String Board_IP; private EditText myEditText; private Button myButtonConnect; private Button myButton0; private Button myButton1; private Button myButton2; private Button myButton3; private Button myButtonStatus; private Button autoButton; private Button manualButton; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); myEditText = (EditText) findViewById(R.id.editText); myButtonConnect = (Button) findViewById(R.id.myButtonConnect); myButtonConnect.setOnClickListener(new ConnectListener()); myImageView = (ImageView) findViewById(R.id.imageView); autoButton = (Button) findViewById(R.id.autoButton); manualButton = (Button) findViewById(R.id.manualButton); myButton0 = (Button) findViewById(R.id.myButton0); myButton1 = (Button) findViewById(R.id.myButton1); myButton2 = (Button) findViewById(R.id.myButton2); myButton3 = (Button) findViewById(R.id.myButton3); myButtonStatus = (Button) findViewById(R.id.myButtonStatus); StopService(); } public boolean onKeyDown(int keyCode, KeyEvent msg) { if (keyCode == KeyEvent.KEYCODE_BACK) { finish(); System.exit(0); } return false; } private void StartService() { // TODO Auto-generated method stub m_Handler.postDelayed(m_RefreshImage, 0); myButton0.setOnClickListener(new LED0Listener()); myButton1.setOnClickListener(new LED1Listener()); myButton2.setOnClickListener(new LED2Listener()); myButton3.setOnClickListener(new LED3Listener()); myButtonStatus.setOnClickListener(new StatusListener()); autoButton.setOnClickListener(new AutoRefresh()); manualButton.setOnClickListener(new ManualRefresh()); } private void StopService() { // TODO Auto-generated method stub m_Handler.removeCallbacks(m_RefreshImage); myImageView.setImageResource(R.drawable.first); myButton0.setOnClickListener(new DefaultListener()); myButton1.setOnClickListener(new DefaultListener()); myButton2.setOnClickListener(new DefaultListener()); myButton3.setOnClickListener(new DefaultListener()); myButtonStatus.setOnClickListener(new DefaultListener()); autoButton.setOnClickListener(new DefaultListener()); manualButton.setOnClickListener(new DefaultListener()); } public class ConnectListener implements OnClickListener { public void onClick(View v) { // TODO Auto-generated method stub Board_IP = myEditText.getText().toString(); if (Connect_flag == 0) { Connect_flag = 1; StartService(); myButtonConnect.setText("Disconnect"); showMessage("已连接:" + Board_IP); } else { Connect_flag = 0; AutoRefresh_flag = 0; StopService(); myButtonConnect.setText("Connect"); showMessage("已断开:" + Board_IP); } } } public class DefaultListener implements OnClickListener { public void onClick(View v) { // TODO Auto-generated method stub showMessage("请先连接ARM板!"); } } public class ManualRefresh implements OnClickListener { public void onClick(View v) { // TODO Auto-generated method stub if (AutoRefresh_flag == 1) AutoRefresh_flag = 0; m_Handler.postDelayed(m_RefreshImage, 0); showMessage("手动刷新成功!"); } } public class AutoRefresh implements OnClickListener { public void onClick(View v) { // TODO Auto-generated method stub if (AutoRefresh_flag == 0) AutoRefresh_flag = 1; m_Handler.postDelayed(m_RefreshImage, 0); showMessage("自动刷新设置成功!"); } } private Runnable m_RefreshImage = new Runnable() { public void run() { // TODO Auto-generated method stub RefreshImage(); if (AutoRefresh_flag == 1) m_Handler.postDelayed(m_RefreshImage, 100); else m_Handler.removeCallbacks(m_RefreshImage); } private void RefreshImage() { // TODO Auto-generated method stub try { URL m_URL = new URL("http://" + Board_IP + ":8080/?action=snapshot"); URLConnection m_URL_Connection = m_URL.openConnection(); m_URL_Connection.connect(); InputStream m_InputStream = m_URL_Connection.getInputStream(); m_Bitmap = BitmapFactory.decodeStream(m_InputStream); myImageView.setImageBitmap(m_Bitmap); m_InputStream.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }; public class LED0Listener implements OnClickListener { public void onClick(View arg0) { // TODO Auto-generated method stub LED_flag[0]++; if (LED_flag[0] % 2 == 1) { HttpSendCmd("58400F01"); showMessage("LED0已打开!"); } else { HttpSendCmd("58400F00"); showMessage("LED0已关闭!"); } } } public class LED1Listener implements OnClickListener { public void onClick(View v) { // TODO Auto-generated method stub LED_flag[1]++; if (LED_flag[1] % 2 == 1) { HttpSendCmd("58401F01"); showMessage("LED1已打开!"); } else { HttpSendCmd("58401F00"); showMessage("LED1已关闭!"); } } } public class LED2Listener implements OnClickListener { public void onClick(View v) { // TODO Auto-generated method stub LED_flag[2]++; if (LED_flag[2] % 2 == 1) { HttpSendCmd("58402F01"); showMessage("LED2已打开!"); } else { HttpSendCmd("58402F00"); showMessage("LED2已关闭!"); } } } public class LED3Listener implements OnClickListener { public void onClick(View v) { // TODO Auto-generated method stub LED_flag[3]++; if (LED_flag[3] % 2 == 1) { HttpSendCmd("58403F01"); showMessage("LED3已打开!"); } else { HttpSendCmd("58403F00"); showMessage("LED3已关闭!"); } } } public class StatusListener implements OnClickListener { public void onClick(View v) { // TODO Auto-generated method stub String display_info = ""; // 以后此处可以通过发送http请求查询硬件状态 HttpSendCmd("5840FFFF"); if (LED_flag[0] % 2 == 1) display_info += "LED0:开"; else display_info += "LED0:关"; display_info += " "; if (LED_flag[1] % 2 == 1) display_info += "LED1:开"; else display_info += "LED1:关"; display_info += " "; if (LED_flag[2] % 2 == 1) display_info += "LED2:开"; else display_info += "LED2:关"; display_info += " "; if (LED_flag[3] % 2 == 1) display_info += "LED3:开"; else display_info += "LED3:关"; showMessage(display_info); } } public void HttpSendCmd(String cmd) { // TODO Auto-generated method stub HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost("http://" + Board_IP + "/mjpg-streamer/post_data.php"); try { List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(3); nameValuePairs.add(new BasicNameValuePair("user", "root")); nameValuePairs.add(new BasicNameValuePair("passwd", "shiguang")); nameValuePairs.add(new BasicNameValuePair("para", cmd)); httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); HttpResponse response = httpclient.execute(httppost); String tmpString = EntityUtils.toString(response.getEntity()); System.out.println(tmpString); } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void showMessage(String str) { Toast toast = Toast.makeText(this, str, Toast.LENGTH_SHORT); toast.setGravity(Gravity.TOP, 0, 550); toast.show(); } }
最终效果图:
/nfsroot/rootfs/usr/local/apache_arm/htdocs/mjpg-streamer/post_data.php
[php]
view plaincopyprint?
<?php @header("content-type:text/html; charset=utf-8"); error_reporting(E_ALL); set_time_limit(0); $user = $_REQUEST['user']; $passed = $_REQUEST['passwd']; $para = $_REQUEST['para']; $service_port = 9090; $address = "192.168.1.97"; $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if ($socket < 0) { echo "socket_create() failed: reason: " . socket_strerror($socket) . "\n"; } $result = socket_connect($socket, $address, $service_port); if ($result < 0) { echo "socket_connect() failed: reason: " . socket_strerror($result) . "\n"; } $in = $user . $passed . $para; $result = socket_write($socket, $in, strlen($in)) ; if(!$result) { echo "socket_write() failed: reason: " . socket_strerror($socket) . "\n"; } /* while($out = socket_read($socket,256)) { echo $out; break; } */ socket_close($socket); ?>
<?php @header("content-type:text/html; charset=utf-8"); error_reporting(E_ALL); set_time_limit(0); $user = $_REQUEST['user']; $passed = $_REQUEST['passwd']; $para = $_REQUEST['para']; $service_port = 9090; $address = "192.168.1.97"; $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if ($socket < 0) { echo "socket_create() failed: reason: " . socket_strerror($socket) . "\n"; } $result = socket_connect($socket, $address, $service_port); if ($result < 0) { echo "socket_connect() failed: reason: " . socket_strerror($result) . "\n"; } $in = $user . $passed . $para; $result = socket_write($socket, $in, strlen($in)) ; if(!$result) { echo "socket_write() failed: reason: " . socket_strerror($socket) . "\n"; } /* while($out = socket_read($socket,256)) { echo $out; break; } */ socket_close($socket); ?>手机端控制测试:
OK!
现在,基本通路已经打通,剩下的就是简单的指令转换和设备控制了!
转一篇文章:/article/2021691.html
USB 设备,是我刚刚开始学习的,完全搞不懂,玩这个USB摄像头淘宝上买的杂牌子,我在xp 下测试了一下,只能保证芯片是芯片是ZC0301PL。 其它都未知。
现在开始正文:( 博文来自CSDN Acanoe 的博客:http://blog.csdn.net/ACanoe
我的操作环境是、主机:xp + VMware ubuntu 10.10 。 开发板:OK6410 A板。 使用内核:Linux 2.6.36.2 。 使用软件: mjpg-streamer
1、配置内核支持 中微星的 ZC3XX 摄像头。
Device Drivers ->
Multimedia devices->
<*>video for linux
[*]video capture adapters->
[*]V4l USB devices ->
<*>USB video class (UVC)
[*] UVC input events device support
<*>GSPCA based webcams ->
<*>ZC3XX USB Camera Driver
配置好了以后编译内核,下载到开发板。
2、查看USB 摄像头接入开发板的打印信息,当然你的开发板首先需要先支持 USB-Host 。我的开发板串口打印信息是:
[root@FORLINX6410]# usb 1-1: new full speed USB device using s3c2410-ohci and ad
dress 4
usb 1-1: New USB device found, idVendor=0ac8, idProduct=301b
usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
usb 1-1: Product: PC Camera
usb 1-1: Manufacturer: Vimicro Corp.
gspca: probing 0ac8:301b
zc3xx: probe sensor -> 000a
zc3xx: Find Sensor PB0330. Chip revision 0
input: zc3xx as /class/input/input2
gspca: video0 created
[root@FORLINX6410]#
释放 USB 摄像头 的打印信息是:
[root@FORLINX6410]# usb 1-1: USB disconnect, address 4
gspca: video0 disconnect
gspca: video0 released
[root@FORLINX6410]#
3、编译安装:mjpg-streamer
移植参考了百度文库的
基于TQ2440开发板的Linux-2.6.30.4的网络现, 下载地址为:
http://wenku.baidu.com/view/9c712cd950e2524de5187e76.html
主要步骤,自己总结为:3.1 : 下载 mjgp-streamer 源码包
http://mjpg-streamer.svn.sourceforge.net/viewvc/mjpg-streamer.tar.gz?view=tar
解压后进入 mjgp-streamer 目录 修改顶层 Makefile ,将 CC=gcc 修改为 CC=arm-linux-gcc。 或者直接使用 make CC=arm-linux-gcc 可以直接编译。
3.2 : make 后在 mjpg-streamer 目录下会生成 *.so 和 mjpt-streamer 可执行文件 ,其中 input_uvc.so 和 output_http.so 是我们需要的测试文件
3.3 : 测试准备,你可以直接将我们编译好的 mjpg-streamer 的整个目录 copy 到你的文件系统根目录下,也可以只copy mjpg-streamer , input_uvc.so
和 output_http.so 这三个文件。 不过我是将真个目录copy 到我的文件系统根目录下的。(我是用的是yaffs2 文件系统)。测试前先用网线联通你的主机
和 开发板,我是用虚拟机上的 火狐浏览器测试的。(使用viewer.exe 和 XP 下的IE 浏览器都不成功),要保证你的虚拟机能 ping 通你的开发板。
3.4 :进入你的文件系统,进入你已经copy 好了的mjpg-streamer 目录,我mjpg-streamer 下的文件有:
[root@FORLINX6410]# ls
CHANGELOG mjpg-streamer plugins
LICENSE mjpg_streamer scripts
Makefile mjpg_streamer.c start.sh
README mjpg_streamer.h utils.c
TODO mjpg_streamer.o utils.h
input_file.so output_file.so utils.o
input_testpicture.so output_http.so www
input_uvc.so output_udp.so
[root@FORLINX6410]#
然后输入命令:
./mjpg_streamer -i "./input_uvc.so" -o "./output_http.so -w ./www"
输入完命令后我开发板串口的打印信息是:
MJPG Streamer Version: svn rev:
i: Using V4L2 device.: /dev/video0
i: Desired Resolution: 640 x 480
i: Frames Per Second.: 5
i: Format............: MJPEG
Adding control for Pan (relative)
UVCIOC_CTRL_ADD - Error: Invalid argument
Adding control for Tilt (relative)
UVCIOC_CTRL_ADD - Error: Invalid argument
Adding control for Pan Reset
UVCIOC_CTRL_ADD - Error: Invalid argument
Adding control for Tilt Reset
UVCIOC_CTRL_ADD - Error: Invalid argument
Adding control for Pan/tilt Reset
UVCIOC_CTRL_ADD - Error: Invalid argument
Adding control for Focus (absolute)
UVCIOC_CTRL_ADD - Error: Invalid argument
mapping control for Pan (relative)
UVCIOC_CTRL_MAP - Error: Invalid argument
mapping control for Tilt (relative)
UVCIOC_CTRL_MAP - Error: Invalid argument
mapping control for Pan Reset
UVCIOC_CTRL_MAP - Error: Invalid argument
mapping control for Tilt Reset
UVCIOC_CTRL_MAP - Error: Invalid argument
mapping control for Pan/tilt Reset
UVCIOC_CTRL_MAP - Error: Invalid argument
mapping control for Focus (absolute)
UVCIOC_CTRL_MAP - Error: Invalid argument
mapping control for LED1 Mode
UVCIOC_CTRL_MAP - Error: Invalid argument
mapping control for LED1 Frequency
UVCIOC_CTRL_MAP - Error: Invalid argument
mapping control for Disable video processing
UVCIOC_CTRL_MAP - Error: Invalid argument
mapping control for Raw bits per pixel
UVCIOC_CTRL_MAP - Error: Invalid argument
o: www-folder-path...: ./www/
o: HTTP TCP port.....: 8080
o: username:password.: disabled
o: commands..........: enabled
我这里显然有报错信息, 上次也是,这此我就没管它,然后进入ubuntu 虚拟机进行测试。
在火狐浏览器里面输入:
192.168.0.232:8080/?action=stream
就可以看到流畅的视频流了。
很想给大家上传我的视频截图,可是我学校用的网络客户端很垃圾,总是和 CSDN 有冲突,不能上传图片,也不能进个人主页。
呵呵:想看图的点这里:
http://hi.baidu.com/%D2%A1%D2%B7%B5%C4%B4%B0%C7%B0%D1%A9/album/linux%20uvc%20%C9%E3%CF%F1%CD%B7
哈:这是我用外网上传的图片:
mjpg-stream移植
一、环境主机环境 :ubuntu 10.10
目标机 :FS2410(S3C2410)
主机工具链 :gcc-4.4.5
交叉工具链 :arm-none-linux-gnueabi-gcc-4.3.2
摄像头 :ZC301
二、移植过程
1、配置内核是内核支持芯片为ZC301的摄像头
Make menuconfig
Device Drivers --->
<*> Multimedia support --->
<*> Video For Linux
[*] Enable Video For Linux API 1 (DEPRECATED) (NEW)
[*] Video capture adapters (NEW) --->
[*] V4L USB devices (NEW) --->
<*> USB Video Class (UVC)
[*] UVC input events device support (NEW)
<*> USB ZC0301[P] webcam support (DEPRECATED)
2、重新编译内核
make zImage
通过上面两个步骤就可以驱动我们的摄像头了。但是这个驱动是基于V4l2的。以前基于 V4L的一些上层应用就不能用了,或需要做大量的修改!这里我们要实现网络视频的功能,以前都是用servfox这个网络视频服务器,但是这个服务器就是 基于V4L的,我们如果想用的话就得对servfox的源码进行修改。这里我们选用另外一种方案mjpg-stream。
3、mjpg-stream的移植
关于mjpg-stream的资料大家可以在下面这个网址查看:http://sourceforge.net/apps/mediawiki/mjpg-streamer/index.php?title=Main_Page
mjpg-stream的移植需要jpeg的库,所以我们先移植jpeg的库
(1)jpeg库的移植
1)jpeg源码包通过下面这个网址下载
http://www.ijg.org/files/jpegsrc.v8b.tar.gz
2)解压源码包
tar xvf jpegsrc.v8b.tar.gz
3)配置源码
cd jpeg-8b
./configure --prefix=/home/linux/s3c2410-2.6.35/video/jpeg --host=arm-none-linux-gnueabi
4)编译
make
5)安装
make install
6)拷贝库到文件系统中
cp //home/linux/s3c2410-2.6.35/video/jpeg /lib/libjpeg.so.8 /source/rootfs/lib
(2)mjpg-stream的移植
1)mjpg-stream源码包通过下面这个网址下载
http://sourceforge.net/projects/mjpg-streamer/
2)解压源码
tar xvf mjpg-streamer-r63.tar.gz
3)修改源码
cd mjpg-streamer-r63
修改顶层makefile及plugins目录中的各级makefile将所有
CC=gcc
修改为
CC=arm-none-linux-gnueabi-gcc
修改plugins/input_uvc/Makfile
修改
CFLAGS += -O2 -DLINUX -D_GNU_SOURCE -Wall -shared -fPIC
为
CFLAGS += -O2 -DLINUX -D_GNU_SOURCE -Wall -shared -fPIC -I/home/linux/s3c2410-2.6.35/video/jpeg/include
修改
$(CC) $(CFLAGS) -ljpeg -o $@ input_uvc.c v4l2uvc.lo jpeg_utils.lo dynctrl.lo
为
$(CC) $(CFLAGS) -ljpeg -L/home/linux/s3c2410-2.6.35/video/jpeg/lib -o $@ input_uvc.c v4l2uvc.lo jpeg_utils.lo dynctrl.lo
jpeg_utils.c:27: fatal error: jpeglib.h: No such file or directory
4)编译
make
5)测试
mkdir /source/rootfs/mjpg
cp *.so /source/rootfs/mjpg
cp mjpg-stream /source/rootfs/bin
打开开开发板运行
mjpg_streamer -i "/mjpg/input_uvc.so" -o "/mjpg/output_http.so -w /www"
在源码目录下有start.sh,这个脚本里有一些mjpg-stream的使用方法及说明
打开一个网页输入下面地址就能够看到一个视频(开发板的IP为192.168.1.202):
http://192.168.1.202:8080/?action=stream
打开一个网页输入下面地址就能够看到一个静态图片:
http://192.168.1.202:8080/?action=snapshot
6)在mjpg源码下有一个www的目录,这个一个网络使用mjpg的实例,结合web服务器(boa)可以实现一些其他相关功能。
基于mjpg-streamer-r63的源码分析之:基础知识详细解释[一]
/article/8011169.htmlFFMPEG库裁剪
经过长期模式,测试,可以用以下方法缩小,在configure的时候加上类似如下的参数:
--disable-encoders --disable-decoders --enable-decoder=h264
解释
--disable-encoders 屏蔽所有编码器
--disable-decoders 屏蔽所有解码器
--enable-decoder=h264 启用h264解码器
由上面可以看出编码器也可以先屏蔽所有编码器,再启用某些编码器。
这样编译出来的 avcodec.dll就会变成 700多K左右,另外几个 avutil.dll、swscale.dll 等等,大小
不会变。它们也没有多大。
相关文章推荐
- 基于H264-USB摄像头的RTP实时视频的传输
- 利用ffmpeg进行摄像头提取视频编码为h264通过RTP发送数据到指定的rtp地址
- 使用ffmpeg捕获USB外部摄像头视频流实时播放
- 使用ffmpeg捕获USB外部摄像头视频流
- 树莓派新版系统上使用mjpg-streamer获取USB摄像头和树莓派专用摄像头RaspiCamera图像
- 使用ffmpeg捕获USB外部摄像头视频流
- mjpg-streamer在树莓派上的使用(树莓派+usb摄像头)
- mjpg-streamer 移植到OK6410,从摄像头采集视频直播
- 使用ffmpeg捕获USB外部摄像头视频流
- 树莓派新版系统上使用mjpg-streamer获取USB摄像头和树莓派专用摄像头RaspiCamera图像
- 基于USB摄像头视频数据采集和利用FFMPEG库函数进行视频数据压缩
- 利用ffmpeg进行摄像头提取视频编码为h264通过RTP发送数据到指定的rtp地址
- ffmpeg学习:ffmpeg下载,播放音频、视频,读取USB摄像头数据流并实时播放
- openwrt 在RT5350上实现mjpg-streamer视频流输出(摄像头格式为YUYV格式)
- openwrt 在RT5350上实现mjpg-streamer视频流输出(摄像头格式为YUYV格式)
- 基于USB摄像头视频数据采集和利用FFMPEG库函数进行视频数据压缩
- mjpg-streamer视频服务器移植
- 一个可以将usb摄像头的视频和麦克风采集的声音以RTMP协议发布到RTMP Server的应用程序
- 使用ffmpeg采集摄像头的视频和语音,合成mpg文件
- 【OpenCV与USB摄像头】1. Ubuntu下查看USB摄像头设备列表与视频读取