Skip to content

Instantly share code, notes, and snippets.

@GerrieWell
Last active November 9, 2018 12:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GerrieWell/c326f0a14fd685da03964465a38ecd25 to your computer and use it in GitHub Desktop.
Save GerrieWell/c326f0a14fd685da03964465a38ecd25 to your computer and use it in GitHub Desktop.
SufraceEncoder.md
    public void drainAllEncoderMuxer(boolean endOfStream) {
        final int TIMEOUT_USEC = 10000;
        if (VERBOSE) Log.d(TAG, "drainAllEncoderMuxer(" + endOfStream + ")");

        if (endOfStream) {
            if (VERBOSE) Log.d(TAG, "sending EOS to mEncoder");
            mEncoder.signalEndOfInputStream();
        }
        recordAndMuxingAudio();
        try {
            if(mOuputFile==null)
                mOuputFile = new FileOutputStream(Environment.getExternalStorageDirectory()+"/test.h264");


            ByteBuffer[] encoderOutputBuffers = mEncoder.getOutputBuffers();
        while (true) {
            int encoderStatus = mEncoder.dequeueOutputBuffer(mBufferInfo, TIMEOUT_USEC);
            Log.v(TAG, "bufferInfo f:" + mBufferInfo.flags + "\tpts:" + mBufferInfo.presentationTimeUs);
            if (encoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
                Log.v(TAG,"INFO_TRY_AGAIN_LATER");
                // no output available yet
                if (!endOfStream) {
                    break;      // out of while
                } else {
                    if (VERBOSE) Log.d(TAG, "no output available, spinning to await EOS");
                }
            } else if (encoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
                // not expected for an mEncoder
                encoderOutputBuffers = mEncoder.getOutputBuffers();
            } else if (encoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                Log.i(TAG, "INFO_OUTPUT_FORMAT_CHANGED");
                // should happen before receiving buffers, and should only happen once
                if (mMuxerStarted) {
                    throw new RuntimeException("format changed twice");
                }
                MediaFormat newFormat = mEncoder.getOutputFormat();
                Log.d(TAG, "mEncoder output format changed: " + newFormat);
                if(mMuxer!=null){
                    mVideoTrackIndex = mMuxer.addTrack(newFormat);
                    tryStartMuxer();
                    //mMuxer.start();
                }
                if(mOuputFile!=null){
                    ByteBuffer sps = newFormat.getByteBuffer("csd-0");
                    ByteBuffer pps = newFormat.getByteBuffer("csd-1");
                    mOuputFile.write(sps.array());
                    mOuputFile.write(pps.array());
                }
            } else if (encoderStatus < 0) {
                Log.w(TAG, "unexpected result from mEncoder.dequeueOutputBuffer: " +
                        encoderStatus);
            } else {
                ByteBuffer encodedData = encoderOutputBuffers[encoderStatus];
                if (encodedData == null) {
                    throw new RuntimeException("encoderOutputBuffer " + encoderStatus +
                            " was null");
                }

                if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) {
                    // @wei The codec config data was pulled out and fed to the muxer when we got
                    // the INFO_OUTPUT_FORMAT_CHANGED status.  Ignore it.
                    if (VERBOSE) Log.d(TAG, "ignoring BUFFER_FLAG_CODEC_CONFIG");
                    mBufferInfo.size = 0;   //or continue
                }

                if (mBufferInfo.size != 0 /*&& mBufferInfo.presentationTimeUs!=0*/) {   //pts is for test todo  the first frame
                    // adjust the ByteBuffer values to match BufferInfo (not needed?)
                    encodedData.position(mBufferInfo.offset);
                    encodedData.limit(mBufferInfo.offset + mBufferInfo.size);
                    if(mVideoStartStampUs==0){
                        mBufferInfo.presentationTimeUs = 0;
                        mVideoStartStampUs = System.currentTimeMillis() * 1000;
                    }else
                        mBufferInfo.presentationTimeUs = System.currentTimeMillis() * 1000 - mVideoStartStampUs;
                    //mBufferInfo.presentationTimeUs - mVideoStartStampUs;
                    if(mMuxer!=null && mMuxerStarted)
                        mMuxer.writeSampleData(mVideoTrackIndex, encodedData, mBufferInfo);
                    if(mOuputFile !=null){
                        byte[] outData = new byte[mBufferInfo.size];                                //copy protected buffer.
                        encodedData.get(outData);
                        mOuputFile.write(outData);
                    }
                    if (VERBOSE)
                        Log.d(TAG, "sent " + mBufferInfo.size + " bytes to muxer, ts=" +mBufferInfo.presentationTimeUs);
                }

                mEncoder.releaseOutputBuffer(encoderStatus, false);

                if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                    if (!endOfStream) {
                        Log.w(TAG, "reached end of stream unexpectedly");
                    } else {
                        if (VERBOSE) Log.d(TAG, "end of stream reached");
                    }
                    break;      // out of while
                }
            }//END OF WHILE true
        }
        } catch (IOException e) {
            e.printStackTrace();
        }                                                                //不给音频单独线程.
        if(mMuxerStarted){
            synchronized (sMuxSync){
                sMuxSync.notifyAll();
            }
        }
/*        if(stopCounterTest++ >=400){
            stopCounterTest = 0;
            mMuxer.stop();
            mMuxer.release();
        }*/
    }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment