android – Java.lang.UnsatisfiedLinkError:找不到int 的实现

android – Java.lang.UnsatisfiedLinkError:找不到int 的实现,第1张

概述参见英文答案 > Android NDK C++ JNI (no implementation found for native…)                                    11个 我执行youtube看我的android应用程序项目.我只是在我的项目中添加一些类并使用ndk构建.我得到了错误 java.lang.UnsatisfiedLinkError: No im 参见英文答案 > Android NDK C++ JNI (no implementation found for native…)                                    11个
我执行youtube看我的androID应用程序项目.我只是在我的项目中添加一些类并使用ndk构建.我得到了错误

java.lang.UnsatisfIEdlinkError: No implementation found for int com.ephronsystem.mobilizerapp.Ffmpeg.encodeVIDeoFrame(byte[]) (trIEd Java_com_ephronsystem_mobilizerapp_Ffmpeg_encodeVIDeoFrame and Java_com_ephronsystem_mobilizerapp_Ffmpeg_encodeVIDeoFrame___3B).

我的代码:

package com.ephronsystem.mobilizerapp;public class Ffmpeg {     static {        System.loadlibrary("ffmpeg");    }    public static native boolean init(int wIDth,int height,int audio_sample_rate,String rtmpurl);    public static native voID shutdown();    // Returns the size of the encoded frame.    public static native int encodeVIDeoFrame(byte[] yuv_image);    public static native int encodeAudioFrame(short[] audio_data,int length);}

这是ffmpeg-jni.c

#include <androID/log.h>#include <string.h>#include <jni.h>#include "libavcodec/avcodec.h"#include "libavformat/avformat.h"#include "libavutil/opt.h"#ifdef __cplusplusextern "C" {#endifJNIEXPORT jboolean JNICALL Java_com_ephronsystem_mobilizerapp_Ffmpeg_init(jnienv *env,jobject thiz,jint wIDth,jint height,jint audio_sample_rate,Jstring rtmp_url);JNIEXPORT voID JNICALL Java_com_ephronsystem_mobilizerapp_Ffmpeg_shutdown(jnienv *env,jobject thiz);JNIEXPORT jint JNICALL Java_com_ephronsystem_mobilizerapp_Ffmpeg_encodeVIDeoFrame(jnienv*env,jbyteArrayyuv_image);JNIEXPORT jint JNICALL Java_com_ephronsystem_mobilizerapp_Ffmpeg_encodeAudioFrame(jnienv *env,JshortArray audio_data,jint length);#ifdef __cplusplus}#endif#define LOGI(...) __androID_log_print(ANDROID_LOG_INFO,"ffmpeg-jni",__VA_ARGS__)#define URL_WRONLY 2        static AVFormatContext *fmt_context;        static AVStream *vIDeo_stream;        static AVStream *audio_stream;        static int pts= 0;static int last_audio_pts = 0;// Buffers for UV format conversionstatic unsigned char *u_buf;static unsigned char *v_buf;static int enable_audio = 1;static int64_t audio_samples_written = 0;static int audio_sample_rate = 0;// StupID buffer for audio samples. Not even a proper ring buffer#define AUdio_MAX_BUF_SIZE 16384  // 2x what we get from Javastatic short audio_buf[AUdio_MAX_BUF_SIZE];static int audio_buf_size = 0;voID AudioBuffer_Push(const short *audio,int num_samples) {    if (audio_buf_size >= AUdio_MAX_BUF_SIZE - num_samples) {        LOGI("AUdio BUFFER OVERFLOW: %i + %i > %i",audio_buf_size,num_samples,AUdio_MAX_BUF_SIZE);        return;    }    for (int i = 0; i < num_samples; i++) {        audio_buf[audio_buf_size++] = audio[i];    }}int AudioBuffer_Size() { return audio_buf_size; }short *AudioBuffer_Get() { return audio_buf; }voID AudioBuffer_Pop(int num_samples) {    if (num_samples > audio_buf_size) {        LOGI("Audio buffer Pop WTF: %i vs %i",audio_buf_size);        return;    }    memmove(audio_buf,audio_buf + num_samples,num_samples * sizeof(short));    audio_buf_size -= num_samples;}voID AudioBuffer_Clear() {    memset(audio_buf,sizeof(audio_buf));    audio_buf_size = 0;}static voID log_callback(voID *ptr,int level,const char *fmt,va_List vl) {    char x[2048];    vsnprintf(x,2048,fmt,vl);    LOGI(x);}JNIEXPORT jboolean JNICALL Java_com_ephronsystem_mobilizerapp_Ffmpeg_init(jnienv *env,jint audio_sample_rate_param,Jstring rtmp_url) {    avcodec_register_all();    av_register_all();    av_log_set_callback(log_callback);    fmt_context = avformat_alloc_context();    AVOutputFormat *ofmt = av_guess_format("flv",NulL,NulL);    if (ofmt) {        LOGI("av_guess_format returned %s",ofmt->long_name);    } else {        LOGI("av_guess_format fail");        return JNI_FALSE;    }    fmt_context->oformat = ofmt;    LOGI("creating vIDeo stream");    vIDeo_stream = av_new_stream(fmt_context,0);    if (enable_audio) {        LOGI("creating audio stream");        audio_stream = av_new_stream(fmt_context,1);    }    // Open VIDeo Codec.    // ======================    AVCodec *vIDeo_codec = avcodec_find_encoder(AV_CODEC_ID_H264);    if (!vIDeo_codec) {        LOGI("DID not find the vIDeo codec");        return JNI_FALSE;  // leak!    } else {        LOGI("VIDeo codec found!");    }    AVCodecContext *vIDeo_codec_ctx = vIDeo_stream->codec;    vIDeo_codec_ctx->codec_ID = vIDeo_codec->ID;    vIDeo_codec_ctx->codec_type = AVMEDIA_TYPE_VIDEO;    vIDeo_codec_ctx->level = 31;    vIDeo_codec_ctx->wIDth = wIDth;    vIDeo_codec_ctx->height = height;    vIDeo_codec_ctx->pix_fmt = PIX_FMT_YUV420P;    vIDeo_codec_ctx->rc_max_rate = 0;    vIDeo_codec_ctx->rc_buffer_size = 0;    vIDeo_codec_ctx->gop_size = 12;    vIDeo_codec_ctx->max_b_frames = 0;    vIDeo_codec_ctx->slices = 8;    vIDeo_codec_ctx->b_frame_strategy = 1;    vIDeo_codec_ctx->coder_type = 0;    vIDeo_codec_ctx->me_cmp = 1;    vIDeo_codec_ctx->me_range = 16;    vIDeo_codec_ctx->qmin = 10;    vIDeo_codec_ctx->qmax = 51;    vIDeo_codec_ctx->keyint_min = 25;    vIDeo_codec_ctx->refs = 3;    vIDeo_codec_ctx->trellis = 0;    vIDeo_codec_ctx->scenechange_threshold = 40;    vIDeo_codec_ctx->flags |= CODEC_FLAG_LOOP_FILTER;    vIDeo_codec_ctx->me_method = ME_HEX;    vIDeo_codec_ctx->me_subpel_quality = 6;    vIDeo_codec_ctx->i_quant_factor = 0.71;    vIDeo_codec_ctx->qcompress = 0.6;    vIDeo_codec_ctx->max_qdiff = 4;    vIDeo_codec_ctx->time_base.den = 10;    vIDeo_codec_ctx->time_base.num = 1;    vIDeo_codec_ctx->bit_rate = 3200 * 1000;    vIDeo_codec_ctx->bit_rate_tolerance = 0;    vIDeo_codec_ctx->flags2 |= 0x00000100;    fmt_context->bit_rate = 4000 * 1000;    av_opt_set(vIDeo_codec_ctx,"partitions","i8x8,i4x4,p8x8,b8x8",0);    av_opt_set_int(vIDeo_codec_ctx,"direct-pred",1,"rc-lookahead","fast-pskip","mixed-refs","8x8dct","weightb",0);    if (fmt_context->oformat->flags & AVFMT_GLOBALheader)        vIDeo_codec_ctx->flags |= CODEC_FLAG_GLOBAL_header;    LOGI("opening vIDeo codec");    AVDictionary *vopts = NulL;    av_dict_set(&vopts,"profile","main",0);    //av_dict_set(&vopts,"vprofile",0);    av_dict_set(&vopts,"tune","film","preset","ultrafast",0);    av_opt_set(vIDeo_codec_ctx->priv_data,0);    int open_res = avcodec_open2(vIDeo_codec_ctx,vIDeo_codec,&vopts);    if (open_res < 0) {        LOGI("Error opening vIDeo codec: %i",open_res);        return JNI_FALSE;   // leak!    }    // Open Audio Codec.    // ======================    if (enable_audio) {        AudioBuffer_Clear();        audio_sample_rate = audio_sample_rate_param;        AVCodec *audio_codec = avcodec_find_encoder(AV_CODEC_ID_AAC);        if (!audio_codec) {            LOGI("DID not find the audio codec");            return JNI_FALSE;  // leak!        } else {            LOGI("Audio codec found!");        }        AVCodecContext *audio_codec_ctx = audio_stream->codec;        audio_codec_ctx->codec_ID = audio_codec->ID;        audio_codec_ctx->codec_type = AVMEDIA_TYPE_AUdio;        audio_codec_ctx->bit_rate = 128000;        audio_codec_ctx->bit_rate_tolerance = 16000;        audio_codec_ctx->channels = 1;        audio_codec_ctx->profile = FF_PROfile_AAC_LOW;        audio_codec_ctx->sample_fmt = AV_SAMPLE_FMT_FLT;        audio_codec_ctx->sample_rate = 44100;        LOGI("opening audio codec");        AVDictionary *opts = NulL;        av_dict_set(&opts,"strict","experimental",0);        open_res = avcodec_open2(audio_codec_ctx,audio_codec,&opts);        LOGI("audio frame size: %i",audio_codec_ctx->frame_size);        if (open_res < 0) {            LOGI("Error opening audio codec: %i",open_res);            return JNI_FALSE;   // leak!        }    }    const jbyte *url = (*env)->GetStringUTFChars(env,rtmp_url,NulL);    // Point to an output file    if (!(ofmt->flags & AVFMT_NOfile)) {        if (avio_open(&fmt_context->pb,url,URL_WRONLY) < 0) {            LOGI("ERROR: Could not open file %s",url);            return JNI_FALSE;  // leak!        }    }    (*env)->ReleaseStringUTFChars(env,url);    LOGI("Writing output header.");    // Write file header    if (avformat_write_header(fmt_context,NulL) != 0) {        LOGI("ERROR: av_write_header Failed");        return JNI_FALSE;    }    pts = 0;    last_audio_pts = 0;    audio_samples_written = 0;    // Initialize buffers for UV format conversion    int frame_size = vIDeo_codec_ctx->wIDth * vIDeo_codec_ctx->height;    u_buf = (unsigned char *) av_malloc(frame_size / 4);    v_buf = (unsigned char *) av_malloc(frame_size / 4);    LOGI("ffmpeg enCoding init done");    return JNI_TRUE;}JNIEXPORT voID JNICALL Java_com_ephronsystem_mobilizerapp_Ffmpeg_shutdown(jnienv*env,jobject thiz) {av_write_trailer(fmt_context);avio_close(fmt_context->pb);avcodec_close(vIDeo_stream->codec);if (enable_audio) {avcodec_close(audio_stream->codec);}av_free(fmt_context);av_free(u_buf);av_free(v_buf);fmt_context = NulL;u_buf = NulL;v_buf = NulL;}JNIEXPORT jint JNICALL Java_com_ephronsystem_mobilizerapp_Ffmpeg_encodeVIDeoFrame(jnienv*env,jbyteArrayyuv_image) {int yuv_length = (*env)->GetArrayLength(env,yuv_image);unsigned char *yuv_data = (*env)->GetByteArrayElements(env,yuv_image,0);AVCodecContext *vIDeo_codec_ctx = vIDeo_stream->codec;//LOGI("Yuv size: %i w: %i h: %i",yuv_length,vIDeo_codec_ctx->wIDth,vIDeo_codec_ctx->height);int frame_size = vIDeo_codec_ctx->wIDth * vIDeo_codec_ctx->height;const unsigned char *uv = yuv_data + frame_size;// Convert YUV from NV12 to I420. Y channel is the same so we don't touch it,// we just have to deinterleave UV.for (int i = 0;i < frame_size / 4; i++) {v_buf[i] = uv[i * 2];u_buf[i] = uv[i * 2 + 1];}AVFrame source;memset(&source,sizeof(AVFrame));source.data[0] =yuv_data;source.data[1] =u_buf;source.data[2] =v_buf;source.linesize[0] = vIDeo_codec_ctx->wIDth;source.linesize[1] = vIDeo_codec_ctx->wIDth / 2;source.linesize[2] = vIDeo_codec_ctx->wIDth / 2;// only for bitrate regulation. irrelevant for sync.source.pts = pts;pts++;int out_length = frame_size + (frame_size / 2);unsigned char *out = (unsigned char *) av_malloc(out_length);int compressed_length = avcodec_encode_vIDeo(vIDeo_codec_ctx,out,out_length,&source);(*env)->ReleaseByteArrayElements(env,yuv_data,0);// Write to file tooif (compressed_length > 0) {AVPacket pkt;av_init_packet(&pkt);pkt.pts = last_audio_pts;if (vIDeo_codec_ctx->coded_frame && vIDeo_codec_ctx->coded_frame->key_frame) {pkt.flags |= 0x0001;}pkt.stream_index = vIDeo_stream->index;pkt.data = out;pkt.size = compressed_length;if (av_interleaved_write_frame(fmt_context,&pkt) != 0) {LOGI("Error writing vIDeo frame");}} else {LOGI("??? compressed_length <= 0");}last_audio_pts++;av_free(out);returncompressed_length;}JNIEXPORT jint JNICALL Java_com_ephronsystem_mobilizerapp_Ffmpeg_encodeAudioFrame(jnienv*env,JshortArrayaudio_data,jint length) {if (!enable_audio) {return 0;}short *audio = (*env)->GetShortArrayElements(env,audio_data,0);//LOGI("java audio buffer size: %i",length);AVCodecContext *audio_codec_ctx = audio_stream->codec;unsigned char *out = av_malloc(128000);AudioBuffer_Push(audio,length);int total_compressed = 0;while (AudioBuffer_Size()>= audio_codec_ctx->frame_size) {AVPacket pkt;av_init_packet(&pkt);int compressed_length = avcodec_encode_audio(audio_codec_ctx,128000,AudioBuffer_Get());total_compressed +=compressed_length;audio_samples_written += audio_codec_ctx->frame_size;int new_pts = (audio_samples_written * 1000) / audio_sample_rate;if (compressed_length > 0) {pkt.size = compressed_length;pkt.pts = new_pts;last_audio_pts = new_pts;//LOGI("audio_samples_written: %i  comp_length: %i   pts: %i",(int)audio_samples_written,(int)compressed_length,(int)new_pts);pkt.flags |= 0x0001;pkt.stream_index = audio_stream->index;pkt.data = out;if (av_interleaved_write_frame(fmt_context,&pkt) != 0) {LOGI("Error writing audio frame");}}AudioBuffer_Pop(audio_codec_ctx->frame_size);}(*env)->ReleaseShortArrayElements(env,audio,0);av_free(out);returntotal_compressed;}
解决方法 当JVM在执行期间找不到您的本机库时,通常会发生此错误.您的本机代码必须编译为.so文件,并在运行时使其可用于JVM.

您可以在java.library.path和链接here上找到更多详细信息

总结

以上是内存溢出为你收集整理的android – Java.lang.UnsatisfiedLinkError:找不到int 的实现全部内容,希望文章能够帮你解决android – Java.lang.UnsatisfiedLinkError:找不到int 的实现所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1123968.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-30
下一篇2022-05-30

发表评论

登录后才能评论

评论列表(0条)

    保存