
我执行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 的实现所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)