FFmpegSource2: fix the last memory leaks

Originally committed to SVN as r2328.
This commit is contained in:
Fredrik Mellbin 2008-09-06 20:05:29 +00:00
parent 91e1fb7f06
commit 3d0855e619
2 changed files with 50 additions and 15 deletions

View file

@ -95,7 +95,7 @@ VideoBase::~VideoBase() {
} }
AVFrame *GetFrameByTime(double Time, char *ErrorMsg, unsigned MsgSize) { AVFrame *GetFrameByTime(double Time, char *ErrorMsg, unsigned MsgSize) {
// FIXME
//Frames.ClosestFrameFromDTS(); //Frames.ClosestFrameFromDTS();
//return GetFrame(, ErrorMsg, MsgSize); //return GetFrame(, ErrorMsg, MsgSize);
return NULL; return NULL;
@ -129,6 +129,14 @@ int FFVideoSource::GetTrackIndex(int &Index, char *ErrorMsg, unsigned MsgSize) {
return 0; return 0;
} }
void FFVideoSource::Free(bool CloseCodec) {
if (CloseCodec)
avcodec_close(CodecContext);
av_close_input_file(FormatContext);
// FIXME
//av_free(FormatContext);
}
FFVideoSource::FFVideoSource(const char *SourceFile, int Track, FrameIndex *TrackIndices, FFVideoSource::FFVideoSource(const char *SourceFile, int Track, FrameIndex *TrackIndices,
const char *PP, int Threads, int SeekMode, char *ErrorMsg, unsigned MsgSize) { const char *PP, int Threads, int SeekMode, char *ErrorMsg, unsigned MsgSize) {
@ -142,22 +150,27 @@ FFVideoSource::FFVideoSource(const char *SourceFile, int Track, FrameIndex *Trac
} }
if (av_find_stream_info(FormatContext) < 0) { if (av_find_stream_info(FormatContext) < 0) {
Free(false);
_snprintf(ErrorMsg, MsgSize, "Couldn't find stream information"); _snprintf(ErrorMsg, MsgSize, "Couldn't find stream information");
throw ErrorMsg; throw ErrorMsg;
} }
VideoTrack = Track; VideoTrack = Track;
if (GetTrackIndex(VideoTrack, ErrorMsg, MsgSize)) if (GetTrackIndex(VideoTrack, ErrorMsg, MsgSize)) {
Free(false);
throw ErrorMsg; throw ErrorMsg;
}
Frames = (*TrackIndices)[VideoTrack]; Frames = (*TrackIndices)[VideoTrack];
if (Frames.size() == 0) { if (Frames.size() == 0) {
Free(false);
_snprintf(ErrorMsg, MsgSize, "Video track contains no frames"); _snprintf(ErrorMsg, MsgSize, "Video track contains no frames");
throw ErrorMsg; throw ErrorMsg;
} }
if (SeekMode >= 0 && av_seek_frame(FormatContext, VideoTrack, Frames[0].DTS, AVSEEK_FLAG_BACKWARD) < 0) { if (SeekMode >= 0 && av_seek_frame(FormatContext, VideoTrack, Frames[0].DTS, AVSEEK_FLAG_BACKWARD) < 0) {
Free(false);
_snprintf(ErrorMsg, MsgSize, "Video track is unseekable"); _snprintf(ErrorMsg, MsgSize, "Video track is unseekable");
throw ErrorMsg; throw ErrorMsg;
} }
@ -167,19 +180,23 @@ FFVideoSource::FFVideoSource(const char *SourceFile, int Track, FrameIndex *Trac
Codec = avcodec_find_decoder(CodecContext->codec_id); Codec = avcodec_find_decoder(CodecContext->codec_id);
if (Codec == NULL) { if (Codec == NULL) {
Free(false);
_snprintf(ErrorMsg, MsgSize, "Video codec not found"); _snprintf(ErrorMsg, MsgSize, "Video codec not found");
throw ErrorMsg; throw ErrorMsg;
} }
if (avcodec_open(CodecContext, Codec) < 0) { if (avcodec_open(CodecContext, Codec) < 0) {
Free(false);
_snprintf(ErrorMsg, MsgSize, "Could not open video codec"); _snprintf(ErrorMsg, MsgSize, "Could not open video codec");
throw ErrorMsg; throw ErrorMsg;
} }
// Always try to decode a frame to make sure all required parameters are known // Always try to decode a frame to make sure all required parameters are known
int64_t Dummy; int64_t Dummy;
if (DecodeNextFrame(DecodeFrame, &Dummy, ErrorMsg, MsgSize)) if (DecodeNextFrame(DecodeFrame, &Dummy, ErrorMsg, MsgSize)) {
Free(true);
throw ErrorMsg; throw ErrorMsg;
}
//VP.image_type = VideoInfo::IT_TFF; //VP.image_type = VideoInfo::IT_TFF;
VP.Width = CodecContext->width; VP.Width = CodecContext->width;
@ -190,6 +207,7 @@ FFVideoSource::FFVideoSource(const char *SourceFile, int Track, FrameIndex *Trac
VP.PixelFormat = CodecContext->pix_fmt; VP.PixelFormat = CodecContext->pix_fmt;
if (VP.Width <= 0 || VP.Height <= 0) { if (VP.Width <= 0 || VP.Height <= 0) {
Free(true);
_snprintf(ErrorMsg, MsgSize, "Codec returned zero size video"); _snprintf(ErrorMsg, MsgSize, "Codec returned zero size video");
throw ErrorMsg; throw ErrorMsg;
} }
@ -213,16 +231,13 @@ FFVideoSource::FFVideoSource(const char *SourceFile, int Track, FrameIndex *Trac
OutputFrame(DecodeFrame); OutputFrame(DecodeFrame);
LastFrameNum = 0; LastFrameNum = 0;
// Set AR variables // Set AR variables
VP.SARNum = CodecContext->sample_aspect_ratio.num; VP.SARNum = CodecContext->sample_aspect_ratio.num;
VP.SARDen = CodecContext->sample_aspect_ratio.den; VP.SARDen = CodecContext->sample_aspect_ratio.den;
} }
FFVideoSource::~FFVideoSource() { FFVideoSource::~FFVideoSource() {
if (VideoTrack >= 0) Free(true);
avcodec_close(CodecContext);
av_close_input_file(FormatContext);
} }
int FFVideoSource::DecodeNextFrame(AVFrame *AFrame, int64_t *AStartTime, char *ErrorMsg, unsigned MsgSize) { int FFVideoSource::DecodeNextFrame(AVFrame *AFrame, int64_t *AStartTime, char *ErrorMsg, unsigned MsgSize) {
@ -347,12 +362,25 @@ int MatroskaVideoSource::GetTrackIndex(int &Index, char *ErrorMsg, unsigned MsgS
return 0; return 0;
} }
void MatroskaVideoSource::Free(bool CloseCodec) {
if (CS)
cs_Destroy(CS);
if (MC.ST.fp) {
mkv_Close(MF);
fclose(MC.ST.fp);
}
if (CloseCodec)
avcodec_close(CodecContext);
av_free(CodecContext);
}
MatroskaVideoSource::MatroskaVideoSource(const char *SourceFile, int Track, MatroskaVideoSource::MatroskaVideoSource(const char *SourceFile, int Track,
FrameIndex *TrackIndices, const char *PP, FrameIndex *TrackIndices, const char *PP,
int Threads, char *ErrorMsg, unsigned MsgSize) { int Threads, char *ErrorMsg, unsigned MsgSize) {
unsigned int TrackMask = ~0; unsigned int TrackMask = ~0;
AVCodec *Codec = NULL; AVCodec *Codec = NULL;
CodecContext = NULL;
TrackInfo *TI = NULL; TrackInfo *TI = NULL;
CS = NULL; CS = NULL;
@ -372,12 +400,15 @@ MatroskaVideoSource::MatroskaVideoSource(const char *SourceFile, int Track,
} }
VideoTrack = Track; VideoTrack = Track;
if (GetTrackIndex(VideoTrack, ErrorMsg, MsgSize)) if (GetTrackIndex(VideoTrack, ErrorMsg, MsgSize)) {
Free(false);
throw ErrorMsg; throw ErrorMsg;
}
Frames = (*TrackIndices)[VideoTrack]; Frames = (*TrackIndices)[VideoTrack];
if (Frames.size() == 0) { if (Frames.size() == 0) {
Free(false);
_snprintf(ErrorMsg, MsgSize, "Video track contains no frames"); _snprintf(ErrorMsg, MsgSize, "Video track contains no frames");
throw ErrorMsg; throw ErrorMsg;
} }
@ -388,6 +419,7 @@ MatroskaVideoSource::MatroskaVideoSource(const char *SourceFile, int Track,
if (TI->CompEnabled) { if (TI->CompEnabled) {
CS = cs_Create(MF, VideoTrack, ErrorMessage, sizeof(ErrorMessage)); CS = cs_Create(MF, VideoTrack, ErrorMessage, sizeof(ErrorMessage));
if (CS == NULL) { if (CS == NULL) {
Free(false);
_snprintf(ErrorMsg, MsgSize, "Can't create decompressor: %s", ErrorMessage); _snprintf(ErrorMsg, MsgSize, "Can't create decompressor: %s", ErrorMessage);
throw ErrorMsg; throw ErrorMsg;
} }
@ -400,19 +432,23 @@ MatroskaVideoSource::MatroskaVideoSource(const char *SourceFile, int Track,
Codec = avcodec_find_decoder(MatroskaToFFCodecID(TI)); Codec = avcodec_find_decoder(MatroskaToFFCodecID(TI));
if (Codec == NULL) { if (Codec == NULL) {
Free(false);
_snprintf(ErrorMsg, MsgSize, "Video codec not found"); _snprintf(ErrorMsg, MsgSize, "Video codec not found");
throw ErrorMsg; throw ErrorMsg;
} }
if (avcodec_open(CodecContext, Codec) < 0) { if (avcodec_open(CodecContext, Codec) < 0) {
Free(false);
_snprintf(ErrorMsg, MsgSize, "Could not open video codec"); _snprintf(ErrorMsg, MsgSize, "Could not open video codec");
throw ErrorMsg; throw ErrorMsg;
} }
// Always try to decode a frame to make sure all required parameters are known // Always try to decode a frame to make sure all required parameters are known
int64_t Dummy; int64_t Dummy;
if (DecodeNextFrame(DecodeFrame, &Dummy, ErrorMsg, MsgSize)) if (DecodeNextFrame(DecodeFrame, &Dummy, ErrorMsg, MsgSize)) {
Free(true);
throw ErrorMsg; throw ErrorMsg;
}
VP.Width = CodecContext->width; VP.Width = CodecContext->width;
VP.Height = CodecContext->height;; VP.Height = CodecContext->height;;
@ -422,6 +458,7 @@ MatroskaVideoSource::MatroskaVideoSource(const char *SourceFile, int Track,
VP.PixelFormat = CodecContext->pix_fmt; VP.PixelFormat = CodecContext->pix_fmt;
if (VP.Width <= 0 || VP.Height <= 0) { if (VP.Width <= 0 || VP.Height <= 0) {
Free(true);
_snprintf(ErrorMsg, MsgSize, "Codec returned zero size video"); _snprintf(ErrorMsg, MsgSize, "Codec returned zero size video");
throw ErrorMsg; throw ErrorMsg;
} }
@ -451,11 +488,7 @@ MatroskaVideoSource::MatroskaVideoSource(const char *SourceFile, int Track,
} }
MatroskaVideoSource::~MatroskaVideoSource() { MatroskaVideoSource::~MatroskaVideoSource() {
mkv_Close(MF); Free(true);
fclose(MC.ST.fp);
if (CodecContext)
avcodec_close(CodecContext);
av_free(CodecContext);
} }
int MatroskaVideoSource::DecodeNextFrame(AVFrame *AFrame, int64_t *AFirstStartTime, char *ErrorMsg, unsigned MsgSize) { int MatroskaVideoSource::DecodeNextFrame(AVFrame *AFrame, int64_t *AFirstStartTime, char *ErrorMsg, unsigned MsgSize) {

View file

@ -65,8 +65,9 @@ public:
class FFVideoSource : public VideoBase { class FFVideoSource : public VideoBase {
private: private:
AVFormatContext *FormatContext; AVFormatContext *FormatContext;
int SeekMode; int SeekMode;
void Free(bool CloseCodec);
int GetTrackIndex(int &Index, char *ErrorMsg, unsigned MsgSize); int GetTrackIndex(int &Index, char *ErrorMsg, unsigned MsgSize);
int DecodeNextFrame(AVFrame *Frame, int64_t *DTS, char *ErrorMsg, unsigned MsgSize); int DecodeNextFrame(AVFrame *Frame, int64_t *DTS, char *ErrorMsg, unsigned MsgSize);
public: public:
@ -82,6 +83,7 @@ private:
CompressedStream *CS; CompressedStream *CS;
char ErrorMessage[256]; char ErrorMessage[256];
void Free(bool CloseCodec);
int DecodeNextFrame(AVFrame *AFrame, int64_t *AFirstStartTime, char *ErrorMsg, unsigned MsgSize); int DecodeNextFrame(AVFrame *AFrame, int64_t *AFirstStartTime, char *ErrorMsg, unsigned MsgSize);
int GetTrackIndex(int &Index, char *ErrorMsg, unsigned MsgSize); int GetTrackIndex(int &Index, char *ErrorMsg, unsigned MsgSize);
public: public: