c - 如何在c中使用ffmpeg读取数据?
问题描述
我已经按照本教程进行操作:http : //dranger.com/ffmpeg/tutorial01.html 使用 android NDK 在 android studio 中使用 ffmpeg。我做了一些小的更正,因为这里使用的一些功能现在已经贬值了。这是我的代码,任何人都可以指出我的代码有什么问题,因为我遇到了错误并且无法找出问题所在
#include <jni.h>
#include <string.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>
void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame);
JNICALL
JNIEXPORT jstring
Java_com_viralsam_root_tester_MainActivity_trtest(JNIEnv *env, jobject obj , jint argc,
jstring argv_){
const char *name;
int i,videostream;
name= (*env)->GetStringUTFChars(env, argv_,0);
AVFormatContext *pFormatctx=NULL;
if (avformat_open_input(&pFormatctx,name,NULL,NULL)!=0){
return (*env)->NewStringUTF(env,"a");
}
if(pFormatctx==NULL){
return (*env)->NewStringUTF(env,"b");
}
if(avformat_find_stream_info(pFormatctx,NULL)<0){
return (*env)->NewStringUTF(env,"c");
}
av_dump_format(pFormatctx, 0, name, 0);
videostream=-1;
AVCodecContext *pCodecCtxOrig = NULL;
AVCodecContext *pCodecCtx = NULL;
for (i=0;i<pFormatctx->nb_streams;i++){
if((pFormatctx->streams[i]->codecpar->codec_type)==AVMEDIA_TYPE_VIDEO){
videostream=i;
break;
}
}
if(videostream==-1){
return (*env)->NewStringUTF(env,"d");
}
pCodecCtx=pFormatctx->streams[videostream]->codecpar;
AVCodec *pCodec = NULL;
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL){
return (*env)->NewStringUTF(env,"e");
}
pCodecCtx=avcodec_alloc_context3(pCodec);
if(avcodec_open2(pCodecCtx,pCodec,NULL)<0){
return (*env)->NewStringUTF(env,"g");
}
AVFrame *pFrame = NULL,*pFrameRBG=NULL;
pFrame=av_frame_alloc();
pFrameRBG=av_frame_alloc();
if(pFrameRBG==NULL){
return (*env)->NewStringUTF(env,"h");
}
uint8_t *buffer=NULL;
int numBytes;
numBytes=av_image_get_buffer_size(AV_PIX_FMT_RGB24,pCodecCtx->width,pCodecCtx->height,1);
buffer=(uint8_t *)av_malloc(numBytes* sizeof(uint8_t));
av_image_fill_arrays(pFrameRBG->data,pFrameRBG->linesize,buffer,AV_PIX_FMT_RGB24,pCodecCtx->width,pCodecCtx->height,1);
struct SwsContext *sws_ctx = NULL;
int frameFinished;
AVPacket *packet=av_packet_alloc();
sws_ctx=sws_getContext(pCodecCtx->width,pCodecCtx->height,pCodecCtx->pix_fmt,pCodecCtx->width,pCodecCtx->height,AV_PIX_FMT_RGB24,SWS_BILINEAR,NULL,NULL,NULL);
i=0;
while(av_read_frame(pFormatctx,&packet)>=0){
if(packet->stream_index==videostream){
int used=avcodec_send_packet(pCodecCtx,&packet);
used=avcodec_receive_frame(pCodecCtx,pFrame);
if (used < 0 && used != AVERROR(EAGAIN) && used != AVERROR_EOF){
break;
} else{
if (used == AVERROR(EAGAIN) || used == AVERROR_EOF){
break;
}
}
sws_scale(sws_ctx,(uint8_t const * const *)pFrame->data,pFrame->linesize,0,pCodecCtx->height,pFrameRBG->data,pFrameRBG->linesize);
if(++i<=5){
SaveFrame(pFrameRBG,pCodecCtx->width,pCodecCtx->height,i);
}
}
av_packet_free(&packet);
}
char blubuk[50];
sprintf(blubuk,"%d",buffer);
av_free(buffer);
av_frame_free(&pFrameRBG);
av_frame_free(&pFrame);
avcodec_close(pCodecCtx);
avcodec_close(pCodecCtxOrig);
avformat_close_input(&pFormatctx);
return (*env)->NewStringUTF(env,blubuk);
}
void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame){
FILE *pFile;
char szFilename[32];
int y;
sprintf(szFilename, "frame%d.ppm", iFrame);
pFile=fopen(szFilename,"wb");
if(pFile==NULL){
return;
}
fprintf(pFile, "P6\n%d %d\n255\n", width, height);
for(y=0; y<height; y++){
fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width*3, pFile);
}
fclose(pFile);
}
更新:我从“int used=avcodec_send_packet(pCodecCtx,packet);”得到“-22”。不知道我哪里出错了。
解决方案
推荐阅读
- amazon-web-services - 优化使用缓存生成和提供文件的 aws 托管应用程序
- python - pyinstaller 和 pandas(缺少多个挂钩)
- javascript - Angularjs - 将 blob 保存到无法处理动态数据的文本文件中
- camunda - 如何控制是否在 Camunda Tasklist 中显示流程实例变量?
- c# - 在列表中获取 JSON API 扩展
- javascript - es6扩展运算符不组合键控对象
- ios - 如何使用情节提要在 Tableview Cell 中为 2 个标签和一个图像视图设置约束?
- php - 复杂的数组比较
- python - 在 python 3.6 上安装 nltk 2.0.4 时出错
- java - 在进行 twilio 电话会议时收集用户的输入