APP与终端通信经验七(解析与解码的关联)

在前几篇已经顺利的使用serversocket线程把远程推送的流媒体视频和音频数据保存到两个集合对象里了。
接下来就是需要继续开启线程来对解析的数据进行播放了。
先看音频,开启一个线程

  			long start = System.currentTimeMillis();
                        getG726();//解码播放
                        long end = System.currentTimeMillis();
                        long end_start = end - start;
//                Log.e("@@", "@@g726:" + end_start);
                        if (end_start >= time) {
                            g726Handler.postDelayed(myg726Runnable, 0);
                        } else {
                            g726Handler.postDelayed(myg726Runnable, time - end_start);
                        }

解码播放,耗时大于定时器的时间,那么播放下一帧音频以耗时为准。否则,用规定的20ms时间减去耗时作为剩下的时间作为等待的时间。确保每一帧的时间(解码播放时间+等待时间)在20ms

具体的解码过程

 if (10 >= server.getClientInputThread().allg726.size()) { 
        } else {
             if (isstartvideo) {//开始播放后开始  合并两帧解码  音质相对好点,音频RTP头26,另含4字节海思头
                g726data = server.getClientInputThread().allg726.get(8);
                g726data1 = server.getClientInputThread().allg726.get(9);
                if (isPlayAudio) {
                    if (g726data != null && g726data1 != null) {//4字节的海思头已在开始去掉
                        g726temp = new byte[g726data.length + g726data1.length - 0];
                        System.arraycopy(g726data, 0, g726temp, 0, g726data.length - 0);
                        System.arraycopy(g726data1, 0, g726temp, g726data.length - 0, g726data1.length - 0);
                        int audiotype=server.getClientInputThread().audioType;
                        if (audiotype==8) {
                            pcm = HstAVNativeJNI.OneG726Topcm(g726temp);
                        }else if (audiotype==6) {
                            G711Decode.decode(g726temp, 0, g726temp.length, pcm);
                        }
                        else
                            {
                            System.arraycopy(g726temp,0,pcm,0,g726temp.length);
                        }

                        /**
                         * 模拟环境下  音频数据不够长(暂时用填补海思头的方法)
                         */
//                        byte[] pcm2=new byte[pcm.length+64];
//                        System.arraycopy(pcm,0,pcm2,0,pcm.length);
//                        for (int i = 1; i <=64 ; i++) {
//                            pcm2[pcm2.length-i]=(byte)0xf0;
//                        }
//                        Log.e("@@","@@"+g726data.length+"   "+pcm.length);
                        mat.playAudioTrack(pcm, 0, pcm.length);
                    }

                } else {

                }
                server.getClientInputThread().allg726.remove(9);
//                if (g726data!=null){
//                    g726temp=new byte[g726data.length-30];
//                    System.arraycopy(g726data,30,g726temp,0,80);
//                    pcm = HstAVNativeJNI.OneG726Topcm(g726temp);
//                    mat.playAudioTrack(pcm, 0, pcm.length);
//                }
                server.getClientInputThread().allg726.remove(8);
            }
        }

音频把两帧音频合并为一帧然后在播,音质好。

视频帧
在播放视频时,把解码视频和播放视频放到了两个线程,这是和音频的差异。

  /**
     * 播放图片线程
     */
    private void showH264() {
        h264Handler = new Handler();
        myh264Runnable = new Runnable() {
            public void run() {
                 if (server != null) {
                     if (server.getClientInputThread() != null) {
                        geth264();
                    }
                }
                h264Handler.postDelayed(myh264Runnable, 0);
            }
        };
        h264Handler.postDelayed(myh264Runnable, 0);
    }
/**
     * 显示一帧图片
     */
    private void geth264() {
        if (server==null||server.getClientInputThread()==null){
            return;
        }
        if (0 == server.getClientInputThread().allmp4.size()) {

        } else {
             data = server.getClientInputThread().allmp4.get(0);

            if (data != null) {
                 temp = new byte[data.length];
                System.arraycopy(data, 0, temp, 0, data.length );
                if (temp.length > 5) {
                    if (temp[0] == 0x00 && temp[1] == 0x00 && temp[2] == 0x00 && temp[3] == 0x01 && temp[4] == 0x67) {
                         if (isstart) {
                            temponedata = new byte[frontlength];
                            System.arraycopy(onedata, 0, temponedata, 0, frontlength);
                            h264list.add(temponedata);
                            frontlength = 0;
                            System.arraycopy(temp, 0, onedata, frontlength, temp.length);
                            frontlength += temp.length;
                         } else {
                            isstart = true;
                            frontlength = 0;
                            System.arraycopy(temp, 0, onedata, frontlength, temp.length);
                            frontlength += temp.length;
                        }
                    } else if (temp[0] == 0x00 && temp[1] == 0x00 && temp[2] == 0x00 && temp[3] == 0x01 && temp[4] == 0x61) {
                        if (isstart) {
                            temponedata = new byte[frontlength];
                            System.arraycopy(onedata, 0, temponedata, 0, frontlength);
                            h264list.add(temponedata);
                   
                            frontlength = 0;
                            System.arraycopy(temp, 0, onedata, frontlength, temp.length);
                            frontlength += temp.length;
                        }
                    } else {
                        if (isstart) {
                            System.arraycopy(temp, 0, onedata, frontlength, temp.length);
                            frontlength += temp.length;
                        }
                    }
                } else {
                    if (isstart) {
                        System.arraycopy(temp, 0, onedata, frontlength, temp.length);
                        frontlength += temp.length;
                    }
                }
            }
            server.getClientInputThread().allmp4.remove(0);
        }
    }

 /**
     * 播放
     */
    private void show() {
        showHandler = new Handler();
        myshowRunnable = new Runnable() {
            public void run() {

                Log.e("@@:a:"+a, "@@@result:show"+h264list.size()+"isstarrvideo:"+isstartvideo );
                if (h264list.size() > 2) {
                    if (isstartvideo==false) {
                        playRealAVUI.setWaitForMsgIndex(0);
                    }
                    isstartvideo = true;
                    if (onvideoChange != null) {
                        onvideoChange.setOnVideoChangeListener(isstartvideo);
                    }
                }
                long start = System.currentTimeMillis();
                if (isstartvideo) {
                    if (h264list.size() > 0) {
                        listdata = h264list.get(0);
                        h264list.remove(0);
                        if (listdata != null) {
                            if (listdata[0] == 0x00 && listdata[1] == 0x00 && listdata[2] == 0x00 && listdata[3] == 0x01 && listdata[4] == 0x67) {
                                if (a == 0) {
                                    HstAVNativeJNI.play2(listdata, surfaceViewHolder.getSurface());
                                } else if (a == 1) {
                                    HstAVNativeJNI.play22(listdata, surfaceViewHolder.getSurface());
                                } else if (a == 2) {
                                    HstAVNativeJNI.play23(listdata, surfaceViewHolder.getSurface());
                                } else if (a == 3) {
                                    HstAVNativeJNI.play24(listdata, surfaceViewHolder.getSurface());
                                }

                            } else {
                                if (a == 0) {
                                    HstAVNativeJNI.play2(listdata, surfaceViewHolder.getSurface());
                                } else if (a == 1) {
                                    HstAVNativeJNI.play22(listdata, surfaceViewHolder.getSurface());
                                } else if (a == 2) {
                                    HstAVNativeJNI.play23(listdata, surfaceViewHolder.getSurface());
                                } else if (a == 3) {
                                    HstAVNativeJNI.play24(listdata, surfaceViewHolder.getSurface());
                                }
                            }
                        }

                        hwhandler.sendEmptyMessage(0x123);
                    }
                }
                long end = System.currentTimeMillis();
                long end_start = end - start;
//                Log.e("@@", "@@show:" + end_start);
                if (end_start > 40) {
                    showHandler.postDelayed(myshowRunnable, 0);
                } else {
                    showHandler.postDelayed(myshowRunnable, 40 - end_start);
                }
            }
        };
        showHandler.postDelayed(myshowRunnable, 0);
    }

视频宽高适配

  Handler hwhandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (!isClicked) {
                return;
            }
            int h = surfaceView.getLayoutParams().height;
            int w = surfaceView.getLayoutParams().width;
            if (a == 0) {
                if (w > 0) {
                    h = (int) (w * chufa(HstAVNativeJNI.getHeight(), HstAVNativeJNI.getWidth()));
                } else {
                    w = (int) (h * chufa(HstAVNativeJNI.getWidth(), HstAVNativeJNI.getHeight()));
                }
            } else if (a == 1) {
                if (w > 0) {
                    h = (int) (w * chufa(HstAVNativeJNI.getHeight2(), HstAVNativeJNI.getWidth2()));
                } else {
                    w = (int) (h * chufa(HstAVNativeJNI.getWidth2(), HstAVNativeJNI.getHeight2()));
                }
            } else if (a == 2) {
                if (w > 0) {
                    h = (int) (w * chufa(HstAVNativeJNI.getHeight3(), HstAVNativeJNI.getWidth3()));
                } else {

                    w = (int) (h * chufa(HstAVNativeJNI.getWidth3(), HstAVNativeJNI.getHeight3()));
                }
            } else if (a == 3) {
                if (w > 0) {
                    h = (int) (w * chufa(HstAVNativeJNI.getHeight4(), HstAVNativeJNI.getWidth4()));
                } else {
                    w = (int) (h * chufa(HstAVNativeJNI.getWidth4(), HstAVNativeJNI.getHeight4()));
                }
            }
//            Log.e("@@","@@w="+w+"  h="+h);
            surfaceViewHolder.setFixedSize(w, h);//设置视频大小
            ll_progress.setVisibility(View.GONE);
            tv_zhegai.setVisibility(View.GONE);
         }
    };
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值