請問讀avi檔進來在image上顯示怎麼沒多少記憶體就吃光光了 |
尚未結案
|
dragonhippopdc
一般會員 發表:45 回覆:51 積分:19 註冊:2005-01-15 發送簡訊給我 |
請問為何使用下面這個讀avi檔案的寫法~讀時間久一點的檔案~例如大概一兩分鐘的檔就會把記憶體都吃光光了~是那裡有寫錯了嗎~請各位大大幫我看一下ㄛ~謝謝各位大大
//--------------------------------------------------------------------------- #include |
pwipwi
版主 發表:68 回覆:629 積分:349 註冊:2004-04-08 發送簡訊給我 |
|
dragonhippopdc
一般會員 發表:45 回覆:51 積分:19 註冊:2005-01-15 發送簡訊給我 |
|
dragonhippopdc
一般會員 發表:45 回覆:51 積分:19 註冊:2005-01-15 發送簡訊給我 |
|
Demo99
一般會員 發表:2 回覆:8 積分:2 註冊:2003-06-27 發送簡訊給我 |
|
dragonhippopdc
一般會員 發表:45 回覆:51 積分:19 註冊:2005-01-15 發送簡訊給我 |
|
u9012021
一般會員 發表:21 回覆:19 積分:23 註冊:2005-01-18 發送簡訊給我 |
|
dragonhippopdc
一般會員 發表:45 回覆:51 積分:19 註冊:2005-01-15 發送簡訊給我 |
bool Frame2TImage (PAVISTREAM *gapavi,AVISTREAMINFO *avis,long miniSecond,TImage *Image1) { PGETFRAME gapgf; // GetFrame物件 //5. 對指定的 gapavi video stream 進行解壓縮,傳回 GetFrame物件放在gapgf中 if (avis->fccType == streamtypeVIDEO) { gapgf = AVIStreamGetFrameOpen(*gapavi, NULL); if (gapgf == NULL) return false; } //6. 對指定的時間(2th) 計算相對應的frame LONG lFrame; lFrame = AVIStreamTimeToSample(*gapavi, miniSecond); if(!(lFrame>=AVIStreamStart(*gapavi) && lFrame我將這這個部分改成你所說的這樣~不過還是會慢慢吃掉記憶體~大概兩三秒吃掉一m左右~請問是我有改錯嗎~請大大再賜教一下~謝謝你 |
u9012021
一般會員 發表:21 回覆:19 積分:23 註冊:2005-01-18 發送簡訊給我 |
您好!
測試你的程式發現~~下面這段程式有問題~~把這段程式移除測試~~記憶體不會有增加的現象~~你要判斷影片是否結束的判斷式可以用avis的資訊來判斷~~不一定要寫在函式內!!
if(!(lFrame>=AVIStreamStart(*gapavi) && lFrame如果沒移除這一行~~程式好像每兩三秒就增加1K的記憶體~~並沒有像你說的每兩三秒增加1M左右~~你是否打錯字了@@ |
dragonhippopdc
一般會員 發表:45 回覆:51 積分:19 註冊:2005-01-15 發送簡訊給我 |
|
u9012021
一般會員 發表:21 回覆:19 積分:23 註冊:2005-01-18 發送簡訊給我 |
|
dragonhippopdc
一般會員 發表:45 回覆:51 積分:19 註冊:2005-01-15 發送簡訊給我 |
|
dragonhippopdc
一般會員 發表:45 回覆:51 積分:19 註冊:2005-01-15 發送簡訊給我 |
|
u9012021
一般會員 發表:21 回覆:19 積分:23 註冊:2005-01-18 發送簡訊給我 |
|
dragonhippopdc
一般會員 發表:45 回覆:51 積分:19 註冊:2005-01-15 發送簡訊給我 |
你好~我後來從xp記憶體管理去看也是一樣~大約兩到三秒就少了一m~還是說我跟你的設定是不一樣的所以看起來不太一樣呢~我讀的檔案是大約兩分鐘~我的timer是設1000然後timer的內部是寫這樣
void __fastcall TForm1::Timer1Timer(TObject *Sender) { //Frame2TImage(&gapavi,&avis,Counter,Image1); Frame2TImage(&gapavi,&avis,Counter,Image1); Counter = 30 * (1000 / 30); //假設AVI一秒30Frames } //-------------------------------------------------------------------讓它一秒只顯示一個frame~還有大大你說的這個方式該如何做呢~因我是一秒只要一個frame~如果這個avi檔是一秒三十個frame那我是其他都不要~那這樣有辦法用你所說的~你可以由avis.dwLength知道整段AVI可以分成多少個Frame!~來做判斷嗎 |
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
dragonhippopdc 您好: 我做了些測試後將程式修改了一下,我手邊僅有較小的 AVI 檔案,測試結果是 OK 啦,您試試看吧:
bool Frame2TImage (PAVISTREAM *gapavi,AVISTREAMINFO *avis,long miniSecond,TImage *Image1) { PGETFRAME gapgf; // GetFrame物件 //5. 對指定的 gapavi video stream 進行解壓縮,傳回 GetFrame物件放在gapgf中 if (avis->fccType == streamtypeVIDEO) { gapgf = AVIStreamGetFrameOpen(*gapavi, NULL); if (gapgf == NULL) return false; } //6. 對指定的時間(2th) 計算相對應的frame LONG lFrame; lFrame = AVIStreamTimeToSample(*gapavi, miniSecond); if (!(lFrame>=AVIStreamStart(*gapavi) && lFrame紅色標示的部份為我修改過的地方,請特別留意一下 DC 的釋放。 7 天天敲鍵盤 v 時時按滑鼠 8 |
wccheng
一般會員 發表:5 回覆:4 積分:1 註冊:2005-06-11 發送簡訊給我 |
|
u9012021
一般會員 發表:21 回覆:19 積分:23 註冊:2005-01-18 發送簡訊給我 |
引言: 你好~我後來從xp記憶體管理去看也是一樣~大約兩到三秒就少了一m~還是說我跟你的設定是不一樣的所以看起來不太一樣呢~我讀的檔案是大約兩分鐘~我的timer是設1000然後timer的內部是寫這樣您好! 我是用Timer去控制播放速度~~你可以上傳你讀取的AVI檔嗎~~正常來說應該都可以抓的到你的Frame總數!void __fastcall TForm1::Timer1Timer(TObject *Sender) { //Frame2TImage(&gapavi,&avis,Counter,Image1); Frame2TImage(&gapavi,&avis,Counter,Image1); Counter = 30 * (1000 / 30); //假設AVI一秒30Frames } //-------------------------------------------------------------------讓它一秒只顯示一個frame~還有大大你說的這個方式該如何做呢~因我是一秒只要一個frame~如果這個avi檔是一秒三十個frame那我是其他都不要~那這樣有辦法用你所說的~你可以由avis.dwLength知道整段AVI可以分成多少個Frame!~來做判斷嗎 lpbi = (LPBITMAPINFOHEADER)AVIStreamGetFrame(gapgf,lFrame );lFrame就是控制你要抓整段AVI檔的第幾個Frame 例如說你傳入avis.dwLeng的值給它~他應該會抓到你AVI影片的最後一張Frame!! |
dragonhippopdc
一般會員 發表:45 回覆:51 積分:19 註冊:2005-01-15 發送簡訊給我 |
|
dragonhippopdc
一般會員 發表:45 回覆:51 積分:19 註冊:2005-01-15 發送簡訊給我 |
各位大大~目前現在是改成這樣可是好像還是會有問題~真是怪ㄟ
bool GetVideoStream(char *szFile,PAVISTREAM *gapavi,AVISTREAMINFO *avis) { //1 Initial the AVI library AVIFileInit(); //2 Open an AVI-file HRESULT hr; PAVIFILE pfile; // 讀取avi檔案 hr = AVIFileOpen(&pfile,szFile , 0, 0L); if (hr != 0) { return false; } //3 Getting an AVI stream //PAVISTREAM gapavi; // for storage the frames of AVI int gcpavi; AVIFileGetStream(pfile, gapavi, 0L, 0); // 把得到的 Stream interface放在gapavi中 //4. Get the stream information //AVISTREAMINFO avis; AVICOMPRESSOPTIONS gaAVIOptions; LPAVICOMPRESSOPTIONS galpAVIOptions; // Stream header的資訊放在 avis中 AVIStreamInfo(*gapavi, avis, sizeof(*avis)); galpAVIOptions = &gaAVIOptions; // 把 gaAVIOptions的內容清為0 _fmemset(galpAVIOptions, 0, sizeof(AVICOMPRESSOPTIONS)); // 取出該 stream 的多媒體型態放在相對應的gaAVIOptions陣列中 galpAVIOptions->fccType = avis->fccType; switch(avis->fccType) { case streamtypeVIDEO: galpAVIOptions->dwFlags = AVICOMPRESSF_VALID | AVICOMPRESSF_KEYFRAMES | AVICOMPRESSF_DATARATE; galpAVIOptions->fccHandler = 0; galpAVIOptions->dwQuality = (DWORD)ICQUALITY_DEFAULT; galpAVIOptions->dwKeyFrameEvery = (DWORD)-1; // Default galpAVIOptions->dwBytesPerSecond = 0; galpAVIOptions->dwInterleaveEvery = 1; break; default: break; } pfile->Release(); AVIFileExit(); return true; } //--------------------------------------------------------- bool HBITMAP2TImage(HBITMAP hBitmap,TImage *Image1) { BITMAP bitmap; Graphics::TBitmap *Bitmap1=new Graphics::TBitmap(); Bitmap1->Handle=hBitmap; // 取得 Bmp 的 Width & Height GetObject(hBitmap,sizeof(BITMAP),&bitmap); Image1->Width=bitmap.bmWidth; Image1->Height=bitmap.bmHeight; // 把 Bitmap 畫在 Image1上 Image1->Canvas->Draw(0,0,Bitmap1); delete Bitmap1; //Image1->Visible=true; //Image1->Repaint(); DeleteObject(hBitmap); return true; } //------------------------------------------------------------------- bool Frame2TImage (PAVISTREAM *gapavi,AVISTREAMINFO *avis,long miniSecond,TImage *Image1) { PGETFRAME gapgf; // GetFrame物件 //5. 對指定的 gapavi video stream 進行解壓縮,傳回 GetFrame物件放在gapgf中 if (avis->fccType == streamtypeVIDEO) { gapgf = AVIStreamGetFrameOpen(*gapavi, NULL); if (gapgf == NULL) return false; } //6. 對指定的時間(2th) 計算相對應的frame LONG lFrame; lFrame = AVIStreamTimeToSample(*gapavi, miniSecond); if(!(lFrame>=AVIStreamStart(*gapavi) && lFrame不過還是會有吃記憶體的現象~請問各位大大為何會這樣~ |
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
dragonhippopdc 您好: 請不要一邊要求他人協助解決問題,卻又一邊將程式改成與主題無關的狀態,或是插入與發問原型無關的程式敘述,您要新增功能到程式裡邊,那是另外的事情,請不要在眾人設法協助您解決問題之時,將問題複雜化。 您這次貼上來的程式碼,在 Timer 程序中加入了一大段的圖像處理動作,但是卻未將相關宣告與設定列出來,而且 new 了 TBitmap 卻又沒 delete 掉,記憶體為何不會漸漸被吃光?請您說說看您到底是在協助眾人瞭解問題,以解決 "記憶體吃光" 的問題,還是在製造新的問題? 請調整一下您的作法,否則眾人提供的協助難以追上您製造問題的速度。 7 天天敲鍵盤 v 時時按滑鼠 8
|
dragonhippopdc
一般會員 發表:45 回覆:51 積分:19 註冊:2005-01-15 發送簡訊給我 |
|
taishyang
站務副站長 發表:377 回覆:5490 積分:4563 註冊:2002-10-08 發送簡訊給我 |
dragonhippopdc您好:
引言:至於大大你說的那個未刪除的那個 new 了 TBitmap 卻又沒 delete 掉~因為我是用它來將image1被我存到陣列中的值再重新貼到image2上~所以如果刪掉了~那這樣圖不是就顯示不出來了嗎~還是說有其他的方可以將他delete掉呢我不懂,您已經在http://www.programmer-club.com/pc2020v5/forum/ShowSameTitleN.asp?URL=N&board_pc2020=cb&index=26&id=9713&mode=&type_pc2020=sametitleLevel-2 問過同樣的問題了,且victortom(鬼翼@娃娃魚) 前輩不是也告訴您答案了嗎? 引言: 在Form的Header或者全域變數....宣告Graphics::TBitmap *preFrame; 然後看是在Form的建構子或開AVI時.... preFrame = new Graphics::TBitmap; Timer1Timer() { ....影像相減or其他的處理.... preFrame->Assign(Image1->Picture->Bitmap); } 要更保險一點, 在Assign()前先設定一下.... preFrame->Height = Image1->Picture->Bitmap->Height; preFrame->Width = Image1->Picture->Bitmap->Width; 不過印象中, 應該不設定也不會有問題啦@_@"最後, Form的Destory或解構子的地方.... preFrame先前new過就要delete掉.... new出來的東西記得要在適當的地方delete.... |
arisaka_matsuri
高階會員 發表:25 回覆:205 積分:231 註冊:2003-10-19 發送簡訊給我 |
引言: 我不懂,您已經在http://www.programmer-club.com/pc2020v5/forum/ShowSameTitleN.asp?URL=N&board_pc2020=cb&index=26&id=9713&mode=&type_pc2020=sametitleLevel-2 問過同樣的問題了,且victortom(鬼翼@娃娃魚) 前輩不是也告訴您答案了嗎?副站還真是厲害~ 好久沒看xx了,我是路人,呵呵~^^ |
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
dragonhippopdc 您好: 您多加了一段程式碼,而該段程序導致了新的記憶體流失問題 (雖然您沒看出來),但是您卻將這種結果歸於他人的建議未解決您原來的問題,這種作法是不妥的,這不但對解決問題沒有幫助,而且也會把您自己搞迷糊了,我個人覺得您應該要在解決問題的過程中,儘量的將有問題的程式過濾、簡化掉,而不是將它膨脹、複雜化。 建議您將新增的部份暫時移除掉,以 "原樣" 配合大家的建議來做修改與測試,並且將測試的結果做個說明,讓提出建議的諸位熱心人知道他們的建議到底是不是解決了您的問題? 您新增的部份以及您前一篇對該段的解說,存在著一些問題與誤區,您可以另開一題來發問,這樣可以讓問題單純些。 7 天天敲鍵盤 v 時時按滑鼠 8
|
dragonhippopdc
一般會員 發表:45 回覆:51 積分:19 註冊:2005-01-15 發送簡訊給我 |
RedSnow大大你好~我將多加的部份拿掉變成以下這樣然後我讀一個兩分鐘的avi檔~我的timer是設1000大約吃掉十m左右~真的是我多加的那段的問題~對各位大大說聲抱歉~現在沒吃的那麼多了~請問吃十m這樣算是正常的嗎?
TForm1 *Form1; int i=0; bool Frame2TImage(PAVISTREAM *gapavi,AVISTREAMINFO *avis,long miniSecond,TImage *Image1);// 從影像串流中取出相對應時間的Frame, 並秀在指定TImage的Canvas 上 bool GetVideoStream(char *szFile,PAVISTREAM *gapavi,AVISTREAMINFO *avis); // 由 AVI 檔中取出影像串流 //(DWORD)ICQUALITY_DEFAULT; PAVISTREAM gapavi; AVISTREAMINFO avis; static long Counter = 0; bool GetVideoStream(char *szFile,PAVISTREAM *gapavi,AVISTREAMINFO *avis) { //1 Initial the AVI library AVIFileInit(); //2 Open an AVI-file HRESULT hr; PAVIFILE pfile; // 讀取avi檔案 hr = AVIFileOpen(&pfile,szFile , 0, 0L); if (hr != 0) { return false; } //3 Getting an AVI stream //PAVISTREAM gapavi; // for storage the frames of AVI int gcpavi; AVIFileGetStream(pfile, gapavi, 0L, 0); // 把得到的 Stream interface放在gapavi中 //4. Get the stream information //AVISTREAMINFO avis; AVICOMPRESSOPTIONS gaAVIOptions; LPAVICOMPRESSOPTIONS galpAVIOptions; // Stream header的資訊放在 avis中 AVIStreamInfo(*gapavi, avis, sizeof(*avis)); galpAVIOptions = &gaAVIOptions; // 把 gaAVIOptions的內容清為0 _fmemset(galpAVIOptions, 0, sizeof(AVICOMPRESSOPTIONS)); // 取出該 stream 的多媒體型態放在相對應的gaAVIOptions陣列中 galpAVIOptions->fccType = avis->fccType; switch(avis->fccType) { case streamtypeVIDEO: galpAVIOptions->dwFlags = AVICOMPRESSF_VALID | AVICOMPRESSF_KEYFRAMES | AVICOMPRESSF_DATARATE; galpAVIOptions->fccHandler = 0; galpAVIOptions->dwQuality = (DWORD)ICQUALITY_DEFAULT; galpAVIOptions->dwKeyFrameEvery = (DWORD)-1; // Default galpAVIOptions->dwBytesPerSecond = 0; galpAVIOptions->dwInterleaveEvery = 1; break; default: break; } pfile->Release(); AVIFileExit(); return true; } //--------------------------------------------------------- bool HBITMAP2TImage(HBITMAP hBitmap,TImage *Image1) { BITMAP bitmap; Graphics::TBitmap *Bitmap1=new Graphics::TBitmap(); Bitmap1->Handle=hBitmap; // 取得 Bmp 的 Width & Height GetObject(hBitmap,sizeof(BITMAP),&bitmap); Image1->Width=bitmap.bmWidth; Image1->Height=bitmap.bmHeight; // 把 Bitmap 畫在 Image1上 Image1->Canvas->Draw(0,0,Bitmap1); delete Bitmap1; //Image1->Visible=true; //Image1->Repaint(); DeleteObject(hBitmap); return true; } //--------------------------------------------------------------------------- bool Frame2TImage (PAVISTREAM *gapavi,AVISTREAMINFO *avis,long miniSecond,TImage *Image1) { PGETFRAME gapgf; // GetFrame物件 //5. 對指定的 gapavi video stream 進行解壓縮,傳回 GetFrame物件放在gapgf中 if (avis->fccType == streamtypeVIDEO) { gapgf = AVIStreamGetFrameOpen(*gapavi, NULL); if (gapgf == NULL) return false; } //6. 對指定的時間(2th) 計算相對應的frame LONG lFrame; lFrame = AVIStreamTimeToSample(*gapavi, miniSecond); if(!(lFrame>=AVIStreamStart(*gapavi) && lFrame |
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
dragonhippopdc 您好: 我測試過後與我原先測的結果差不多,但是您竟然會有吃掉 10MB 的問題?因此我猜想可能是您對記憶體佔用與流失的認知上有誤區,您看到的大概是那個兩分鐘的 avi 檔案被載入後所佔用的空間變化,您可以換個方式來測試您的程式:另設一個按鈕作重播的動作,例如:
void __fastcall TForm1::Button3Click(TObject *Sender) { Timer1->Enabled = true; Button13->Enabled = false; Counter = 0; }同時您也可以將 ShowMessage("Over !"); 改成 Button13->Enabled = true,以方便操作。 當您第一次使用 Button1 載入檔案併播放完畢之後,請透過工作管理員查看您的程式佔用記憶體的狀態,然後點點擊上述新增按鈕,重複播放 avi 數次,每次都記下記憶體佔用情形,這樣子應該就可以瞭解記憶體是被佔用還是流失掉了,程式佔用記憶體是正常的,程式結束 (或程序結束、或呼叫釋放函數) 後可以正常釋回就 OK 了,但若有流失的情形,那就要抓出臭蟲,然後幹掉它! 7 天天敲鍵盤 v 時時按滑鼠 8 發表人 - RedSnow 於 2005/06/17 12:42:41 |
dragonhippopdc
一般會員 發表:45 回覆:51 積分:19 註冊:2005-01-15 發送簡訊給我 |
|
RedSnow
版主 發表:79 回覆:1322 積分:845 註冊:2003-12-15 發送簡訊給我 |
|
wccheng
一般會員 發表:5 回覆:4 積分:1 註冊:2005-06-11 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |