
Recherche avancée
Médias (91)
-
#3 The Safest Place
16 octobre 2011, par
Mis à jour : Février 2013
Langue : English
Type : Audio
-
#4 Emo Creates
15 octobre 2011, par
Mis à jour : Février 2013
Langue : English
Type : Audio
-
#2 Typewriter Dance
15 octobre 2011, par
Mis à jour : Février 2013
Langue : English
Type : Audio
-
#1 The Wires
11 octobre 2011, par
Mis à jour : Février 2013
Langue : English
Type : Audio
-
ED-ME-5 1-DVD
11 octobre 2011, par
Mis à jour : Octobre 2011
Langue : English
Type : Audio
-
Revolution of Open-source and film making towards open film making
6 octobre 2011, par
Mis à jour : Juillet 2013
Langue : English
Type : Texte
Autres articles (18)
-
Keeping control of your media in your hands
13 avril 2011, parThe vocabulary used on this site and around MediaSPIP in general, aims to avoid reference to Web 2.0 and the companies that profit from media-sharing.
While using MediaSPIP, you are invited to avoid using words like "Brand", "Cloud" and "Market".
MediaSPIP is designed to facilitate the sharing of creative media online, while allowing authors to retain complete control of their work.
MediaSPIP aims to be accessible to as many people as possible and development is based on expanding the (...) -
Publier sur MédiaSpip
13 juin 2013Puis-je poster des contenus à partir d’une tablette Ipad ?
Oui, si votre Médiaspip installé est à la version 0.2 ou supérieure. Contacter au besoin l’administrateur de votre MédiaSpip pour le savoir -
Submit bugs and patches
13 avril 2011Unfortunately a software is never perfect.
If you think you have found a bug, report it using our ticket system. Please to help us to fix it by providing the following information : the browser you are using, including the exact version as precise an explanation as possible of the problem if possible, the steps taken resulting in the problem a link to the site / page in question
If you think you have solved the bug, fill in a ticket and attach to it a corrective patch.
You may also (...)
Sur d’autres sites (3564)
-
avcodec/vvcdec : deblock, support virtual boundaries
15 juin 2024, par Nuo Mi -
avfilter/af_sofalizer : allow to specify virtual speakers indetifier as number
11 octobre 2020, par Paul B Mahol -
How do you properly free a BitStreamFilter (bsf) without getting a double free error ?
19 janvier 2021, par Alexis WilkeI'm trying to write a C++ class handling MP4 movies via ffmpeg.


First I created a couple of functions to use with
std::unique<>()
so that way things get released even on exceptions.

However, I get a double free when I try to free the BitStreamFilter object, yet the documentation clearly says that each
av_bsf_alloc()
must be paired with anav_bsf_free()
call.



@param ctx
a pointer into which the pointer to the newly-allocated context
will be written. It must be freed withav_bsf_free()
after the
filtering is done.



Note : emphasis mine.


However, at the time I call the
avformat_close_input()
I get a double free error, even if I haven't used the two contexts for anything !? I'm thinking that there may be a packet that both allocate and both try to free. But since these two contexts are not directly connected, I really don't understand how they end up freeing something twice.

Below is code which reproduce the error (at least on an amd64 platform). Once compiled, you can just execute it. Make sure to specify a filename as in :


./ffmpeg_demuxer_test mymovie.mp4



I used the following command to compile & link the code :


$ /usr/bin/c++ -std=c++17 -DDEBUG -D_DEBUG -D_GLIBCXX_ASSERTIONS -g -O0 \
 -fsanitize=address -fsanitize=enum -fsanitize=unreachable \
 -o ffmpeg_demuxer_test ffmpeg_demuxer_test.cpp \
 -lavformat -lavcodec



Notice the
-fsanitize=...
options to capture errors such as a double free error.

Here is the code :


extern "C" {
#include <libavformat></libavformat>avformat.h>
#include <libavformat></libavformat>avio.h>
#include <libavcodec></libavcodec>avcodec.h>
}
#include <iostream>
#include <memory>


void ffmpeg_demuxer_avformat_context_free(AVFormatContext * context)
{
 if(context != nullptr) avformat_close_input(&context);
}

void ffmpeg_demuxer_av_bsf_free(AVBSFContext * context)
{
 if(context != nullptr) av_bsf_free(&context);
}


int main(int argc, char * argv [])
{
 if(argc != 2)
 {
 std::cout << "Usage: " << argv[0] << " movie.mp4" << std::endl;
 exit(1);
 }

 // init the AV libraries
 //
 av_register_all();
 avformat_network_init();

 // allocate the AVFormatContext
 //
 AVFormatContext * format_context(nullptr);
 int const r1(avformat_open_input(
 &format_context
 , argv[1]
 , nullptr // input format
 , nullptr)); // options
 if(r1 != 0
 || format_context == nullptr)
 {
 throw std::bad_alloc();
 }

 auto f_format_context = std::unique_ptr<
 AVFormatContext
 , decltype(&ffmpeg_demuxer_avformat_context_free)>(
 format_context
 , &ffmpeg_demuxer_avformat_context_free);


 // now allocate a stream
 //
 if(avformat_find_stream_info(f_format_context.get(), nullptr) < 0)
 {
 throw std::runtime_error("ffmpeg: Could not find stream info");
 }

 auto f_video_stream_index = av_find_best_stream(
 f_format_context.get()
 , AVMEDIA_TYPE_VIDEO
 , -1 // wanted stream (any)
 , -1 // related stream (none)
 , nullptr // AVCodec *
 , 0); // flags
 if(f_video_stream_index < 0)
 {
 throw std::runtime_error("ffmpeg: Could not find stream in input file");
 }
 if(static_cast<unsigned int="int">(f_video_stream_index) >= f_format_context->nb_streams)
 {
 throw std::range_error("ffmpeg: Stream index out of range");
 }

 auto f_stream = f_format_context->streams[f_video_stream_index];

 auto f_video_codec = f_stream->codecpar->codec_id;

 int f_bit_depth(0);
 switch(f_stream->codecpar->format)
 {
 case AV_PIX_FMT_YUV420P10LE:
 f_bit_depth = 10;
 break;

 case AV_PIX_FMT_YUV420P12LE:
 f_bit_depth = 12;
 break;

 default:
 f_bit_depth = 8;
 break;

 }

 bool f_mp4_h264 = f_video_codec == AV_CODEC_ID_H264 && (
 strcmp(f_format_context->iformat->long_name, "QuickTime / MOV") == 0
 || strcmp(f_format_context->iformat->long_name, "FLV (Flash Video)") == 0
 || strcmp(f_format_context->iformat->long_name, "Matroska / WebM") == 0
 );

 if(f_mp4_h264)
 {
 AVBitStreamFilter const * bsf_stream_filter(av_bsf_get_by_name("h264_mp4toannexb"));
 if(bsf_stream_filter == nullptr)
 {
 throw std::runtime_error("av_bsf_get_by_name(\"h264_mp4toannexb\") failed");
 }
 AVBSFContext * bsf_context(nullptr);
 int const r2(av_bsf_alloc(bsf_stream_filter, &bsf_context));
 if(r2 < 0
 || bsf_context == nullptr)
 {
 throw std::bad_alloc();
 }
 auto f_bsf_context = std::unique_ptr<
 AVBSFContext
 , decltype(&ffmpeg_demuxer_av_bsf_free)>(
 bsf_context
 , &ffmpeg_demuxer_av_bsf_free);
 f_bsf_context->par_in = f_stream->codecpar;
 if(av_bsf_init(f_bsf_context.get()) < 0)
 {
 throw std::runtime_error("av_bsf_init() failed");
 }
 }

 return 0;
}
</unsigned></memory></iostream>


So. Am I misreading the documentation or misusing one of the free/close function ? I don't think that the
AVBSFContext
itself gets released when I close theAVFormatContext
, but I may be mistaken ?

I won't put "C" as a tag since it will get removed even though this applies to C. It's not because I use C++ that I get a double free (i.e. it happens in the ffmpeg C library).