2016年12月9日工作总结(JNI问题,AudioTrack之回调,FFmpeg之Seek)

1.这个是今天定位系统Selector.select(long timeout)和select()一样,除了最长会阻塞timeout毫秒(参数)。 没有用处,顾用sleep来替换
Java NIO 系列教程

2.在解码的时候没有调用 avcodec_flush_buffers(pFormatCtx->streams[videoStream]->codec); 导致seek播放的问题
FFmpeg av_seek_frame()参数以及使用

3.java的long类型对应jni层的jlong相当于c++层的longlong 所以需要强转。

C++

virtual void onSeekCompleteListener(
            long seekTime)
    {
        FFMPEG_LOGD("callback::jni::::onSeekCompleteListener::start");
        if (m_jobjDecoder == NULL)
        {
            return;
        }
        if (NULL == s_mthdDecoder_onSeekCompleteListener)
        {
            jclass clazz = m_envStart->GetObjectClass(m_jobjDecoder);
            s_mthdDecoder_onSeekCompleteListener = m_envStart->GetMethodID(clazz, "onSeekCompleteListener", "(J)V");
            FFMPEG_LOGD("callback::jni::::onSeekCompleteListener::%p\n",s_mthdDecoder_onSeekCompleteListener);
            m_envStart->DeleteLocalRef(clazz);
        }
        if (s_mthdDecoder_onSeekCompleteListener != NULL)
        {
            FFMPEG_LOGD("callback::jni::::onSeekCompleteListener::%ld\n",seekTime);
            m_envStart->CallVoidMethod(m_jobjDecoder, s_mthdDecoder_onSeekCompleteListener, (jlong)seekTime);
        }
        else
        {
            FFMPEG_LOGD("callback::jni::::onSeekCompleteListener");
        }
        FFMPEG_LOGD("callback::jni::::onSeekCompleteListener::end");

    }

java

@Override
            public void onSeekCompleteListener(long seekTime) {
                LogUtil.logd("callback:jni::onSeekCompleteListener" + sessionID + "/" + seekTime);
//                ToastUtils.showShortOnUI("拖动完成");
                if (mAudioTrack != null) {
                    mAudioTrack.setPlaybackPositionUpdateListener(new ProgressListener(), mFreeHandler);
                    mAudioTrack.setPositionNotificationPeriod(sampleRateInHz);
                }
                if (mTrackSession != null) {
                    mTrackSession.playedTime = seekTime;
                }
                if (null != mOnStateListener) {
                    mOnStateListener.onSeekCompleteListener();
                }
            }

4.JNIEnv线程相关
JNI 实战全面解析
**JNIEnv与JavaVM
JNIEnv 概念 : 是1个线程相干的结构体, 该结构体代表了 Java 在本线程的运行环境 ;
JNIEnv 与 JavaVM : 注意辨别这两个概念;
– JavaVM : JavaVM 是 Java虚拟机在 JNI 层的代表, JNI 全局只有1个;
– JNIEnv : JavaVM 在线程中的代表, 每一个线程都有1个, JNI 中可能有很多个 JNIEnv;
JNIEnv 作用 :
– 调用 Java 函数 : JNIEnv 代表 Java 运行环境, 可使用 JNIEnv 调用 Java 中的代码;
– 操作 Java 对象 : Java 对象传入 JNI 层就是 Jobject 对象, 需要使用 JNIEnv 来操作这个 Java 对象;**

5.发现AudioTrack在我flush的时候就不能回调播放进度了。重新设值就可以,因为flush的时候会将回调清空。
audiotrack的Marker/PeriodPosition/flush流程(mode_stream)

6.JNI对于c和c++语法不同
C 语法:jsize len = (*env)->GetArrayLength(env,array);
C++ 语法:jsize len =env->GetArrayLength(array);
C和C++函数时的JNI使用区别

7.JNI创建引用
JNI学习笔记——局部和全局引用

注意和上面的JNI代码一起看。一个是声明的位置,一个是调用的位置

public:
    TXZFFMpegCodec_WithPipe_Jni(JNIEnv* env,jobject obj) :m_envCreate(env),m_envStart(NULL)
    {
        //这里使用m_jobjDecoder =obj的方式有问题
        m_jobjDecoder = env->NewGlobalRef(obj);
    }

    virtual ~TXZFFMpegCodec_WithPipe_Jni()
    {

    }

猜你喜欢

转载自blog.csdn.net/telenewbie/article/details/53543383