请选择 进入手机版 | 继续访问电脑版
正在上传图片(0/1)

关于视频预览硬解的问题

 0
手机看帖 15 6269
hi,各位,最近在弄dji摄像头预览的视频数据处理工作,经过一段时间的网上调研,准备采用硬解码的方式,
以下是我的代码,有没有人能帮我看一下问题出在哪呢。
//解码器初始化
MediaCodec mediaCodec =  MediaCodec.createDecoderByType("video/avc");
MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", 640, 360);
if(mediaCodec == null)
{
            Log.e("","mediaCodec == null");
            return;
}
mediaCodec.configure(mediaFormat, null, null, 0);
mediaCodec.start();


//视频数据回调接口,我的解码在这里面处理的,这个代码参考的英文网站http://forum.dji.com/forum.php?m ... mp;page=1#pid137903
mReceivedVideoDataCallBack = new DJIReceivedVideoDataCallBack(){
            
            private int packetLength = 0;
            private ByteBuffer accessUnitBuffer = ByteBuffer.allocate( 50000 ); //数据流缓冲区,存放一帧完整的数据流
            

            @Override
            public void onResult(byte[] videoBuffer, int size)
            {
                // TODO Auto-generated method stub
               

                for(int i = 0; i < size-5; i++)
                {
                     //查找H264数据流中的结束符,将当前帧数据送到mediaCodec解码
                    if(videoBuffer== 0x00 && videoBuffer[i+1]== 0x00
                    && videoBuffer[i+2]== 0x00 && videoBuffer[i+3]== 0x01
                    && videoBuffer[i+4]== 0x09)
                    {
                         handler.sendMessage(handler.obtainMessage(SHOWTOAST, "packetLength = "+ packetLength));        
                        ByteBuffer[] inputBuffers = mediaCodec.getInputBuffers();
                        ByteBuffer[] outputBuffers = mediaCodec.getOutputBuffers();
                        int inputBufferIndex = mediaCodec.dequeueInputBuffer(-1);
                        handler.sendMessage(handler.obtainMessage(SHOWTOAST, "inputBufferIndex = "+ inputBufferIndex));
                        if (inputBufferIndex >= 0) {
                            ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
                            inputBuffer.clear();
                            inputBuffer.put(accessUnitBuffer);
                            mediaCodec.queueInputBuffer(inputBufferIndex, 0, packetLength, presentationTime, 0);
                            presentationTime += 100;
                            packetLength = 0;
                            accessUnitBuffer.clear();
                            accessUnitBuffer.rewind();

                        }

                        //解码后的数据存入到dataListOut中,为后面写入文件准备
                        MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();            
                        int outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);
                        handler.sendMessage(handler.obtainMessage(SHOWTOAST, "outputBufferIndex = "+ outputBufferIndex));
                        //现在问题就在这,outputBufferIndex 这个数值得到的是-1,没有解码数据,有没有大神能帮我找一下原因啊
                        while (outputBufferIndex >= 0) {
                            ByteBuffer outputBuffer = outputBuffers[outputBufferIndex];
                            byte[] outData = new byte[bufferInfo.size];
                            outputBuffer.get(outData);
                            if (dataListOut != null)
                                dataListOut.add(outData);
                           
                            mediaCodec.releaseOutputBuffer(outputBufferIndex, false);
                            outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);
                        }

                        //解码后的一帧数据写入文件
                        handler.sendMessage(handler.obtainMessage(SHOWTOAST, "dataListOut.size() = "+ dataListOut.size()));
                        if(dataListOut.size()!=0)
                        {
                            try {
                                FileOutputStream fout = new FileOutputStream(createNewFileName());
                                int offset = 0;
                                for(int j = 0; j< dataListOut.size();j++)
                                {
                                    fout.write(dataListOut.get(j),offset,dataListOut.get(j).length);
                                    offset += dataListOut.get(j).length;
                                }
                                fout.close();
                                handler.sendMessage(handler.obtainMessage(SHOWTOAST, "write file succes"));
                                dataListOut.clear();

                            } catch (FileNotFoundException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }

                    }else
                    {
                        accessUnitBuffer.put(videoBuffer);
                        packetLength++;
                    }
                    
                }
                              
             //   mDjiGLSurfaceView.setDataToDecoder(videoBuffer, size);

            }

  
        };

然后还有一个问题,这样解码后得到的一帧的图像数据应该是YUV格式的吧,我将YUV格式的文件存为.raw后缀名的文件可以吗,用什么软件可以查看这种格式的图片



评论
上传
你需要登录之后才能回帖    登录 | 注册
yasenhu   2015-8-17 2#
你是用的是什么型号的设备呢, Mediacodec 好像在一些设备上会出这样的问题 (outputBufferIndex = -1),要不然换一个设备试一试?
楼主   2015-8-18 3#
yasenhu 发表于 2015-8-17 23:33
你是用的是什么型号的设备呢, Mediacodec 好像在一些设备上会出这样的问题 (outputBufferIndex = -1),要 ...
我用的note3, 4.3版本的,应该不是设备问题,我用这个设备运行Android SDK里的mediaCodec例子播放MP4视频都没有问题

楼主   2015-8-18 4#
yasenhu 发表于 2015-8-17 23:33
你是用的是什么型号的设备呢, Mediacodec 好像在一些设备上会出这样的问题 (outputBufferIndex = -1),要 ...
我感觉还是我代码哪有问题,可能送进去解码的数据不对
shadowyin   2015-8-18 5#
4423839 发表于 2015-8-18 09:40
我感觉还是我代码哪有问题,可能送进去解码的数据不对
你卡在哪了,我研究好久了。我也一直有问题

楼主   2015-8-18 6#
shadowyin 发表于 2015-8-18 09:48
你卡在哪了,我研究好久了。我也一直有问题
就是上面红色的部分。我现在感觉应该是我送到解码器的数据不是完整的一帧缓存,
又不确定具体是哪的问题,哎,好艰难,版上不知道有没有人能解答下,
我看之前有人说用硬解码实现了的,能贴下代码就好了

shadowyin   2015-8-18 7#
我的也是-1那里。。
yasenhu   2015-8-18 8#
if(videoBuffer== 0x00 && videoBuffer[i+1]== 0x00
                    && videoBuffer[i+2]== 0x00 && videoBuffer[i+3]== 0x01
                    && videoBuffer[i+4]== 0x09)
这样不一定取得就是一帧吧?应该找两个 00 00 00 01 09 之间的才是一帧?
yasenhu   2015-8-18 9#
4423839 发表于 2015-8-18 11:02
就是上面红色的部分。我现在感觉应该是我送到解码器的数据不是完整的一帧缓存,
又不确定具体是哪的问题 ...
我想了一下,是不是第一次截取的有可能不是完整的一帧,因为我们并不知道videobuffer在最开始的时候传过来的是不是一帧的起始,你这样在第一次循环的时候很可能只获取到了完整帧的一部分,你试一试加一个flag,将第一次获取到的那一帧舍弃,然后后面的帧就能保证是在两个 0x00 0x00 0x00 0x01 0x09 之间的完整帧,再进行解码
楼主   2015-8-18 10#
yasenhu 发表于 2015-8-18 16:52
我想了一下,是不是第一次截取的有可能不是完整的一帧,因为我们并不知道videobuffer在最开始的时候传过 ...
有道理啊,我赶紧去试一下
yasenhu   2015-8-18 11#
4423839 发表于 2015-8-18 18:23
有道理啊,我赶紧去试一下
恩,看看私信给你留言了
shadowyin   2015-8-19 12#
4423839 发表于 2015-8-18 18:23
有道理啊,我赶紧去试一下
行了么。。我就是取的09之间的一帧啊,还是不行


楼主   2015-8-19 13#
shadowyin 发表于 2015-8-19 09:36
行了么。。我就是取的09之间的一帧啊,还是不行
还没有试呢。。昨天下班了
shadowyin   2015-8-19 14#
4423839 发表于 2015-8-19 09:46
还没有试呢。。昨天下班了
现在好了么。。。。。


楼主   2015-8-21 15#
shadowyin 发表于 2015-8-19 18:47
现在好了么。。。。。
没有呢。搞不定我又去试ffmpeg解码去了

siberiamark   2015-9-2 16#
楼主在吗。。。你的哪个型号飞机? 我的PV+,之前分析的码流 ,那个09的分隔符 不是单独一次传回来的, 传4次是1帧,5个NAL单元,最后那个分隔符和倒数第二个NAL单元是一起的
收藏 点赞 评论
分享至:
回复:
上传
取消 评论
快速回复 返回顶部 返回列表