Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Snorky

Frischling

  • »Snorky« ist der Autor dieses Themas

Beiträge: 34

Wohnort: Berlin

Beruf: Student

  • Private Nachricht senden

1

23.08.2003, 22:46

tbVideo mit Speicherleck und gelegentlichem Abbruch

Tja, diesmal komme ich einfach nicht weiter. :crying:
Wenn man sich die tbVideo-Struktur etwas genauer ansieht, stellt man fest, dass es einen Pointer gibt

Quellcode

1
    IBaseFilter*    m_pRenderer;

der zwar in

Quellcode

1
2
3
4
5
tbResult tbVideo::Init(char* pcFilename)
{
    // Neuen Video-Renderer erstellen
    m_pRenderer = new tbVideoRenderer(NULL, &r);
}

belegt, aber nirgends mehr freigegeben wird. Naja, man denkt sich natürlich, easy, hauen wir mal

Quellcode

1
    TB_SAFE_DELETE(m_pRenderer);

in den Destruktor. Zu dumm, denn dann kommt bei mir immer ein merkwürdiger Assert-Fehler. Hm, ok schaun wir mal ein bischen genauer in die Init und man überlege sich, wenn ich einen Filter irgendwo setze, dann könnte man ihn vielleicht auch wieder irgendwo rausnehmen. Vielleicht mit sowas wie

Quellcode

1
2
    if(m_pGraph != NULL && m_pRenderer != NULL)
        m_pGraph->RemoveFilter(m_pRenderer);

aber irgendwie hilft das auch nicht. Mal schauen, was tbMusic dazu sagt, aber da gibts das Problem nicht, bzw. ist es mir noch nicht aufgefallen. Alles wieder rückgängig und mit dem Speicherleck leben ist auch nicht das Wahre. Mal abgesehen davon, dass bei einem wiederholten initiieren des Videos es zu einem Abbruch kommen kann. Soll heißen, wenn man ein g_pVideo mit Speicher belegt, das Video abspielt, wieder freigibt und dann erneut mit Speicher belegt und initiiert, bricht das Programm manchmal ab, nicht immer aber immer öfter. Ich hab den Fehler jetzt schon auf die folgende Zeile zurückgeführt:

Quellcode

1
    if(FAILED(r = m_pGraph->Render(pSrcFilterOut)))

Es kommt hier oder vorher zu keinem Fehler, nur mit Debugausgaben konnte ich feststellen, dass er beim zweiten Mal Init bis zu dieser Zeile kommt und nicht weiter. Sehr ärgerlich das Ganze :angry: vorallem weil ich es nicht hinbekomme ;(
Aber vielleicht hat ja Jemand hier noch Ideen und möchte sich an das Problem probieren? Ansonsten heißt es wohl warten, bis David wieder aus dem Urlaub zurück ist. Hach ja Urlaub, das wäre jetzt genau das Richtige für mich ;D

Jens

Treue Seele

Beiträge: 117

Wohnort: Dresden

  • Private Nachricht senden

2

24.08.2003, 12:26

Assert bei SAFE_DELETE

ich habe mich, ehrlich gesagt, noch nicht mit dem Videorendern beschäftigt, aber was sagt denn die ASSERT-Meldung?
Etwa, dass ein Referenz-Zähler noch nicht den Wert 0 oder 1 erreicht hat?
Dann könnte es doch sein, dass zuerst RemoveFilter und dann SAFE_DELETE aufgerufen werden müsste.
Aber da wärst Du sicher alleine dahintergekommen... :rolleyes:

Vielleicht hilft Dir das DirectShow-Sample Texture3D weiter.
Dort ist "m_pRenderer" auf einen SmartPointer gelegt worden. Da der Smartpointer lokal ist, wird er sicher nach Abschlus der Funktion Init wieder freigegeben. Das könnte bedeuten, dass sich der Graph selbst um die Zerstörung der hinzugefügten Filter kümmert.

Snorky

Frischling

  • »Snorky« ist der Autor dieses Themas

Beiträge: 34

Wohnort: Berlin

Beruf: Student

  • Private Nachricht senden

3

24.08.2003, 17:10

Jo, das habe ich ja auch versucht, sobald ich aber den Speicher mit safedelete freigebe kommt der Assertfehler, egal ob ich den Filter vorher rausnehme, oder nicht. Ich kenne mich mit Asserts nicht sonderlich aus, aber ich vermute, dass das Problem vom Pointertyp stammt.
m_pRenderer ist vom Typ IBaseFilter*, allerdings wird ihm Speicher vom Typ tbVideoRenderer zugewiesen. Also habe ich mal den Speicher beim freigeben auch wieder ins richtige Format gecastet

Quellcode

1
2
    if(m_pRenderer != NULL) delete ((tbVideoRenderer*)m_pRenderer);
    m_pRenderer = NULL;

(mit Macro gings irgendwie nicht) und siehe da, es kommt kein Assertfehler mehr. :) Allerdings bricht das Programm trotzdem sofort ab. :( Also schaue ich mir den Destruktor von tbVideoRenderer an. Sieht ja alles sauber aus, trotzdem mit ein paar Debugausgaben bestückt und ich stelle fest, dass der Destruktor schon direkt nach dem Aufruf von RemoveFilter aufgerufen wird. Hmm, ok, wird schon so seine Berechtigung haben, wenn er beim removen des Filters den auch gleich löscht, naja, also sollte man den Speicher von m_pRenderer nicht erneut freigeben, sondern gleich danach auf NULL setzen. ;( Nun stehe ich aber wieder am Anfang der Probleme, es kommt kein Assertfehler und das Programm bricht trotzdem ab und zu ab, wenn er das Video neu initialisieren soll.
:rolleyes:

Snorky

Frischling

  • »Snorky« ist der Autor dieses Themas

Beiträge: 34

Wohnort: Berlin

Beruf: Student

  • Private Nachricht senden

4

14.09.2003, 18:44

Hallo David,
kann ich Deine Aufmerksamkeit vielleicht auf dieses tbVideo-Problem lenken? :help:
Sieht nicht so aus, als ob mir hier andere Forenbesucher weiterhelfen können. Möglicherweise hast Du eine Idee oder womöglich schon eine Lösung parat?
Gruß

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

5

14.09.2003, 18:59

Mir ist das Problem bisher nicht aufgefallen...
Man muss aber auch sagen, dass es mit DirectShow oft Probleme gibt, auch bei kommerziellen Anwendungen. Ich werde aber mal sehen, was ich tun kann.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

6

14.09.2003, 19:06

Also, wenn ich folgende Zeile zum tbVideo-Destruktor hinzufüge:

TB_SAFE_DELETE(m_pRenderer);

Dann klappt es, zumindest bei mir.
Es kommt keine Fehlermeldung.

Anonymous

unregistriert

7

14.09.2003, 21:31

Muss es nicht TB_SAFE_RELEASE heißen?

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

8

14.09.2003, 21:32

Hatte ich erst auch gedacht, aber dann gab's eine Fehlermeldung. Ich steige da auch nicht durch.

Snorky

Frischling

  • »Snorky« ist der Autor dieses Themas

Beiträge: 34

Wohnort: Berlin

Beruf: Student

  • Private Nachricht senden

9

14.09.2003, 22:53

Sehr verwirrend alles.
TB_SAFE_RELEASE bricht bei mir ab (tbExit wird automatisch aufgerufen) und TB_SAFE_DELETE bringt besagten Assert-Fehler:
Debug Assertion Failed!
Program: bla.exe
File: dbgheap.c
Line: 1132
Expression: _CrtIsValidHeapPointer(pUserData)
Blabla

Was auch ein möglicher Fehlergrund sein kann, ist dass m_pRenderer vom Typ IBaseFilter ist, aber Speicher der Form tbVideoRenderer zugewiesen bekommt. Vielleicht kommt er deswegen nicht klar.
Etwas anderes wäre das Entfernen des Filters. Aber wie schon beschrieben ruft RemoveFilter(), wenn man den Aufruf einfügt, den Destruktor von tbVideoRenderer auf, was ja auch schon etwas wert ist, nur für mich etwas unlogisch klingt. Na ich glaube hier stimmt sowieso etwas überhaupt nicht. :ohoh:

Anonymous

unregistriert

10

17.09.2003, 12:24

kann es sein das ihr speicher von der dll aus anlegt und aus dem hauptprogramm löscht?

Werbeanzeige