英文:
Why the source order matters on working with multiple media sources in a single AVFormatContext?
问题
avformat_open_input()
在源顺序更改时会删除AVFormatContext*
并返回-6
。
我尝试以单个上下文(AVFormatContext
)动态打开多个不同(混合)格式和编解码器的媒体源。
我的媒体源是首先作为第一源的BlackMagic DeckLink Duo SDI输入,然后是mp4文件
或rtsp流
。
当我首先打开源2(RTSP或MP4文件),然后打开BlackMagic DeckLink Duo,一切都如预期那样进行。
但当我更改顺序,首先打开DeckLink,然后尝试打开RTSP流或MP4文件时,根据调试器的检查,av_open_input()
函数会删除AVFormatContext*
并返回-6
作为结果。
请查看以下的简单错误重现代码片段;
AVFormatContext* context{avformat_alloc_context()};
const char* url_source1{"DeckLink Duo (1)"};
const AVInputFormat* format_source1{av_find_input_format("decklink")};
const char* url_source2{"http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"};
// 打开第一个媒体输入
int result = avformat_open_input(&context, url_source1, format_source1, NULL);
if(result < 0) {
exit(1);
}
// 打开第二个媒体输入
// 在当前顺序中,此函数会删除上下文并返回-6
result = avformat_open_input(&context, url_source2, NULL, NULL);
if(result < 0) {
exit(1);
}
// 由于上一步中已删除上下文,因此会在此处发生分段错误!
result = avformat_find_stream_info(context, NULL);
if(result < 0) {
exit(1);
}
std::cout << "流的总数: " << context->nb_streams << std::endl;
但是,当我更改顺序,首先为mp4
文件调用avformat_open_input()
,然后为DeckLink
设备调用,如下所示,一切都如预期那样进行,没有错误。
AVFormatContext* context{avformat_alloc_context()};
const char* url_source1{"DeckLink Duo (1)"};
const AVInputFormat* format_source1{av_find_input_format("decklink")};
const char* url_source2{"http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"};
// 打开第二个媒体输入
int result = avformat_open_input(&context, url_source2, NULL, NULL);
if(result < 0) {
exit(1);
}
// 打开第一个媒体输入
result = avformat_open_input(&context, url_source1, format_source1, NULL);
if(result < 0) {
exit(1);
}
result = avformat_find_stream_info(context, NULL);
if(result < 0) {
exit(1);
}
std::cout << "流的总数: " << context->nb_streams << std::endl;
英文:
avformat_open_input()
deletes the AVFormatContext*
and returns -6
when the source order changes.
I am trying to open multiple media sources dynamically with different(mixed) formats and codecs in a single context (AVFormatContext
).
My media sources are a BlackMagic DeckLink Duo SDI input as first source and an mp4 file
or rtsp stream
as second.
When I order to open (avformat_open_input()
) the source 2 (RTSP or MP4 file) at first and then open the BlackMagic DeckLink Duo, proceed as expected.
But when I change the order, and first open the DeckLink and then try to open RTSP stream or MP4 file, as I inspected in the step debugger; AVFormatContext*
deleting in the av_open_input()
function and it returns -6
as result.
Please find the simple error reproduction code snappet below;
AVFormatContext* context{avformat_alloc_context()};
const char* url_source1{"DeckLink Duo (1)"};
const AVInputFormat* format_source1{av_find_input_format("decklink")};
const char* url_source2{"http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"};
// Open the first media input
int result = avformat_open_input(&context, url_source1, format_source1, NULL);
if(result < 0) {
exit(1);
}
// Open the second media input
// This function in current order deletes the context and returns -6
result = avformat_open_input(&context, url_source2, NULL, NULL);
if(result < 0) {
exit(1);
}
// Since the context has been deleted in previous step, segmentation fault accours here!
result = avformat_find_stream_info(context, NULL);
if(result < 0) {
exit(1);
}
std::cout << "Total number of streams: " << context->nb_streams << std::endl;
But When I change the order and call the avformat_open_input()
first for the mp4
file and then the DeckLink
device as following it proceed as expected, no error.
AVFormatContext* context{avformat_alloc_context()};
const char* url_source1{"DeckLink Duo (1)"};
const AVInputFormat* format_source1{av_find_input_format("decklink")};
const char* url_source2{"http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"};
// Open the second media input
int result = avformat_open_input(&context, url_source2, NULL, NULL);
if(result < 0) {
exit(1);
}
// Open the first media input
result = avformat_open_input(&context, url_source1, format_source1, NULL);
if(result < 0) {
exit(1);
}
result = avformat_find_stream_info(context, NULL);
if(result < 0) {
exit(1);
}
std::cout << "Total number of streams: " << context->nb_streams << std::endl;
答案1
得分: 1
在FFmpeg API中明确提到,avformat_open_input()
会在失败的情况下释放用户提供的上下文:
- ps(第一个参数)是指向用户提供的AVFormatContext的指针(由avformat_alloc_context分配),可能是指向NULL的指针,这种情况下,该函数将分配一个AVFormatContext并将其写入ps。请注意,如果出现失败,用户提供的AVFormatContext将被释放。
在错误处理程序中实现av_strerror
以获取人类可读的错误信息。这将有所帮助。
英文:
It is clearly mentioned on the FFmpeg API avformat_open_input()
will free the user-supplied context in case of failure:
ps (the first parameter) is a pointer to the user-supplied AVFormatContext (allocated by
avformat_alloc_context) may be a pointer to NULL, in which case an AVFormatContext is
allocated by this function and written into ps. Note that a user-supplied AVFormatContext
will be freed on failure.
Implement on your error handler an av_strerror
to get human-readable error information. It will help.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论