
u01468235005-14 20:30
等级
3楼
这个是从论坛中到一个android上的h264,代码如下。
packageh264.com;
importjava.io.FileInputStream;
importjava.io.IOException;
importjava.io.InputStream;
importjava.nio.ByteBuffer;
importandroid.app.Activity;
importandroid.content.Context;
importandroid.graphics.Bitmap;
importandroid.graphics.Canvas;
importandroid.graphics.Matrix;//////////////////////////////////////////////////////////////////
importandroid.graphics.Paint;
importandroid.graphics.Bitmap.Config;
importandroid.os.Bundle;
importandroid.view.Menu;
importandroid.view.MenuItem;
importandroid.view.View;
publicclassH264AndroidextendsActivity{//有关窗口的各种事宜都在Activity中声明
VViewvv;
@Override
当多个窗口同时 attach 到同一个容器的时候,所有窗口都会同步显示。介面 2:实时数据接收窗口,用于实时接收并显示各生产线看板的各项数据(根据看板的数量,刷新时间在 10 秒至 2 分钟不等),也可以通过此窗口修改看板中的数据(下图仅作参考)。支持信号源轮询查看功能,可以选定多路信号在指定窗口中以一定的时间间隔按次序进行轮流查询显示,无须切换开关周边其他信号窗口,不影响其他信号的正常显示,需提供软件界面截图并加盖厂家鲜章。
super.onCreate(savedInstanceState);
vv=newVView(this);
setContentView(vv);
}
//MenuitemIds
publicstaticfinalintPLAY_ID=Menu.FIRST;
publicstaticfinalintEXIT_ID=Menu.FIRST+1;
@Override
publicbooleanonCreateOptionsMenu(Menumenu){
super.onCreateOptionsMenu(menu);
menu.add(0,PLAY_ID,0,R.string.play);
menu.add(0,EXIT_ID,1,R.string.exit);
returntrue;
}
@Override
publicbooleanonOptionsItemSelected(MenuItemitem){
switch(item.getItemId()){
casePLAY_ID:

{
//此处设定不同分辨率的码流文件
Stringfile="/sdcard/352x288.h264";//352x288.264";//240x320.264";
vv.PlayVideo(file);
returntrue;
}
caseEXIT_ID:
{
finish();
returntrue;
}
}
returnsuper.onOptionsItemSelected(item);
}
}//至此,对窗口的各种说明都完成
classVViewextendsViewimplementsRunnable{
BitmapmBitQQ=null;
PaintmPaint=null;
BitmapmSCBitmap=null;
Matrixmatrix=newMatrix();////////////////////////////////////////////////////////////////////////////
intwidth=352;//此处设定不同的分辨率
intheight=288;
//创建第三个子roi区域 cvsetimageroi(result, cvrect(frame->width * 2, 0, frame->width, frame->height))。this.grid=newbyte[images.height][images.width]。这个小jquery插件为css min-width, min-height, max-width, max-height, border-*-width, margin, 和padding 属性添加支持。
在最终opengl es写入这些buffer时,opengl es提供一些mask 函数可以控制color buffer 中rgba通道,是否允许写入depth buffer 等,这些mask 函数可以打开或是关闭某个通道,只有通道打开后视频软件无法播放,对应的分量才会写入指定buffer,比如你可以关闭红色通道,这样最后写道color buffer中就不含有红色。除了*wrap*系列方法以及empty()、clone()方法外,当使用上述插入、追加、替换、删除方法时,如果用于插入/追加/替换/删除的元素是文档中的元素,则这些元素将从原位置上消失。 bytebuffer buffer = bytebuffer.wrap(b)。
BitmapVideoBit=Bitmap.createBitmap(width,height,Config.RGB_565);//以参数所要求的格式创建一个bitmap
intmTrans=0x0F0F0F0F;
StringPathFileName;
publicnativeintInitDecoder(intwidth,intheight);
publicnativeintUninitDecoder();
publicnativeintDecoderNal(byte[]in,intinsize,byte[]out);
static{
System.loadLibrary("H264Android");
}
publicVView(Contextcontext){//构造函数
super(context);
setFocusable(true);//使当前视图focused
inti=mPixel.length;
for(i=0;i<mPixel.length;i++)
{
mPixel[i]=(byte)0x00;//将mPixel中每个元素初始化为零
}

}
publicvoidPlayVideo(Stringfile)//这是VView的核心!
{
PathFileName=file;
newThread(this).start();//Thread构造器需要一个Runnable对象,使用start初始化,然后调用runnable的run方法!
}
@OverrideprotectedvoidonDraw(Canvascanvas){
super.onDraw(canvas);//在画布上画图
//BitmapVideoBit=Bitmap.createBitmap(width,height,Config.RGB_565);//.ARGB_8888);在这面建Bitmap,视频播放更慢,貌似每三帧间还有暂停~
VideoBit.copyPixelsFromBuffer(buffer);//makeBuffer(data565,N));将buffer中的像素复制进VideoBit,但buffer中的像素并不变。
matrix.postScale(1,1);///////////////////////////////////////////////////////////////////////////
matrix.setRotate(90,120,130);////////////////////////////////////////////////////////////////////
canvas.drawbitmap(bitmap,0,0,paint)。 canvas.drawbitmap(bitmap, 0, 0, paint)。 canvas.drawbitmap(bitmap,0,0,paint)。
}
intMergeBuffer(byte[]NalBuf,intNalBufUsed,byte[]SockBuf,intSockBufUsed,intSockRemain)
//exec返回的数组第1到n元素中包含的是匹配中出现的任意一个子匹配。向量索引:索引格式为:向量1[向量2],返回的结果为向量1中索引为向量2的那些元素,注意元素允许重复。assign() 给list赋值 back() 返回最后一个元素 clear() 删除所有元素 empty() 如果list是空的则返回true end() 返回末尾的迭代器 erase() 删除一个元素 front() 返回第一个元素 get_allocator() 返回list的配置器 insert() 插入一个元素到list中 max_size() 返回list能容纳的最大元素数量 merge() 合并两个list pop_back() 删除最后一个元素 pop_front() 删除第一个元素 push_back() 在list的末尾添加一个元素 push_front() 在list的头部添加一个元素 rbegin() 返回指向第一个元素的逆向迭代器 remove() 从list删除元素 remove_if() 按指定条件删除元素 rend() 指向list末尾的逆向迭代器 resize() 改变list的大小 reverse() 把list的元素倒转 size() 返回list中的元素个数 sort() 给list排序 splice() 合并两个list swap() 交换两个list unique() 删除list中重复的元素。
{
inti=0;
byteTemp;
for(i=0;i<SockRemain;i++)
{
Temp=SockBuf[i+SockBufUsed];
NalBuf[i+NalBufUsed]=Temp;//将剩余的Sock中SockRemain个像素全部都存NalBuf[]中,从NalBuf[NalBufUsed]接着存~
mTrans<<=8;//左移八位
mTrans|=Temp;//和Temp各位相或
if(mTrans==1)//找到一个开始byte??
{
i++;
break;
}
}
returni;
}
publicvoidrun()
{
InputStreamis=null;
FileInputStreamfileIS=null;
intiTemp=0;
intnalLen;
booleanbFirst=true;
booleanbFindPPS=true;

intbytesRead=0;
intNalBufUsed=0;
intSockBufUsed=0;
byte[]NalBuf=newbyte[40980];//40k个元素
byte[]SockBuf=newbyte[2048];//2k个元素
try
{
fileIS=newFileInputStream(PathFileName);//将文件PathFileName读入该流中
}
catch(IOExceptione)
{
return;
}
InitDecoder(width,height);//根据宽高度初始化
while(!Thread.currentThread().isInterrupted())//若当前进程没有被打断,便执行
{
try
{
功 能:从一个文件流中读数据,最多读取count个元素,每个元素size字节,如果调用成功返回实际读取到的元素个数,如果不成功返回 0。功能是从流中读取一个字符,结果保存在引用ch中,如果到文件尾,返回空字符。 功能是从流中读取一个字符视频软件无法播放,结果保存在引用ch中,如果到文件尾,返回空字符。
//bytesRead=fileIS.read(SockBuf,0,2048);
//if(bytesRead<=0)
//break;
}
catch(IOExceptione){}
if(bytesRead<=0)
break;
SockBufUsed=0;
while(bytesRead-SockBufUsed>0)//若SockBuff中所存byte数,大于SockBufUsed数
{
nalLen=MergeBuffer(NalBuf,NalBufUsed,SockBuf,SockBufUsed,bytesRead-SockBufUsed);
NalBufUsed+=nalLen;
SockBufUsed+=nalLen;
while(mTrans==1)
{
mTrans=0xFFFFFFFF;
if(bFirst==true)//thefirststartflag
{
bFirst=false;
}
else//acompleteNALdata,include0x00000001trail.
{

if(bFindPPS==true)//true
{
if((NalBuf[4]&0x1F)==7)
{
bFindPPS=false;
}
else
{
NalBuf[0]=0;
NalBuf[1]=0;
NalBuf[2]=0;
NalBuf[3]=1;
NalBufUsed=4;
break;
}
}
//decodenal
iTemp=DecoderNal(NalBuf,NalBufUsed-4,mPixel);
if(iTemp>0)
由于在ios中除了主线程,其他子线程是独立于cocoa touch的,所以只有主线程可以更新ui界面(新版ios中,使用其他线程更新ui可能也能成功,但是不推荐)。2、打开软件之后,,想要将软件进行升级更新需要点击【设置】选项界面中,在这个界面中可以进行多种操作,检查更新、卸载,还有一些软件使用的小设置都在这个界面中进行。程序比较简单,但是需要注意执行步骤:当点击了“加载图片”按钮后启动一个新的线程,这个线程在演示中大概用了5s左右,在这5s内ui线程是不会阻塞的,用户可以进行其他操作,大约5s之后图片下载完成,此时调用ui线程将图片显示到界面中(这个过程瞬间完成)。
}
NalBuf[0]=0;
NalBuf[1]=0;
NalBuf[2]=0;
NalBuf[3]=1;
NalBufUsed=4;
}
}
}
try{
if(fileIS!=null)
fileIS.close();
if(is!=null)
is.close();
}
catch(IOExceptione){
e.printStackTrace();
}
UninitDecoder();
}
}
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/bofangqi/article-116224-1.html
特别申明