首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > Android >

android!怎么加快h264解码速度?352*288

2012-05-31 
android!如何加快h264解码速度?352*288我从论坛中到一个android上的h264解码器,但解码速度很慢,图像也不大

android!如何加快h264解码速度?352*288
我从论坛中到一个android上的h264解码器,但解码速度很慢,图像也不大,只有352*288,播放出来完全是慢动作
请问大侠们,如何提高速度啊!!!
源码如下!
package h264.com;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;//////////////////////////////////////////////////////////////////
import android.graphics.Paint;
import android.graphics.Bitmap.Config;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;




public class H264Android extends Activity {//有关窗口的各种事宜都在Activity中声明

VView vv;

  @Override
  public void onCreate(Bundle savedInstanceState) {//建立并显示一个窗口
  super.onCreate(savedInstanceState);
  vv = new VView(this);
  setContentView(vv);
  }
   
  // Menu item Ids
  public static final int PLAY_ID = Menu.FIRST;  
  public static final int EXIT_ID = Menu.FIRST + 1; 

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
  super.onCreateOptionsMenu(menu);
   
  menu.add(0, PLAY_ID, 0, R.string.play);  
  menu.add(0, EXIT_ID, 1, R.string.exit);

  return true;
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
  switch (item.getItemId()) {  
case PLAY_ID:
{
// 此处设定不同分辨率的码流文件
 
String file = "/sdcard/352x288.h264"; //352x288.264"; //240x320.264"; 
vv.PlayVideo(file);

return true;
}
case EXIT_ID:
{
finish();
return true;
}
  }
  return super.onOptionsItemSelected(item);
  }
}//至此,对窗口的各种说明都完成

class VView extends View implements Runnable{
   
  Bitmap mBitQQ = null;  
   
  Paint mPaint = null;  
   
  Bitmap mSCBitmap = null;  
   
  Matrix matrix = new Matrix(); ////////////////////////////////////////////////////////////////////////////

   
  int width = 352; // 此处设定不同的分辨率
  int height = 288;

  byte [] mPixel = new byte[width*height*2];//创建一个字符串mPixel,单位为byte,个数为width*height*2
   
  ByteBuffer buffer = ByteBuffer.wrap( mPixel );//将mPixel中的元素打包在Buffer中
Bitmap VideoBit = Bitmap.createBitmap(width, height, Config.RGB_565); //以参数所要求的格式创建一个bitmap  
   
int mTrans=0x0F0F0F0F;

String PathFileName; 

  public native int InitDecoder(int width, int height);
  public native int UninitDecoder(); 
  public native int DecoderNal(byte[] in, int insize, byte[] out);
   
  static {
  System.loadLibrary("H264Android");
  }
   
  public VView(Context context) {//构造函数
  super(context);
  setFocusable(true);//使当前视图focused
   
  int i = mPixel.length;
 
  for(i=0; i<mPixel.length; i++)
  {
  mPixel[i]=(byte)0x00;//将mPixel中每个元素初始化为零
  }
  }
   


  public void PlayVideo(String file)//这是VView的核心!
  {
  PathFileName = file;  

  new Thread(this).start();//Thread构造器需要一个Runnable对象,使用start初始化,然后调用runnable的run方法!
  }
   
  @Override protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);//在画布上画图  
   
  //Bitmap VideoBit = 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(VideoBit, 0, 0, null); //在画布上绘制指定的bitmap
  }
   
  int MergeBuffer(byte[] NalBuf, int NalBufUsed, byte[] SockBuf, int SockBufUsed, int SockRemain)
  //将SockBuf中从第(SockBufUsed+1)元素到第(SockBufUsed+SockRemain)个元素add到NalBuf中,返回SockRemain
  {
  int i=0;
  byte Temp;

  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;
  }
  }

  return i;
  }
   
  public void run()  
  {  

  InputStream is = null;
  FileInputStream fileIS=null;
 
  int iTemp=0;
  int nalLen;
 
  boolean bFirst=true;
  boolean bFindPPS=true;
 
  int bytesRead=0;
  int NalBufUsed=0;
  int SockBufUsed=0;
   
  byte [] NalBuf = new byte[40980]; // 40k个元素
  byte [] SockBuf = new byte[2048];//2k个元素
 
 

 
  try
  {  
  fileIS = new FileInputStream(PathFileName);//将文件PathFileName读入该流中
  }
  catch(IOException e) 
  {
  return ;
  } 
 
  InitDecoder(width, height); //根据宽高度初始化解码器
 
  while (!Thread.currentThread().isInterrupted()) //若当前进程没有被打断,便执行 
  {  
  try  
  {  
  bytesRead = fileIS.read(SockBuf, 0, 2048);//从流fileIS中读取2048个byte到SockBuf中,显然将其写满了,返回实际读取数
  //bytesRead = fileIS.read(SockBuf, 0, 2048);
  // if(bytesRead<=0)
  // break;
   
  }
  catch (IOException e) {}
   
  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) // the first start flag
  {
  bFirst = false;
  }
  else // a complete NAL data, include 0x00000001 trail.
  {
  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;
  }
  } 
  //decode nal
  iTemp=DecoderNal(NalBuf, NalBufUsed-4, mPixel);  

  if(iTemp>0)
  postInvalidate(); //使用postInvalidate可以直接在线程中更新界面 // postInvalidate();
  }

  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 (IOException e) {
e.printStackTrace();
  }
  UninitDecoder();
  }  
}
问题可能对于高手不太难,我在线等一会啊~
谢了!

[解决办法]
硬件怎么样?
用的不会是emulator吧


[解决办法]
这个跟你的码流有关系,另外看你所用的是什么硬件平台,平台驱动可以做相关的设置
[解决办法]
大哥,你在JAVA里做解码,然后构造BITMAP显示?不慢才怪呢!
做解码,最好用native代码。
[解决办法]
模拟器的CPU据说只有200MHZ
[解决办法]
看代码也是调用native代码实现解码的啊。
关注ing
[解决办法]
楼主这个代码是调用的一个ffmpeg中的h264移植到android的native代码,播352*288的是会卡,可能是模拟器的缘故吧。
[解决办法]
JNI调用,虽然是本地的,但解码用的还是软件解码,接口函数背后是算法,没有使用硬件加速的缘故
[解决办法]

探讨
我也想知道,如何集成硬解码????

热点排行