Hi all,
I have made a videoplayer class under SDL 2.0 , following this topic : https://forums.libsdl.org/viewtopic.php?t=9898&highlight=ffmpeg
See the video playing code hereinbelow (how can I attach an archive ?).
The memory usage is growing here:
avcodec_decode_video2(pCodecCtx, frame, &frame_finished, &packet);
My question is : does anybody have the same behaviour or am I doing something wrong ?
Thanks
Code:
#include “video.h”
#include <string.h>
#include "globals.h"
extern “C”
{
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavutil/frame.h>
}
#define CODEC_TYPE_VIDEO AVMEDIA_TYPE_VIDEO
video::video(std::string filename,int x,int y,int width,int height,int zindex)
{
av_register_all();
avcodec_register_all();
this->filename = filename;
running = false;
playb = false;
playonceb = false;
stopb = false;
pos.x = x;
pos.y = y;
pos.w = width;
pos.h = height;
this->type = 3;
this->zindex = zindex;
}
video::~video()
{
}
void video::update()
{
if ((playb==false & playonceb==false) & running)
{
clean();
}
if(visible){
if (playb | playonceb)
{
if (!running)
{
pFormatCtx = NULL;
pCodec = NULL;
pCodecCtx = NULL;
if (avformat_open_input(&pFormatCtx, filename.c_str(), NULL, NULL) != 0)
{
playb = false;
printf(“file name error: %s\n”,filename.c_str());
return;
}
avformat_find_stream_info(pFormatCtx, NULL);
av_dump_format(pFormatCtx, 0, filename.c_str(), 0);
for (unsigned int i = 0; i < pFormatCtx->nb_streams; ++i)
{
if (!pCodecCtx && pFormatCtx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO)
{
pCodecCtx = pFormatCtx->streams[i]->codec;
videostream = i;
}
}
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
avcodec_open2(pCodecCtx, pCodec, NULL);
running = true;
}
AVPacket packet;
if(av_read_frame(pFormatCtx, &packet)<0)
{
av_free_packet(&packet);
printf(“Could not read frame!\n”);
if (playb) { avformat_seek_file(pFormatCtx,videostream,0,0,0,0); }
if (playonceb) {printf(“PLAYONCEB stop request\n”); playonceb = false; clean();return;}
} //readframe
AVFrame* frame = avcodec_alloc_frame();
int frame_finished;
avcodec_decode_video2(pCodecCtx, frame, &frame_finished, &packet);
if (frame_finished)
{
SDL_Texture* bmp = SDL_CreateTexture(RENDER, SDL_PIXELFORMAT_YV12,SDL_TEXTUREACCESS_STREAMING,pCodecCtx->width, pCodecCtx->height);
SDL_UpdateYUVTexture(bmp, NULL, frame->data[0], frame->linesize[0],frame->data[1], frame->linesize[1],frame->data[2], frame->linesize[2]);
SDL_RenderCopyEx(RENDER, bmp, NULL, &pos,0,NULL,SDL_FLIP_NONE);
SDL_DestroyTexture(bmp);
}//frame finished
av_free_packet(&packet);
av_free(frame);
}//if playb
} //visible
}
void video::clean()
{
printf(“clean\n”);
avcodec_close(pCodecCtx);
avcodec_close(pFormatCtx->streams[videostream]->codec);
if (pCodecCtx==NULL)
{
printf("(pCodecCtx) = NULL\n");
}
avformat_close_input(&pFormatCtx);
if (pFormatCtx==NULL)
{
printf(“pFormatCtx = NULL\n”);
}
running = false;
}
void video::playloop()
{
playonceb = false;
playb = true;
visible = 1;
}
void video::playonce()
{
playonceb = true;
playb = false;
visible = 1;
}
void video::stop()
{
playonceb = false;
playb = false;
visible = 0;
}
bool video::getrunning()
{
return running;
}