RK3288 MediaCodec ndk 下解码错误 求助

解码H264 代码如下
AMediaCodec_queueInputBuffer 先是正确返回>=0 一两分钟后
后面就是返回-1,一直解码不成功

#include “DecodeOp.h”
#include <media/NdkMediaCodec.h>
//#include “CommonOp.h”
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <android/log.h>
#include <pthread.h>
#define LOG_TAG “C_MDA”
#define LOGD(…) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, VA_ARGS)

#define MIN(_a,_b) ((_a) > (_b) ? (_b) : (_a))

int DecodeOp::init(int width, int height)
{
const char *mine = “video/avc”;
mMediaCodec = AMediaCodec_createDecoderByType(mine);
//注意这里,如果系统不存在对应的mine,mMediaCodec也会返回对象,
//不过之后涉及到mMediaCodec的任何函数都会直接导致程序崩掉。
if (NULL == mMediaCodec)
{
return 0;
}

AMediaFormat *videoFormat = AMediaFormat_new();
AMediaFormat_setString(videoFormat, "mime", "video/avc");
AMediaFormat_setInt32(videoFormat, AMEDIAFORMAT_KEY_WIDTH, width);
AMediaFormat_setInt32(videoFormat, AMEDIAFORMAT_KEY_HEIGHT, height);
media_status_t status = AMediaCodec_configure(mMediaCodec, videoFormat, NULL, NULL, 0);
if (status != AMEDIA_OK)
{
    AMediaCodec_delete(mMediaCodec);
    mMediaCodec = NULL;
    return 0;
}

mWidth = width;
mHeight = height;

mFramecnt=0;
status = AMediaCodec_start(mMediaCodec);
if (status != AMEDIA_OK)
{
    AMediaCodec_delete(mMediaCodec);
    mMediaCodec = NULL;
    return 0;
}

return 1;

}

int DecodeOp::fini()
{
AMediaCodec_stop(mMediaCodec);
AMediaCodec_delete(mMediaCodec);
mMediaCodec = NULL;
return 1;
}

int DecodeOp::decode(char *bufData, int bufSize, char *outBuf,pthread_mutex_t mutex) {
if (NULL == mMediaCodec)
return 0;
ssize_t bufidx = AMediaCodec_dequeueInputBuffer(mMediaCodec, 10000); //-1);
if (bufidx >= 0) {
// 获取buffer的索引
size_t outsize;
uint8_t inputBuf = AMediaCodec_getInputBuffer(mMediaCodec, bufidx, &outsize);
if (inputBuf != nullptr && bufSize <= outsize) {
// 将待解码的数据copy到硬件中
memcpy(inputBuf, bufData, bufSize);
media_status_t status = AMediaCodec_queueInputBuffer(mMediaCodec, bufidx, 0, bufSize,5
mFramecnt++ /
pts */, 0);
}
//LOGD(“ie:%lld”,mFramecnt);
}else
{
LOGD(“ib:%d”,bufidx);
AMediaCodec_flush(mMediaCodec);
AMediaCodec_start(mMediaCodec);
}

int ret=0;
AMediaCodecBufferInfo info;
ssize_t outbufidx = AMediaCodec_dequeueOutputBuffer(mMediaCodec, &info, 0);
//LOGD("ob:%d",outbufidx);
if (outbufidx >= 0) {
    size_t outsize;
    uint8_t *outputBuf = AMediaCodec_getOutputBuffer(mMediaCodec, outbufidx, &outsize);
    LOGD("obs:%d",outsize);
    if (outputBuf != nullptr) {
        ret= 1;
    }
    AMediaCodec_releaseOutputBuffer(mMediaCodec, outbufidx, false);
} else {
    switch (outbufidx) {
        case AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED:
            // 解码输出的格式发生变化
        {
            auto format = AMediaCodec_getOutputFormat(mMediaCodec);
            AMediaFormat_getInt32(format, "width", &mWidth);
            AMediaFormat_getInt32(format, "height", &mHeight);
            int32_t localColorFMT;
            AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_COLOR_FORMAT, &localColorFMT);
        }
        case AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED:
            break;
        default:
            break;
    }
}
return ret;

}

如果 java 模式下 调用 mediacodec 就能一直解码成功
java 调用 mediacodec 解码的代码如下
/**

  • Created by ZhangHao on 2016/8/5.

  • 用于硬件解码(MediaCodec)H264的工具类
    */
    public class MediaCodecUtil {
    //自定义的log打印,可以无视
    //Logger logger = Logger.getLogger();

    private String TAG = “MediaCodecUtil”;
    //解码后显示的surface及其宽高
    private SurfaceHolder holder;
    private int width, height;
    //解码器
    private MediaCodec mCodec;
    private MediaFormat mFormat;
    private boolean isFirst = true;
    // 需要解码的类型
    private final static String MIME_TYPE = “video/avc”; // H.264 Advanced Video
    private final static int TIME_INTERNAL = 5;

    /**

    • 初始化解码器
    • @param holder 用于显示视频的surface
    • @param width surface宽
    • @param height surface高
      */
      public MediaCodecUtil(SurfaceHolder holder, int width, int height) {
      // logger.d("MediaCodecUtil() called with: " + “holder = [” + holder + "], " +
      // “width = [” + width + “], height = [” + height + “]”);
      this.holder = holder;
      this.width = width;
      this.height = height;
      //mFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible);
      }

    public MediaCodecUtil(SurfaceHolder holder) {
    this(holder, holder.getSurfaceFrame().width(), holder.getSurfaceFrame().height());
    }

    public void startCodec() {
    if (isFirst) {
    //第一次打开则初始化解码器
    initDecoder();
    }
    }

    private void initDecoder() {
    try {
    //根据需要解码的类型创建解码器
    mCodec = MediaCodec.createDecoderByType(MIME_TYPE);
    } catch (IOException e) {
    e.printStackTrace();
    }
    //初始化MediaFormat
    MediaFormat mediaFormat = MediaFormat.createVideoFormat(MIME_TYPE,
    width, height);
    //配置MediaFormat以及需要显示的surface
    mCodec.configure(mediaFormat, holder.getSurface(), null, 0);
    //开始解码
    mCodec.start();
    isFirst = false;
    }

    int mCount = 0;
    public boolean onFrame(byte buf, int offset, int length) {
    // 获取输入buffer index
    ByteBuffer inputBuffers = mCodec.getInputBuffers();
    //-1表示一直等待;0表示不等待;其他大于0的参数表示等待毫秒数
    int inputBufferIndex = mCodec.dequeueInputBuffer(-1);
    if (inputBufferIndex >= 0) {
    ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
    //清空buffer
    inputBuffer.clear();
    //put需要解码的数据
    inputBuffer.put(buf, offset, length);
    //解码
    mCodec.queueInputBuffer(inputBufferIndex, 0, length, mCount * TIME_INTERNAL, 0);
    mCount++;
    } else {
    return false;
    }

    //mCodec.flush();
    
     // 获取输出buffer index
     MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
     int outputBufferIndex;
     do{
         outputBufferIndex = mCodec.dequeueOutputBuffer(bufferInfo, 0);
         if(outputBufferIndex<0) break;
         mCodec.releaseOutputBuffer(outputBufferIndex, true);
     }while(true);
    
     if (outputBufferIndex < 0) {
         //logger.e("outputBufferIndex = " + outputBufferIndex);
     }
    
     return true;
    

    }

    /**
    *停止解码,释放解码器
    */
    public void stopCodec() {

     try {
         mCodec.stop();
         mCodec.release();
         mCodec = null;
         isFirst = true;
     } catch (Exception e) {
         e.printStackTrace();
         mCodec = null;
     }
    

    }
    }