我将位图从我的c#app传递到c ++ / cli dll,将其添加到视频中。 问题是程序慢慢泄漏内存。我试过_CrtDumpMemoryLeaks()显示我的位图泄漏&另外40字节泄漏,但我正在处理位图。 任何人都可以看到内存泄漏,这是代码..
流速:
1)通过takescreenshot()获取截图
2)将其传递给c ++ / cli函数
3)配置位图
来自我的c#app的行
Bitmap snap = takescreeshot();
vencoder.AddBitmap(snap);
snap.Dispose();
vencoder.printleak();
private static Bitmap takescreeshot()
{
System.Drawing.Bitmap bitmap = null;
System.Drawing.Graphics graphics = null;
bitmap = new Bitmap
(
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width,
System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height,
System.Drawing.Imaging.PixelFormat.Format24bppRgb
);
graphics = System.Drawing.Graphics.FromImage(bitmap);
graphics.CopyFromScreen(Screen.PrimaryScreen.Bounds.X, Screen.PrimaryScreen.Bounds.Y, 0, 0, Screen.PrimaryScreen.Bounds.Size);
//Write TimeSpamp
Rectangle rect = new Rectangle(1166, 738, 200, 20);
String datetime= System.String.Format("{0:dd:MM:yy hh:mm:ss}",DateTime.Now);
System.Drawing.Font sysfont = new System.Drawing.Font("Times New Roman", 14, FontStyle.Bold);
graphics.DrawString(datetime, sysfont, Brushes.Red,rect);
//
Grayscale filter = new Grayscale(0.2125, 0.7154, 0.0721);
Bitmap grayImage = filter.Apply(bitmap);
//Dispose
bitmap.Dispose();
graphics.Dispose();
return grayImage;
}
现在在c ++ / cli dll
bool VideoEncoder::AddBitmap(Bitmap^ bitmap)
{
BitmapData^ bitmapData = bitmap->LockBits( System::Drawing::Rectangle( 0, 0,bitmap->Width, bitmap->Height ),ImageLockMode::ReadOnly,PixelFormat::Format8bppIndexed);
uint8_t* ptr = reinterpret_cast<uint8_t*>( static_cast<void*>( bitmapData->Scan0 ) );
uint8_t* srcData[4] = { ptr, NULL, NULL, NULL };
int srcLinesize[4] = { bitmapData->Stride, 0, 0, 0 };
pCurrentPicture = CreateFFmpegPicture(pVideoStream->codec->pix_fmt, pVideoStream->codec->width, pVideoStream->codec->height);
sws_scale(pImgConvertCtx, srcData, srcLinesize, 0, bitmap->Height, pCurrentPicture->data, pCurrentPicture->linesize );
bitmap->UnlockBits( bitmapData );
write_video_frame();
bitmapData=nullptr;
ptr=NULL;
return true;
}
AVFrame * VideoEncoder::CreateFFmpegPicture(int pix_fmt, int nWidth, int nHeight)
{
AVFrame *picture = NULL;
uint8_t *picture_buf = NULL;
int size;
picture = avcodec_alloc_frame();
if ( !picture)
{
printf("Cannot create frame\n");
return NULL;
}
size = avpicture_get_size((AVPixelFormat)pix_fmt, nWidth, nHeight);
picture_buf = (uint8_t *) av_malloc(size);
if (!picture_buf)
{
av_free(picture);
printf("Cannot allocate buffer\n");
return NULL;
}
avpicture_fill((AVPicture *)picture, picture_buf,
(AVPixelFormat)pix_fmt, nWidth, nHeight);
return picture;
}
void VideoEncoder::write_video_frame()
{
AVCodecContext* codecContext = pVideoStream->codec;
int out_size, ret = 0;
if ( pFormatContext->oformat->flags & AVFMT_RAWPICTURE )
{
printf( "raw picture must be written" );
}
else
{
out_size = avcodec_encode_video( codecContext, pVideoEncodeBuffer,nSizeVideoEncodeBuffer, pCurrentPicture );
if ( out_size > 0 )
{
AVPacket packet;
av_init_packet( &packet );
if ( codecContext->coded_frame->pts != AV_NOPTS_VALUE )
{
packet.pts = av_rescale_q( packet.pts, codecContext->time_base, pVideoStream->time_base );
}
if ( codecContext->coded_frame->pkt_dts != AV_NOPTS_VALUE )
{
packet.dts = av_rescale_q( packet.dts, codecContext->time_base, pVideoStream->time_base );
}
if ( codecContext->coded_frame->key_frame )
{
packet.flags |= AV_PKT_FLAG_KEY;
}
packet.stream_index = pVideoStream->index;
packet.data = pVideoEncodeBuffer;
packet.size = out_size;
ret = av_interleaved_write_frame( pFormatContext, &packet );
av_free_packet(&packet);
av_freep(pCurrentPicture);
}
else
{
// image was buffered
}
}
if ( ret != 0 )
{
throw gcnew Exception( "Error while writing video frame." );
}
}
void VideoEncoder::printleak()
{
printf("No of leaks: %d",_CrtDumpMemoryLeaks());
printf("\n");
}