Открытый поток с FFmpeg libavformat завершает работу с ошибкой ввода-вывода после однократного в приложении Android
Я пытаюсь открыть видеопоток в приложении для Android. В первый раз, когда я открываю поток, поток открывается, и все работает нормально. Однако, если я нажимаю назад и снова открываю поток, приложение вылетает.
Я новичок в этом, поэтому я использовал лог-операторы, чтобы увидеть, могут ли значения аргументов для методов привести меня к этой проблеме. Я понял что avformat_open_input(&ic, is->filename, is->iformat, NULL)
возвращает ошибку ввода / вывода. Однако я не могу понять, где лежит ошибка, имя файла и формат совпадают, но я не уверен в &ic
который из is->ic = (AVFormatContext*) avformat_alloc_context()
, Буду признателен за любую помощь!
void get_video_info(int p_debug, const char* path) {
int flags;
//VideoState *is;
int err, i, orig_nb_streams, ret;
isquit = 0;
av_log_set_flags(AV_LOG_SKIP_REPEATED);
int st_index[3];
st_index[AVMEDIA_TYPE_AUDIO]=-1;
st_index[AVMEDIA_TYPE_VIDEO]=-1;
/* register all codecs, demux and protocols */
avcodec_register_all();
#if CONFIG_AVDEVICE
avdevice_register_all();
#endif
#if CONFIG_AVFILTER
avfilter_register_all();
#endif
av_register_all();
#if CONFIG_NETWORK
ret = avformat_network_init();
#endif
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());
exit(1);
}
av_init_packet(&flush_pkt);
flush_pkt.data = "FLUSH";
// open video stream
is = av_mallocz(sizeof(VideoState));
if (!is) {
do_exit(NULL);
return;
}
is->abort_request = 0; // FIXME: abort_request changes when on closing or exit
is->pictq_mutex = SDL_CreateMutex();
is->pictq_cond = SDL_CreateCond();
is->pictq_size = 0;
is->pictq_rindex = 0;
is->pictq_windex = 0;
is->av_sync_type = av_sync_type;//AV_SYNC_AUDIO_MASTER;//
if(path != NULL)
{
av_strlcpy(is->filename, path, sizeof(is->filename));
}
else
{
if(streamProtocal==0) {
av_strlcpy(is->filename, "/sdcard/download/sdp_file.sdp", sizeof(is->filename));
}
else
{
av_strlcpy(is->filename, "udp://@:3001", sizeof(is->filename));
is->iformat = av_find_input_format("m4v");
}
}
is->ic = (AVFormatContext*) avformat_alloc_context();
//It is assumed that server always sends m4v data, so that codec search can be avoided
AVFormatContext *ic = is->ic;
if ((err = avformat_open_input(&ic, is->filename, is->iformat, NULL))
!= 0) {
LOGE(1, "Error open video file: %s", is->filename);
char* error = (char*)malloc(1024);
av_strerror(err, error, 1024);
LOGE(1, "Error open video file: %s", error);
do_exit(is);
}
LOGE(1, "entered get_video_info");
is->ic = ic;
orig_nb_streams = ic->nb_streams;
if ((err = avformat_find_stream_info(is->ic, NULL)) < 0) {
LOGE(1, "Error find stream information: %d", err);
return;
}
LOGE(1, "avformat_find_stream_info");
if(is->ic->pb)
is->ic->pb->eof_reached= 0;//FIXME hack, ffplay maybe should not use url_feof() to test for the end
AVCodec *lvideoCodec;
int g_audio_file_type = 0;
// Find the first video stream
for (i=0; i<is->ic->nb_streams; i++) {
//take video stream only for video file types
if (g_audio_file_type == 0) {
if (is->ic->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO &&
st_index[AVMEDIA_TYPE_VIDEO] < 0)
{
st_index[AVMEDIA_TYPE_VIDEO]=i;
}
}
if(is->ic->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO &&
st_index[AVMEDIA_TYPE_AUDIO] < 0)
{
st_index[AVMEDIA_TYPE_AUDIO]=i;
}
}
if (st_index[AVMEDIA_TYPE_AUDIO] >= 0) {
stream_component_open(is, st_index[AVMEDIA_TYPE_AUDIO]);
}
if (st_index[AVMEDIA_TYPE_VIDEO] >= 0) {
stream_component_open(is, st_index[AVMEDIA_TYPE_VIDEO]);
}
if (is->video_stream < 0) {
do_exit(is);
return;
}
is->read_tid = SDL_CreateThread(read_thread, is);
rgb_frame = avcodec_alloc_frame();
}