Runt
2025-04-04 49be01c8fd58a15b16012dc528673343ff7d73b9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
//
// Created by 倪路朋 on 11/28/24.
//
 
#include <string.h>
#include "media_encoder_call.h"
#include <thread>
 
MediaEncoderCall::MediaEncoderCall(JNIEnv *env_, jobject instance_) {
//    this->instance = instance_;//不能直接赋值!
    //一旦涉及到 jobject 跨方法、跨线程,需要创建全局引用
    this->instance = env_->NewGlobalRef(instance_);
    init(env_);
 
}
 
MediaEncoderCall::~MediaEncoderCall() {
    javaVM = 0 ;
    env->DeleteGlobalRef(instance);
    instance = 0 ;
}
 
void MediaEncoderCall::init(JNIEnv *env_) {
    env_->GetJavaVM(&this->javaVM);
    LOGE("javaVM_ %s",&this->javaVM);
    this->env = env_;
    jclass clazz = env->GetObjectClass(instance);
    jmd_encode_yuv = env->GetMethodID(clazz,"encodeYUV","([B)V");
    jmd_encode_pcm = env->GetMethodID(clazz,"encodePCM","([B)V");
    jmd_get_sps_pps = env->GetMethodID(clazz,"getSpsPpsData","()[B");
    jmd_get_audio_seq = env->GetMethodID(clazz,"getAudioSeqData","()[B");
}
 
void MediaEncoderCall::encodeYUV(uint8_t* yuvBuffer, int width, int height) {
 
    //LOGE("VideoEncoderCall encode" );
    int size = width * height * 3 / 2;
 
    JNIEnv *env_child;
    javaVM->AttachCurrentThread(&env_child, 0);
    jbyteArray java_array = env_child->NewByteArray(size);
    env_child->SetByteArrayRegion(java_array, 0, size, (jbyte *)yuvBuffer);
    env_child->CallVoidMethod(instance, jmd_encode_yuv,java_array);
    env_child->DeleteLocalRef(java_array);
    javaVM->DetachCurrentThread();
    // 释放资源
    delete[] yuvBuffer;
}
void MediaEncoderCall::encodePCM(uint8_t* pcmBuffer, int width, int height) {
 
    //LOGE("VideoEncoderCall encode" );
    int size = width * height * 3 / 2;
 
    JNIEnv *env_child;
    javaVM->AttachCurrentThread(&env_child, 0);
    jbyteArray java_array = env_child->NewByteArray(size);
    env_child->SetByteArrayRegion(java_array, 0, size, (jbyte *)pcmBuffer);
    env_child->CallVoidMethod(instance, jmd_encode_pcm,java_array);
    env_child->DeleteLocalRef(java_array);
    javaVM->DetachCurrentThread();
    // 释放资源
    delete[] pcmBuffer;
}
 
void MediaEncoderCall::getSpsPps(uint8_t **data,int *length){
    getJvmBytes(jmd_get_sps_pps,data,length);
}
 
void MediaEncoderCall::getAudioSeqData(uint8_t **data,int *length){
    getJvmBytes(jmd_get_audio_seq,data,length);
}
 
void MediaEncoderCall::getJvmBytes(jmethodID method,uint8_t **data,int *length){
    JNIEnv *env_child;
    javaVM->AttachCurrentThread(&env_child, 0);
    jbyteArray bytes = reinterpret_cast<jbyteArray> (env_child->CallObjectMethod(instance, method));
    if (!bytes) {
        LOGE("Java returned null byte array");
        return;
    }
    jsize javaLength = env_child->GetArrayLength(bytes);
    *length = static_cast<int>(javaLength);
    jbyte *byteData = env_child->GetByteArrayElements(bytes,NULL);
    *data = (uint8_t *)malloc(*length);
    // 获取 Java 数组的数据并拷贝
    env_child->GetByteArrayRegion(bytes, 0, *length, reinterpret_cast<jbyte *>(*data));
    env_child->ReleaseByteArrayElements(bytes,byteData,0);
    javaVM->DetachCurrentThread();
}