私たちは、Androidプラットフォーム上でビデオフレーム抽出のためにFFMPEG
ライブラリを消費するプロジェクトに取り組んでいます。 WindowsではAndroidでFFMPEG APIを使用して30fpsでフレームを抽出するにはどうすればよいですか?
、我々が観察した:
- のCLIを使用して、ffmpegのコマンド
ffmpeg -i input.flv -vf fps=1 out%d.png
を使用して30 fpsでフレームを抽出することができます。 - Xugglerを使用して、30fpsでフレームを抽出することができます。
- コードでFFMPEG APIを直接使用すると、30fpsでフレームが取得されます。
しかし、我々は、Android(See Hardware Details)、我々は次のような結果になっている上で直接FFMPEGのAPIを使用する場合:
- 720pの映像(1280×720) - 16のFPSを(約60ミリ秒/フレーム)
- 1080pの映像(1920×1080) - 7つのFPS(約140ミリ秒/フレーム)
は、我々はまだAndroid上でXuggler/CLIをテストしていません。
理想的には、一定の時間(約30ms /フレーム)でデータを取得できるはずです。
Androidで30fpsを取得するにはどうすればよいですか? Android上で使用されている
コード:
if (avformat_open_input(&pFormatCtx, pcVideoFile, NULL, NULL)) {
iError = -1; //Couldn't open file
}
if (!iError) {
//Retrieve stream information
if (avformat_find_stream_info(pFormatCtx, NULL) < 0)
iError = -2; //Couldn't find stream information
}
//Find the first video stream
if (!iError) {
for (i = 0; i < pFormatCtx->nb_streams; i++) {
if (AVMEDIA_TYPE_VIDEO
== pFormatCtx->streams[i]->codec->codec_type) {
iFramesInVideo = pFormatCtx->streams[i]->nb_index_entries;
duration = pFormatCtx->streams[i]->duration;
begin = pFormatCtx->streams[i]->start_time;
time_base = (pFormatCtx->streams[i]->time_base.num * 1.0f)
/pFormatCtx->streams[i]->time_base.den;
pCodecCtx = avcodec_alloc_context3(NULL);
if (!pCodecCtx) {
iError = -6;
break;
}
AVCodecParameters params = { 0 };
iReturn = avcodec_parameters_from_context(¶ms,
pFormatCtx->streams[i]->codec);
if (iReturn < 0) {
iError = -7;
break;
}
iReturn = avcodec_parameters_to_context(pCodecCtx, ¶ms);
if (iReturn < 0) {
iError = -7;
break;
}
//pCodecCtx = pFormatCtx->streams[i]->codec;
iVideoStreamIndex = i;
break;
}
}
}
if (!iError) {
if (iVideoStreamIndex == -1) {
iError = -3; // Didn't find a video stream
}
}
if (!iError) {
// Find the decoder for the video stream
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
if (pCodec == NULL) {
iError = -4;
}
}
if (!iError) {
// Open codec
if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
iError = -5;
}
if (!iError) {
iNumBytes = av_image_get_buffer_size(AV_PIX_FMT_RGB24, pCodecCtx->width,
pCodecCtx->height, 1);
// initialize SWS context for software scaling
sws_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height,
pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height,
AV_PIX_FMT_RGB24,
SWS_BILINEAR,
NULL,
NULL,
NULL);
if (!sws_ctx) {
iError = -7;
}
}
clock_gettime(CLOCK_MONOTONIC_RAW, &end);
delta_us = (end.tv_sec - start.tv_sec) * 1000000
+ (end.tv_nsec - start.tv_nsec)/1000;
start = end;
//LOGI("Starting_Frame_Extraction: %lld", delta_us);
if (!iError) {
while (av_read_frame(pFormatCtx, &packet) == 0) {
// Is this a packet from the video stream?
if (packet.stream_index == iVideoStreamIndex) {
pFrame = av_frame_alloc();
if (NULL == pFrame) {
iError = -8;
break;
}
// Decode video frame
avcodec_decode_video2(pCodecCtx, pFrame, &iFrameFinished,
&packet);
if (iFrameFinished) {
//OUR CODE
}
av_frame_free(&pFrame);
pFrame = NULL;
}
av_packet_unref(&packet);
}
}
あなたが "30のFPS" とはどういう意味ですか?あなたがテストした 'ffmpeg'コマンドラインが与えられれば、それはよりよく理解されます。 – halfelf
30 fpsとは... 10秒のビデオに300フレームあり、コマンドラインで10秒間に300フレームをディスクに抽出して保存できるとします。 'ffmpeg -i -vf fps = 30 out%d.png' –
ダウン投票にはどのような理由がありますか? –