当前位置:编程学习 > wap >>

求高手帮助,关于视频文件得到视频帧数据问题

各位高手,大家好。我是一个android新手,原来也没有怎么接触过多媒体方面的知识,我想问下在android 2.0下如何解析h.264 的视频文件得到视频帧数据。 --------------------编程问答-------------------- 有高手解答下嘛。。小弟跪谢~~ --------------------编程问答-------------------- 这个你要看opencore了 --------------------编程问答--------------------
引用 2 楼 ultrapro 的回复:
这个你要看opencore了

从什么地方入手呢,我查了下opencore是基于C++的。。小弟只想用android提供的api来干这件事情。 --------------------编程问答-------------------- 这是一个解析本地h.264并播放的例子,希望对你有帮助。看不懂的可以先学习h.264的相关概念,http://hi.baidu.com/sdlyfdy/blog/category/h.264

public class H264Android extends 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.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;   
    
    int width = 352;  
    int height = 288;

    byte [] mPixel = new byte[width*height*2];
    
    ByteBuffer buffer = ByteBuffer.wrap( mPixel );
Bitmap VideoBit = Bitmap.createBitmap(width, height, Config.RGB_565);           
   
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);
        
        int i = mPixel.length;
    
        for(i=0; i<mPixel.length; i++)
        {
         mPixel[i]=(byte)0x00;
        }
    }
           
    public void PlayVideo(String file)
    {
     PathFileName = file;   

     new Thread(this).start();
    }
        
    @Override protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);   
        
          
    
        VideoBit.copyPixelsFromBuffer(buffer);    
        canvas.drawBitmap(VideoBit, 0, 0, null); 
    }
    
    int MergeBuffer(byte[] NalBuf, int NalBufUsed, byte[] SockBuf, int SockBufUsed, int SockRemain)
    {
     int  i=0;
     byte Temp;

     for(i=0; i<SockRemain; i++)
     {
     Temp  =SockBuf[i+SockBufUsed];
     NalBuf[i+NalBufUsed]=Temp;

     mTrans <<= 8;
     mTrans  |= Temp;

     if(mTrans == 1)      {
     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]; 
     byte [] SockBuf = new byte[2048];
    
     try
     {    
    fileIS = new FileInputStream(PathFileName);
     }
     catch(IOException e) 
     {
     return ;
     } 
    
     InitDecoder(width, height); 
 
        while (!Thread.currentThread().isInterrupted())   
        {   
            try  
            {   
           bytesRead = fileIS.read(SockBuf, 0, 2048);
            }
            catch (IOException e) {}
            
            if(bytesRead<=0)
             break;
            
            SockBufUsed =0;
            
     while(bytesRead-SockBufUsed>0)
     {
     nalLen = MergeBuffer(NalBuf, NalBufUsed, SockBuf, SockBufUsed, bytesRead-SockBufUsed);
    
     NalBufUsed += nalLen;
     SockBufUsed += nalLen;
    
     while(mTrans == 1)
     {
     mTrans = 0xFFFFFFFF;

     if(bFirst==true)  {
     bFirst = false;
     }
     else       {
     if(bFindPPS==true)      {
     if( (NalBuf[4]&0x1F) == 7 )
     {
     bFindPPS = false;
     }
     else
     {
         NalBuf[0]=0;
          NalBuf[1]=0;
          NalBuf[2]=0;
          NalBuf[3]=1;
         
          NalBufUsed=4;
         
     break;
     }
     }
          iTemp=DecoderNal(NalBuf, NalBufUsed-4, mPixel);   

                 if(iTemp>0)
                  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();
    }  
}

--------------------编程问答--------------------

/*
 * Class:     h264_VView
 * Method:    InitDecoder
 * Signature: ()I
 */
jlong Java_h264_VView_InitDecoder(JNIEnv* env, jobject thiz)
{
CreateYUVTab_16();
Decoder * de  = (Decoder *)av_malloc(sizeof(Decoder));
de->c = avcodec_alloc_context();

avcodec_open(de->c);

de->picture  = avcodec_alloc_frame();//picture= malloc(sizeof(AVFrame));

return (jlong)de;
}

/*
 * Class:     h264_VView
 * Method:    UninitDecoder
 * Signature: ()I
 */
jint Java_h264_VView_UninitDecoder(JNIEnv* env, jobject thiz,jlong pDecoder)
{
DeleteYUVTab();
if (pDecoder)
{
Decoder * de=(Decoder * )pDecoder;
if(de->c)
{
decode_end(de->c);
free(de->c->priv_data);

free(de->c);
de->c = NULL;
}

if(de->picture)
{
free(de->picture);
de->picture = NULL;
}
free(de);
return 1;
}
else
return 0;




}

/*
 * Class:     h264_VView
 * Method:    DecoderNal
 * Signature: ([B[I)I
 */
jint Java_h264_VView_DecoderNal(JNIEnv* env, jobject thiz,jlong pDecoder,jbyteArray in, jint nalLen, jbyteArray out)
{
int i;
int imod;
int got_picture;
if (pDecoder)
{
Decoder * de=(Decoder * )pDecoder;

jbyte * Buf = (jbyte*)(*env)->GetByteArrayElements(env, in, 0);
jbyte * Pixel= (jbyte*)(*env)->GetByteArrayElements(env, out, 0);

int consumed_bytes = decode_frame(de->c, de->picture, &got_picture, Buf, nalLen);

if(consumed_bytes > 0)
{
DisplayYUV_16((int*)Pixel, de->picture->data[0], de->picture->data[1], de->picture->data[2], de->c->width, de->c->height, de->picture->linesize[0], de->picture->linesize[1],  de->c->width);
}

(*env)->ReleaseByteArrayElements(env, in, Buf, 0);
(*env)->ReleaseByteArrayElements(env, out, Pixel, 0);

return consumed_bytes;
}
else
return 0;
}
--------------------编程问答-------------------- 来人帮忙啊~~ --------------------编程问答-------------------- 我想到一个思路,我看了下摄像头录制视频的时候,很容易就可以提取每帧数据,通过实现PreviewCallback的onPreviewFrame方法。那么请问大家知不知道在播放视频时,是否也有相应的回调接口有类似这样功能的方法来获取每帧数据呢? --------------------编程问答-------------------- 我还想到一种办法,如果利用局部截屏是否可行呢。。各位高手们,帮帮忙。。。
补充:移动开发 ,  Android
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,