
Recherche avancée
Médias (1)
-
The Great Big Beautiful Tomorrow
28 octobre 2011, par
Mis à jour : Octobre 2011
Langue : English
Type : Texte
Autres articles (45)
-
Mise à jour de la version 0.1 vers 0.2
24 juin 2013, parExplications des différents changements notables lors du passage de la version 0.1 de MediaSPIP à la version 0.3. Quelles sont les nouveautés
Au niveau des dépendances logicielles Utilisation des dernières versions de FFMpeg (>= v1.2.1) ; Installation des dépendances pour Smush ; Installation de MediaInfo et FFprobe pour la récupération des métadonnées ; On n’utilise plus ffmpeg2theora ; On n’installe plus flvtool2 au profit de flvtool++ ; On n’installe plus ffmpeg-php qui n’est plus maintenu au (...) -
Personnaliser en ajoutant son logo, sa bannière ou son image de fond
5 septembre 2013, parCertains thèmes prennent en compte trois éléments de personnalisation : l’ajout d’un logo ; l’ajout d’une bannière l’ajout d’une image de fond ;
-
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
Sur d’autres sites (3366)
-
Getting Access Violations Exceptions in FFmpeg when trying to free IO buffer
26 juin 2015, par PatrikI’ve been trying to create an audio stream extractor/demuxer using FFmpeg.AutoGen and C#. While the code actually works (in the sense that it extracts the audio stream correctly), I can’t seem to clean up the resources afterwards. Whenever I try to free my input buffer (allocated using av_malloc) I get an Access Violation Exception, and if I don’t free it, I seem to be leaking memory corresponding to the size of the allocated input buffer.
This is my code (from a console application I used for testing) :
class Program
{
static void Main(string[] args)
{
using (var videoStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("FFmpeg.Demux.test.mp4"))
using (MemoryStream output = new MemoryStream())
{
FFmpegAudioExtractor audioExtractor = new FFmpegAudioExtractor();
audioExtractor.Extract(videoStream, output);
Debug.Assert(1331200 == output.Length);
//File.WriteAllBytes(@"c:\temp\out.pcm", output.ToArray());
}
Console.WriteLine("Done");
Console.ReadLine();
}
}
public class FFmpegAudioExtractor
{
public FFmpegAudioExtractor()
{
FFmpegInvoke.av_register_all();
FFmpegInvoke.avcodec_register_all();
}
public unsafe void Extract(Stream input, Stream output)
{
AVFormatContext* inFormatContextPtr = null;
int inFomatContextOpenResult = -1;
byte* inIoBuffer = null;
AVIOContext* inIoContextPtr = null;
SwrContext* swrContextPtr = null;
AVFrame* inFramePtr = null;
AVFrame* outFramePtr = null;
AVCodecContext* inCodecContextPtr = null;
try
{
/* 1 */
inFormatContextPtr = FFmpegInvoke.avformat_alloc_context();
if (inFormatContextPtr == null)
throw new ApplicationException("Failed to allocate the input format context (AVFormatContext).");
// HACK this should alloc a fixed buffer and use callbacks to fill it
if (input.Length > int.MaxValue)
throw new ArgumentException("Data too large.", "input");
// TEST alloc a 10MB buffer to make the memory leak real obvious
int inIoBufferSize = 1024 * 1024 * 10; //(int)input.Length;
/* 2 */
inIoBuffer = (byte*)FFmpegInvoke.av_malloc((uint)inIoBufferSize);
if (inIoBuffer == null)
throw new ApplicationException("Failed to allocate the input IO buffer.");
// HACK continued, fill buffer
IntPtr inIoBufferPtr = new IntPtr(inIoBuffer);
byte[] buffer = new byte[4096];
int read, offset = 0;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
Marshal.Copy(buffer, 0, inIoBufferPtr + offset, read);
offset += read;
}
/* 3 */
inIoContextPtr = FFmpegInvoke.avio_alloc_context((sbyte*)inIoBuffer,
inIoBufferSize,
0 /* writable */,
null,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero);
if (inIoContextPtr == null)
throw new ApplicationException("Failed to allocate the input IO context (AVIOContext).");
// configure the format context to use our custom IO contect
inFormatContextPtr->pb = inIoContextPtr;
inFormatContextPtr->flags = FFmpegInvoke.AVFMT_FLAG_CUSTOM_IO;
/* 35 */
inFomatContextOpenResult = FFmpegInvoke.avformat_open_input(&inFormatContextPtr, "", null, null);
if (inFomatContextOpenResult != 0)
throw new ApplicationException("Could not open input: " + inFomatContextOpenResult.ToString(CultureInfo.InvariantCulture));
// retrieve stream information
int avformatFindStreamInfoResult = FFmpegInvoke.avformat_find_stream_info(inFormatContextPtr, null);
if (avformatFindStreamInfoResult < 0)
throw new ApplicationException("Failed to locate stream info: " + avformatFindStreamInfoResult.ToString(CultureInfo.InvariantCulture));
// find audio stream
int inAudioStreamIndex = FFmpegInvoke.av_find_best_stream(inFormatContextPtr,
AVMediaType.AVMEDIA_TYPE_AUDIO,
-1 /* wanted_stream_nb */,
-1 /* related_stream */,
null /* [out] decoder */,
0 /* flags */);
if (inAudioStreamIndex < 0)
throw new ApplicationException("Failed to find audio stream: " + inAudioStreamIndex.ToString(CultureInfo.InvariantCulture));
// get audio stream pointer
AVStream* inAudioStreamPtr = inFormatContextPtr->streams[inAudioStreamIndex];
Contract.Assume(inAudioStreamPtr != null);
// find the decoder
AVCodec* inCodecPtr = FFmpegInvoke.avcodec_find_decoder(inAudioStreamPtr->codec->codec_id);
if (inCodecPtr == null)
throw new ApplicationException("Failed to find decoder with codec_id: " + inAudioStreamPtr->codec->codec_id.ToString());
/* 36 */
inCodecContextPtr = FFmpegInvoke.avcodec_alloc_context3(inCodecPtr);
if (FFmpegInvoke.avcodec_copy_context(inCodecContextPtr, inAudioStreamPtr->codec) != 0)
throw new ApplicationException("Failed to copy context.");
// open codec
/* 37 */
if (FFmpegInvoke.avcodec_open2(inCodecContextPtr, inCodecPtr, null) < 0)
{
string codecName = Marshal.PtrToStringAuto(new IntPtr(inCodecPtr->name));
throw new Exception("Failed to open codec: " + codecName);
}
// alloc frame
/* 38 */
inFramePtr = FFmpegInvoke.av_frame_alloc();
if (inFramePtr == null)
throw new ApplicationException("Could not allocate frame");
// initialize packet, set data to NULL, let the demuxer fill it
AVPacket packet = new AVPacket();
AVPacket* packetPtr = &packet;
FFmpegInvoke.av_init_packet(packetPtr);
packetPtr->data = null;
packetPtr->size = 0;
// alloc SWR
/* 4 */
swrContextPtr = FFmpegInvoke.swr_alloc();
AVSampleFormat outSampleFormat = AVSampleFormat.AV_SAMPLE_FMT_S16;
long outChannelLayout = FFmpegInvoke.AV_CH_FRONT_LEFT | FFmpegInvoke.AV_CH_FRONT_RIGHT;
// configure SWR
FFmpegInvoke.av_opt_set_sample_fmt(swrContextPtr, "in_sample_fmt", inCodecContextPtr->sample_fmt, 0);
FFmpegInvoke.av_opt_set_sample_fmt(swrContextPtr, "out_sample_fmt", outSampleFormat, 0);
// setting the in_channel_layout seems to break things
//FFmpegInvoke.av_opt_set_channel_layout(swrContextPtr, "in_channel_layout", (long)inCodecContextPtr->channel_layout, 0);
FFmpegInvoke.av_opt_set_channel_layout(swrContextPtr, "out_channel_layout", outChannelLayout, 0);
FFmpegInvoke.av_opt_set_int(swrContextPtr, "in_sample_rate", inCodecContextPtr->sample_rate, 0);
FFmpegInvoke.av_opt_set_int(swrContextPtr, "out_sample_rate", 44100, 0);
// allock output frane
/* 45 */
outFramePtr = FFmpegInvoke.av_frame_alloc();
outFramePtr->channel_layout = (ulong)outChannelLayout;
outFramePtr->sample_rate = 44100;
outFramePtr->format = (int)outSampleFormat;
// config done, init
FFmpegInvoke.swr_init(swrContextPtr);
bool frameFinished;
// read frames from the file
while (FFmpegInvoke.av_read_frame(inFormatContextPtr, packetPtr) >= 0)
{
AVPacket* origPacketPtr = packetPtr;
try
{
if (packetPtr->stream_index != inAudioStreamIndex)
continue;
do
{
byte[] decodedFrame;
int decodedBytes = this.DecodePacket(inCodecContextPtr,
packetPtr,
inFramePtr,
swrContextPtr,
outFramePtr,
out frameFinished,
out decodedFrame);
if (decodedBytes < 0)
break;
output.Write(decodedFrame, 0, decodedFrame.Length);
packetPtr->data += decodedBytes;
packetPtr->size -= decodedBytes;
} while (packetPtr->size > 0);
}
finally
{
FFmpegInvoke.av_free_packet(origPacketPtr);
}
}
// flush cached frames
packetPtr->data = null;
packetPtr->size = 0;
do
{
byte[] decodedFrame;
this.DecodePacket(inCodecContextPtr, packetPtr, inFramePtr, swrContextPtr, outFramePtr, out frameFinished, out decodedFrame);
if (decodedFrame != null)
output.Write(decodedFrame, 0, decodedFrame.Length);
} while (frameFinished);
}
finally
{
/* 45 */
if (outFramePtr != null)
FFmpegInvoke.av_frame_free(&outFramePtr);
/* 4 */
if (swrContextPtr != null)
FFmpegInvoke.swr_free(&swrContextPtr);
/* 38 */
if (inFramePtr != null)
FFmpegInvoke.av_frame_free(&inFramePtr);
/* 37 */
if (inCodecContextPtr != null)
FFmpegInvoke.avcodec_close(inCodecContextPtr);
/* 36 */
if (inCodecContextPtr != null)
FFmpegInvoke.avcodec_free_context(&inCodecContextPtr);
/* 35 */
if (inFomatContextOpenResult == 0)
FFmpegInvoke.avformat_close_input(&inFormatContextPtr);
/* 3 */
if (inIoContextPtr != null)
FFmpegInvoke.av_freep(&inIoContextPtr);
//* 2 */
if (inIoBuffer != null)
FFmpegInvoke.av_freep(&inIoBuffer);
/* 1 */
// This is called by avformat_close_input
if (inFormatContextPtr != null)
FFmpegInvoke.avformat_free_context(inFormatContextPtr);
}
}
private unsafe int DecodePacket(AVCodecContext* audioDecoderContextPtr, AVPacket* packetPtr, AVFrame* inFramePtr, SwrContext* swrContextPtr, AVFrame* outFramePtr, out bool frameDecoded, out byte[] decodedFrame)
{
decodedFrame = null;
/* decode audio frame */
int gotFrame;
int readBytes = FFmpegInvoke.avcodec_decode_audio4(audioDecoderContextPtr, inFramePtr, &gotFrame, packetPtr);
if (readBytes < 0)
throw new ApplicationException("Error decoding audio frame: " + readBytes.ToString(CultureInfo.InvariantCulture));
frameDecoded = gotFrame != 0;
/* Some audio decoders decode only part of the packet, and have to be
* called again with the remainder of the packet data.
* Sample: fate-suite/lossless-audio/luckynight-partial.shn
* Also, some decoders might over-read the packet. */
int decoded = Math.Min(readBytes, packetPtr->size);
if (frameDecoded)
{
if (FFmpegInvoke.swr_convert_frame(swrContextPtr, outFramePtr, inFramePtr) != 0)
throw new ApplicationException("Failed to convert frame.");
long delay;
do
{
int unpaddedLinesize = outFramePtr->nb_samples * outFramePtr->channels * FFmpegInvoke.av_get_bytes_per_sample((AVSampleFormat)outFramePtr->format);
IntPtr dataPtr = new IntPtr(outFramePtr->extended_data[0]);
decodedFrame = new byte[unpaddedLinesize];
Marshal.Copy(dataPtr, decodedFrame, 0, unpaddedLinesize);
// check if we have more samples to convert for this frame
delay = FFmpegInvoke.swr_get_delay(swrContextPtr, 44100);
if (delay > 0)
{
if (FFmpegInvoke.swr_convert_frame(swrContextPtr, outFramePtr, null) != 0)
throw new ApplicationException("Failed to convert frame.");
}
} while (delay > 0);
}
return decoded;
}
}The failing line is :
FFmpegInvoke.av_freep(&inIoBuffer);
-
ffmpeg : Free last_frame instead of just unref
18 juin 2015, par Michael Niedermayer -
mpjpgdec : free AVIOContext leak on early probe fail
8 juin 2015, par Janne Grunau