手动创建MediaFormat时,是否需要通过muxer的writeSampleData方法写入PPS和SPS?

如题,我是参考 http://blog.51cto.com/ticktick/1710743 改写了一下,但是MediaFormat是通过手动创建的,通过Extractor解出来的Buffer手动的创建MediaFormat,遇到几个问题:将第一帧写入MediaFormat后手动调用MediaExtractor的advance方法运行后直接crash,error是muxer fail to stop 2.SPS和PPS写入MediaFormat后是否还需要再通过muxer写入,不写入的话时间戳会不会有问题?

public class MainActivity extends Activity {

private static final String SDCARD_PATH = Environment.getExternalStorageDirectory().getPath();
private static final String INPUT_FILEPATH = SDCARD_PATH + "/input.mp4";
private static final String OUTPUT_FILEPATH = SDCARD_PATH + "/output.mp4";
private int i = 0;
private TextView mLogView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mLogView = (TextView) findViewById(R.id.LogView);
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                transcode(INPUT_FILEPATH, OUTPUT_FILEPATH);
            } catch (IOException e) {
                e.printStackTrace();
                logout(e.getMessage());
            }
        }
    }).start();
}

protected boolean transcode(String input, String output) throws IOException {

    logout("start processing...");

    MediaMuxer muxer = null;

    MediaExtractor extractor = new MediaExtractor();
    extractor.setDataSource(input);

    logout("start demuxer: " + input);

    MediaFormat videoFormat = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, 1280, 720);

    extractor.selectTrack(0);

// if (muxer == null) {
// logout("no video found !");
// return false;
// }

    BufferInfo info = new BufferInfo();
    info.presentationTimeUs = 0;
    ByteBuffer buffer = ByteBuffer.allocate(1024 * 1024 * 2);

    int i = - 1;
    while (true) {
        i++;
        int sampleSize = extractor.readSampleData(buffer, 0);
        if (sampleSize < 0) {
            logout("read sample data failed , break !");
            break;
        }
        if (i == 0 ){
            byte[] sps_header = new byte[sampleSize];
            for (int j = 0;j < sampleSize;j++){
                sps_header[j] = buffer.array()[sampleSize];
            }

            //SPS
            videoFormat.setByteBuffer("csd-0", ByteBuffer.wrap(sps_header));
            extractor.advance();
            continue;
        }else if (i == 1){
            //PPS
            byte[] pps_header = new byte[sampleSize];
            for (int j = 0; j < sampleSize; j++){
                pps_header[j] = buffer.array()[sampleSize];
            }
            videoFormat.setByteBuffer("csd-1",ByteBuffer.wrap(pps_header));
            videoFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar);
            videoFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 1920 * 1080);
            videoFormat.setInteger(MediaFormat.KEY_CAPTURE_RATE, 25);

            muxer = new MediaMuxer(output,OutputFormat.MUXER_OUTPUT_MPEG_4);
            muxer.addTrack(videoFormat);
            muxer.start();
            continue;
        }

        Log.d("xiaxingyu","i = " + i);
        info.offset = 0;
        info.size = sampleSize;
        info.flags = extractor.getSampleFlags();
        info.presentationTimeUs = extractor.getSampleTime();
        boolean keyframe = (info.flags & MediaCodec.BUFFER_FLAG_SYNC_FRAME) > 0;
        logout("write sample " + keyframe + ", " + sampleSize + ", " + info.presentationTimeUs);
        muxer.writeSampleData(0, buffer, info);
        extractor.advance();
    }

    extractor.release();

    muxer.stop();
    muxer.release();

    logout("process success !");

    return true;
}

private void logout(final String content) {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            Log.i("MediaDemo", content);
            mLogView.setText(mLogView.getText() + "\n" + content);
        }
    });
}

}

要先调用readSampleData方法