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;
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.