第一次运行时,可以正常使用此函数,并完成音视频帧的获取,但关闭文件,再次打开后,运行到此函数,没有提示任何错误就奔溃了。
这里是打开的函数
unsigned char *ffmpegMp4_Openinputfile(char *in_filename,AVFormatContext *out_ifmt_ctx,int stream_v,int stream_a)
{
if(Readframe_ifmt_ctx != NULL){
printf("AVFormatContext need uninit!!!!\n\n");
return NULL;
}
int ret, i;
char buf[1024] = {0};
// av_register_all();
// avcodec_register_all();
//Input
if ((ret = avformat_open_input(&Readframe_ifmt_ctx, in_filename, 0, 0)) < 0) {
av_strerror(ret,buf,1024);
MLOGE(RED"avformat_open_input:%s %s\n",in_filename,buf);
return NULL;
}
MLOGD("\n");
if ((ret = avformat_find_stream_info(Readframe_ifmt_ctx, NULL)) < 0) {//在这里奔溃了
MLOGE( "Failed to retrieve input stream information");
av_strerror(ret,buf,1024);
MLOGE(RED"avformat_find_stream_info:%s\n",buf);
return NULL;
}
MLOGD("\n");
Readframe_videoindex=-1;
for(i=0; i<Readframe_ifmt_ctx->nb_streams; i++) {
if(Readframe_ifmt_ctx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){
Readframe_videoindex=i;
}else if(Readframe_ifmt_ctx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO){
Readframe_audioindex=i;
}
}
MLOGD("\n");
//Dump Format------------------
printf("\nInput Video===========================\n");
av_dump_format(Readframe_ifmt_ctx, 0, in_filename, 0);
printf("\n======================================\n");
#if USE_H264BSF
Readframe_h264bsfc = av_bitstream_filter_init("h264_mp4toannexb");
#endif
memcpy(out_ifmt_ctx,Readframe_ifmt_ctx,sizeof(AVFormatContext));
stream_v = Readframe_videoindex;
stream_a = Readframe_audioindex;
return Readframe_ifmt_ctx->filename;
}
这里是读取帧函数
int ffmpegMp4_Readframe(unsigned char *video_data,int *video_size,int *isKeyframe,unsigned long int *timestamp,unsigned char * audio_data,int *audio_size){
int ret;
if(Readframe_ifmt_ctx == NULL){
MLOGE("Mp4 had not open!\n");
return -1;
}
av_init_packet( &Readframe_pkt );
if(av_read_frame(Readframe_ifmt_ctx, &Readframe_pkt)>=0){
if(Readframe_pkt.stream_index==Readframe_videoindex){
*timestamp = Readframe_pkt.pts * av_q2d(Readframe_ifmt_ctx->streams[Readframe_pkt.stream_index]->time_base) * 1000;
#if USE_H264BSF
av_bitstream_filter_filter(Readframe_h264bsfc, Readframe_ifmt_ctx->streams[Readframe_videoindex]->codec, NULL, &Readframe_pkt.data, &Readframe_pkt.size, Readframe_pkt.data, Readframe_pkt.size, 0);
#endif
/*handle read video frame*/
memcpy(video_data,Readframe_pkt.data,Readframe_pkt.size);
*video_size = Readframe_pkt.size;
*isKeyframe = Readframe_pkt.flags;
}else if(Readframe_pkt.stream_index==Readframe_audioindex){
/*
AAC in some container format (FLV, MP4, MKV etc.) need to add 7 Bytes
ADTS Header in front of AVPacket data manually.
Other Audio Codec (MP3...) works well.
*/
*timestamp = Readframe_pkt.pts * av_q2d(Readframe_ifmt_ctx->streams[Readframe_pkt.stream_index]->time_base) * 1000;
/*handle read Audio frame*/
memcpy(audio_data,Readframe_pkt.data,Readframe_pkt.size);
*audio_size = Readframe_pkt.size;
*isKeyframe = -1;
}
av_free_packet(&Readframe_pkt);
}else{
av_free_packet(&Readframe_pkt);
return ffmpegMp4_StopReadframe();
}
return 0;
}
这里是uninit函数
int ffmpegMp4_StopReadframe(){
if(Readframe_ifmt_ctx == NULL)
return STOPLOOP;
// SeekFrame(Readframe_ifmt_ctx,0);//重置seek位
int ret;
#if USE_H264BSF
av_bitstream_filter_close(Readframe_h264bsfc);
#endif
avformat_close_input(&Readframe_ifmt_ctx);
Readframe_ifmt_ctx = NULL;
printf("stop readframe done!\n");
return STOPLOOP;
}
这里是循环的测试调用
while(count <= 5){
ffmpegMp4_Openinputfile("/mnt/mmc/Normal/NO2021-1224-112203.mp4",&ifmt_ctx,videoindex,audioindex);
while(ffmpegMp4_Readframe(video_buffer,&video_size,&iskeyframe,×tamp,audio_buffer,&audio_size) == 0);
ffmpegMp4_StopReadframe();
printf("break?\n");
usleep(500 * 1000);
}
结果是打印完break后,就挂掉了