提问人:徐同鹏 提问时间:10/25/2023 更新时间:11/9/2023 访问量:19
FFMPEG avcodec_parameters_copy Android 上崩溃
ffmpeg avcodec_parameters_copy crash on android
问:
我是新手,我正在尝试用 Android ffmpeg 创建一个多路复用器应用程序,所以我通过 Ubuntu 编译 .so lib:
API=21
CPU=armv8-a
ARCH=arm64
PREFIX=$(pwd)/android/$CPU/$ARCH
TOOLCHAIN=/root/android-ndk-r21e/toolchains/llvm/prebuilt/linux-x86_64
CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android-
CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang
CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++
SYSROOT=$TOOLCHAIN/sysroot
OPTIMIZE_CFLAGS="-march=$CPU"
./configure \
--prefix=$PREFIX \
--arch=$ARCH \
--cpu=$CPU \
--cross-prefix=$CROSS_PREFIX \
--cc=$CC \
--cxx=$CXX \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fPIC $OPTIMIZE_CFLAGS" \
--target-os=android \
--enable-cross-compile \
--disable-gpl \
--enable-shared \
--disable-static \
--disable-programs \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-doc \
--disable-htmlpages \
--disable-manpages \
--disable-txtpages
我还得到了一些 MUXER 的 C++ 代码片段:
#include <jni.h>
#include <string>
#include <unistd.h>
#include <iostream>
#include <fstream>
#include <stdio.h>
using namespace std;
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/opt.h>
#include <libswresample/swresample.h>
}
//cout
#ifndef LOG_TAG
#define LOG_TAG "recite.debug"
#include <android/log.h>
#define debug(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#endif
//cout
string jstringToStdString(JNIEnv* env, jstring jstr) {
if (jstr == NULL) {
return "";
}
char* chars = (char*)env->GetStringUTFChars(jstr, NULL);
string ret(chars);
env->ReleaseStringUTFChars(jstr, chars);
return ret;
}
void FFMPEG_Callback(void* ptr, int level, const char* fmt, va_list vl)
{
//if(level != 32) return;
char buffer[1024];
vsprintf(buffer, fmt, vl);
debug("msg : [%d] %s", level, buffer);
}
//Java_com_example_recite_display_tabs_Setting_run
extern "C" JNIEXPORT int JNICALL
Java_com_example_recite_util_Bilibili_compose(JNIEnv * env, jclass obj, jstring audioSrc, jstring videoSrc, jstring dest)
{
int ret;
av_log_set_callback(&FFMPEG_Callback);
// const char* input_video_file_name = "payphone.mp4";
// const char* input_audio_file_name = "payphone.mp3";
// const char* output_file_name = "out.mp4";
const char* input_audio_file_name = (const char*)env->GetStringUTFChars(audioSrc, NULL);
const char* input_video_file_name = (const char*)env->GetStringUTFChars(videoSrc, NULL);
const char* output_file_name = (const char*)env->GetStringUTFChars(dest, NULL);
debug("video src: %s", input_video_file_name);
debug("audio src: %s", input_audio_file_name);
debug("dest src: %s", output_file_name);
AVFormatContext* ifmt_ctx_v = NULL, * ifmt_ctx_a = NULL;
AVFormatContext* ofmt_ctx = NULL;
int in_stream_index_v = -1;
int in_stream_index_a = -1;
int out_stream_index_v = -1;
int out_stream_index_a = -1;
debug("<--------------- input file info --------------->\n");
if ((ret = avformat_open_input(&ifmt_ctx_v, input_video_file_name, NULL, NULL)) < 0) {
debug("Cannot open input file\n");
return ret;
}
if ((ret = avformat_find_stream_info(ifmt_ctx_v, NULL)) < 0) {
debug("Cannot find stream information\n");
return ret;
}
ret = av_find_best_stream(ifmt_ctx_v, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
if (ret < 0) {
debug("Cannot find video stream\n");
return ret;
}
in_stream_index_v = ret;
av_dump_format(ifmt_ctx_v, 0, input_video_file_name, 0);
if ((ret = avformat_open_input(&ifmt_ctx_a, input_audio_file_name, NULL, NULL)) < 0) {
debug("Cannot open input file\n");
return ret;
}
if ((ret = avformat_find_stream_info(ifmt_ctx_a, NULL)) < 0) {
debug("Cannot find stream information\n");
return ret;
}
ret = av_find_best_stream(ifmt_ctx_a, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);
if (ret < 0) {
debug("Cannot find audio stream\n");
return ret;
}
in_stream_index_a = ret;
av_dump_format(ifmt_ctx_a, 0, input_audio_file_name, 0);
ret = avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, output_file_name);
if (ret < 0) {
debug("Cannot open output file\n");
return ret;
}
if (in_stream_index_v >= 0) {
AVStream* in_stream = ifmt_ctx_v->streams[in_stream_index_v];
AVStream* out_stream = avformat_new_stream(ofmt_ctx, NULL);
debug("\n<--------------- crash begin --------------->\n");
** //the code crashes here on android **
*** ret = avcodec_parameters_copy(out_stream->codecpar, in_stream->codecpar);***
debug("\n<--------------- crash end --------------->\n");
out_stream->codecpar->codec_tag = 0;
out_stream_index_v = out_stream->index;
}
// blah...blah...
我已经重建了两次.so lib,它不起作用。 谁能告诉我为什么代码在Linux(pc)上运行良好,但在Android上却崩溃了? 而且我真的不确定如何在 Android 中调试 C++ 代码......任何帮助将不胜感激,提前TKS!!
答:
0赞
徐同鹏
11/9/2023
#1
我意识到我错过了 cmakeList.txt 文件中 avdevice.so 库。所以,在我将其添加到编译中后,它工作得很好。
评论