From 764e9f7c32994c949a6e3b95c763235a39bacf9d Mon Sep 17 00:00:00 2001
From: Mike Boers <github@mikeboers.com>
Date: Tue, 29 Oct 2013 13:17:53 -0700
Subject: [PATCH 1/2] Demonstrate that circular references aren't collected.

---
 examples/dealloc.py | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)
 create mode 100644 examples/dealloc.py

diff --git a/examples/dealloc.py b/examples/dealloc.py
new file mode 100644
index 0000000..eed050a
--- /dev/null
+++ b/examples/dealloc.py
@@ -0,0 +1,39 @@
+import resource
+import sys
+
+import av
+
+path = sys.argv[1] if len(sys.argv) > 1 else 'sandbox/640x360.mp4'
+DELINK = True
+
+
+_last_rss = 0
+def report():
+    global _last_rss
+    current = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
+    print '%d %d' % (current - _last_rss, current)
+    _last_rss = current
+
+
+print 'GLOBAL'
+print '========='
+for i in xrange(10):
+    report() 
+    container = av.open(path)
+    codec = container.streams[0].codec
+    if DELINK:
+        container.streams[:] = []
+    del container, codec
+print
+
+def local():
+    print 'LOCAL'
+    print '========='
+    for i in xrange(10):
+        report() 
+        container = av.open(path)
+        codec = container.streams[0].codec
+        if DELINK:
+            container.streams[:] = []
+        del container, codec
+local()
-- 
GitLab


From d4dede171b089f1d62d4cb47221de4c1387f55e7 Mon Sep 17 00:00:00 2001
From: Mike Boers <github@mikeboers.com>
Date: Tue, 29 Oct 2013 13:23:26 -0700
Subject: [PATCH 2/2] Stream and Codec hold onto ContextProxy

This never forms circular references.
---
 .gitignore          | 11 +++++++++++
 av/codec.pyx        |  2 +-
 av/format.pxd       |  2 +-
 av/format.pyx       |  4 ++--
 examples/dealloc.py |  2 +-
 5 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/.gitignore b/.gitignore
index f5e2457..512349b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,17 @@
 .DS_Store
 /venv
 /vendor
+/bin
+/include
+/lib
+
+# Autoconf.
+/autom4te.cache
+/config.py
+/config.log
+/config.status
+/configure
+>>>>>>> Stream and Codec hold onto ContextProxy
 
 # Build products.
 /build
diff --git a/av/codec.pyx b/av/codec.pyx
index 132cb32..b8be4fb 100644
--- a/av/codec.pyx
+++ b/av/codec.pyx
@@ -16,7 +16,7 @@ cdef class Codec(object):
         self.ctx = stream.ptr.codec
         
         # Keep these pointer alive with this reference.
-        self.format_ctx = stream.ctx.proxy
+        self.format_ctx = stream.ctx
         
         if stream.type == 'attachment':
             return
diff --git a/av/format.pxd b/av/format.pxd
index 7fea22f..56ebae1 100644
--- a/av/format.pxd
+++ b/av/format.pxd
@@ -37,7 +37,7 @@ cdef class Stream(object):
     
     cdef readonly bytes type
     
-    cdef Context ctx
+    cdef ContextProxy ctx
     
     cdef lib.AVStream *ptr
     
diff --git a/av/format.pyx b/av/format.pyx
index ef0e522..641132b 100644
--- a/av/format.pyx
+++ b/av/format.pyx
@@ -293,8 +293,8 @@ cdef class Stream(object):
         if index < 0 or index > ctx.proxy.ptr.nb_streams:
             raise ValueError('stream index out of range')
         
-        self.ctx = ctx
-        self.ptr = self.ctx.proxy.ptr.streams[index]
+        self.ctx = ctx.proxy
+        self.ptr = self.ctx.ptr.streams[index]
         self.type = type
 
         self.codec = av.codec.Codec(self)
diff --git a/examples/dealloc.py b/examples/dealloc.py
index eed050a..b2f5c99 100644
--- a/examples/dealloc.py
+++ b/examples/dealloc.py
@@ -4,7 +4,7 @@ import sys
 import av
 
 path = sys.argv[1] if len(sys.argv) > 1 else 'sandbox/640x360.mp4'
-DELINK = True
+DELINK = False
 
 
 _last_rss = 0
-- 
GitLab