0

Android用のffmpegを正常にコンパイルしました。mp4 ファイルを開くだけの簡単なアプリケーションを作成しました。

int main(int argc, char * argv[]) 
{
    av_register_all();

    __android_log_write(ANDROID_LOG_INFO, "NDK", "Opening file: /sdcard/test.mp4...");

    if (avformat_open_input(&pFormatCtx, "/sdcard/test.mp4", NULL, NULL) != 0) {
        __android_log_write(ANDROID_LOG_INFO, "NDK", "file not opened\n");
        return -1;
    }
    __android_log_write(ANDROID_LOG_INFO, "NDK", "file opened\n");
}

このコードを実行すると、C コードがここでクラッシュします。

06-06 18:22:42.629: I/DEBUG(31):          #00  pc 00159804  /data/data libffmpeg.so
06-06 18:22:42.629: I/DEBUG(31):          #01  lr 809465dc  /data/data libffmpeg.so

ndk スタック書き込み:

Stack frame #00  pc 00159804  /data/data/.../lib/libffmpeg.so: Routine av_opt_set_dict in libavutil/opt.c:552

av_opt_set_dict 関数は次のとおりです。

int av_opt_set_dict(void *obj, AVDictionary **options)
{
    AVDictionaryEntry *t = NULL;
    AVDictionary    *tmp = NULL;
    int ret = 0;

    while ((t = av_dict_get(*options, "", t, AV_DICT_IGNORE_SUFFIX))) {
        ret = av_set_string3(obj, t->key, t->value, 1, NULL);
        if (ret == AVERROR_OPTION_NOT_FOUND)
            av_dict_set(&tmp, t->key, t->value, 0);
        else if (ret < 0) {
            av_log(obj, AV_LOG_ERROR, "Error setting option %s to value %s.\n", t->key, t->value);
            break;
        }
        ret = 0;
    }
    av_dict_free(options);
    *options = tmp;
    return ret;
}

552行は次のとおりです。

while ((t = av_dict_get(*options, "", t, AV_DICT_IGNORE_SUFFIX))) {

このコードは私のLinuxマシンで動作します(もちろん、Linuxの場合は.so、Androidの場合はndkビルドの.soファイルを使用します)が、Androidの下では機能しません。

また、ルート化された HTC Desire Z では動作しますが、エミュレーターやルート化されていないデバイスでは動作しません。

ここで、libavformat/file.c file_check 関数を変更する必要があるという投稿を見つけました。

static int file_check(URLContext *h, int mask)
{
    struct stat st;
    int ret = stat(h->filename, &st);
    if (ret < 0)
        return AVERROR(errno);

    ret |= st.st_mode&S_IRUSR ? mask&AVIO_FLAG_READ  : 0;
    ret |= st.st_mode&S_IWUSR ? mask&AVIO_FLAG_WRITE : 0;

    return ret;
}

static int file_check(URLContext *h, int mask)
{
    struct stat st;
    int ret = stat(h->filename, &st);
    if (ret < 0)
        return AVERROR(errno);

    ret |= st.st_mode&S_IRUSR ? mask&AVIO_FLAG_READ  : 0;
    ret |= st.st_mode&S_IRGRP ? mask&AVIO_FLAG_READ  : 0;
    ret |= st.st_mode&S_IROTH ? mask&AVIO_FLAG_READ  : 0;
    ret |= st.st_mode&S_IWUSR ? mask&AVIO_FLAG_WRITE : 0;
    ret |= st.st_mode&S_IWGRP ? mask&AVIO_FLAG_WRITE  : 0;
    ret |= st.st_mode&S_IWOTH ? mask&AVIO_FLAG_WRITE  : 0;


    return ret;
}

しかし、それは助けにはなりませんでした。

助言がありますか?

ありがとう

4

0 に答える 0