3

編集
実行を確認したところ、エラーが(まだ)swscaleポイントにないことがわかりました。私の現在の問題は、JPG 画像が見つからないことです。 何かを登録する必要があると言う前に、既に
No such file or directory 行っていることがわかります (以下のコードを更新しました)。 また、外部ストレージにアクセスするための Android 権限を追加しました (画像も配置されている /mnt/sdcard/ に既に書き込むことができるため、Android に関連しているとは思いません) END EDITavformat_open_input(&pFormatCtx, imageFileName, NULL, NULL);


私はいくつかのチュートリアルを行ってきました(SOから投稿されたいくつか、つまりhttp://dranger.com/ffmpeg/、Android用にffmpegをコンパイルする方法...、ドルフィンプレーヤーのソースコードを調べました)。ここに私が持っているものがあります:
. Android用にコンパイルされたffmpeg
。NDK を使用して基本的なチュートリアルを実行し、Android デバイスでダミー ビデオを作成しました
。上記のダミービデオコードの修正版と多くのグーグルを使用して、Ubuntuの画像からMPEG2ビデオを生成できました
。Android デバイスで新しいコードを実行すると、緑色の画面のビデオが表示されます (エンコードするフレーム数に関係なく、1 秒の長さ)

ARMプロセッサの最適化が原因である可能性があると述べた、同様の状況のiPhoneに関する別の投稿を見ました。いくつかの ldextra-flags (-arch armv7-a など) を試してみましたが、成功しませんでした。

画像をロードするコードを最後に含めます。Linux と Android で何か違うことはありますか? 私の ffmpeg ビルドは Android ビデオ エンコーディングに対して正しくありませんか?

void copyFrame(AVCodecContext *destContext, AVFrame* dest,
            AVCodecContext *srcContext, AVFrame* source) {
struct SwsContext *swsContext;
swsContext = sws_getContext(srcContext->width, srcContext->height, srcContext->pix_fmt,
                destContext->width, destContext->height, destContext->pix_fmt,
                SWS_FAST_BILINEAR, NULL, NULL, NULL);
sws_scale(swsContext, source->data, source->linesize, 0, srcContext->height, dest->data, dest->linesize);
sws_freeContext(swsContext);
}

int loadFromFile(const char* imageFileName, AVFrame* realPicture, AVCodecContext* videoContext) {
AVFormatContext *pFormatCtx = NULL;
avcodec_register_all();
av_register_all();

int ret = avformat_open_input(&pFormatCtx, imageFileName, NULL, NULL);
if (ret != 0) {
    // ERROR hapening here
    // Can't open image file. Use strerror(AVERROR(ret))) for details
    return ERR_CANNOT_OPEN_IMAGE;
}

AVCodecContext *pCodecCtx;

pCodecCtx = pFormatCtx->streams[0]->codec;
pCodecCtx->width = W_VIDEO;
pCodecCtx->height = H_VIDEO;
pCodecCtx->pix_fmt = PIX_FMT_YUV420P;

// Find the decoder for the video stream
AVCodec *pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (!pCodec) {
    // Codec not found
    return ERR_CODEC_NOT_FOUND;
}

// Open codec
if (avcodec_open(pCodecCtx, pCodec) < 0) {
    // Could not open codec
    return ERR_CANNOT_OPEN_CODEC;
}

// 
AVFrame *pFrame;

pFrame = avcodec_alloc_frame();

if (!pFrame) {
    // Can't allocate memory for AVFrame
    return ERR_CANNOT_ALLOC_MEM;
}

int frameFinished;
int numBytes;

// Determine required buffer size and allocate buffer
numBytes = avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
uint8_t *buffer = (uint8_t *) av_malloc(numBytes * sizeof (uint8_t));

avpicture_fill((AVPicture *) pFrame, buffer, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
AVPacket packet;
int res = 0;
while (av_read_frame(pFormatCtx, &packet) >= 0) {
    if (packet.stream_index != 0)
        continue;

    ret = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
    if (ret > 0) {
        // now, load the useful info into realPicture
        copyFrame(videoContext, realPicture, pCodecCtx, pFrame);
        // Free the packet that was allocated by av_read_frame
        av_free_packet(&packet);
        return 0;
    } else {
        // Error decoding frame. Use strerror(AVERROR(ret))) for details
        res = ERR_DECODE_FRAME;
    }
}
av_free(pFrame);

// close codec
avcodec_close(pCodecCtx);

// Close the image file
av_close_input_file(pFormatCtx);

return res;
}

いくつかの ./configure オプション:
--extra-cflags="-O3 -fpic -DANDROID -DHAVE_SYS_UIO_H=1 -Dipv6mr_interface=ipv6mr_ifindex -fasm -Wno-psabi -fno-short-enums -fno-strict-aliasing -finline-limit=300 -mfloat-abi=softfp -mfpu=vfp -marm -march=armv7-a -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE"

--extra-ldflags="-Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -nostdlib -lc -lm -ldl -llog"

--arch=armv7-a --enable-armv5te --enable-armv6 --enable-armvfp --enable-memalign-hack

4

2 に答える 2

1

github「android-ffmpeg」へのリンク...

https://github.com/halfninja/android-ffmpeg-x264

https://github.com/guardianproject/android-ffmpeg

https://github.com/rowntreerob/android-ffmpeg

単一の写真または写真のセットを使用して mpeg ファイルを作成するための CLI 手順...

http://ffmpeg.org/faq.html#How-do-I-encode-single-pictures-into-movies_003f

そのため、jpg 入力から mpeg / mp4 を出力する必要がある場合、libavcodec またはその他の場所ですべての詳細なメソッド呼び出しを行う必要があるほど複雑ではありません。

NDK とツールチェーンを使用して ffmpeg を android 実行可能ファイルにビルドし、ルート化された電話で CLI 式をテストし、それらが機能する場合は、実際の android アプリでラッパー lib を使用して、ガーディアンで説明されているように ffmpeg.main を呼び出すだけです。事業。

ffmpeg.main exit() の呼び出し方法をいじる必要がありますが、それは非常にマイナーな週です。

android-ffmpeg の CLI タイプの呼び出しに関して、SO には多くのスレッドがあります。

あなたが本当に低レベルのものを必要としない限り、アンドロイドの実装でそのコードに関与する利点はありません。

于 2012-10-18T03:15:37.397 に答える
0

上記のコードは実際に機能しています。他のデバイス (Samsung Galaxy Tab 7) で試してみましたが、問題ありません。この問題は、cyanomodgen または特定の Android バージョンが原因である可能性があります。

于 2012-10-31T01:50:04.200 に答える