Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>When converted to compilable code by adding enough pseudo-infrastructure to simulate the GST system, GCC comes up with a warning that's almost surely the source of your trouble:</p> <pre><code>gstq.c: In function ‘dequeue_gstbuffer’: gstq.c:73:12: warning: ‘nextPtr’ is used uninitialized in this function [-Wuninitialized] </code></pre> <p>The lines are:</p> <pre><code>72 GstBufferQueue **nextPtr; 73 *nextPtr = (*head)-&gt;next; </code></pre> <p>On these lines, you need:</p> <pre><code>GstBufferQueue *nextPtr = (*head)-&gt;next; </code></pre> <p>You also need to use:</p> <pre><code>(*head)-&gt;next = nextPtr; </code></pre> <p>Pay attention to your compiler warnings. If your compiler doesn't warn, make it do so. If you can't make it warn, get a better compiler.</p> <hr> <h3>SSCCE</h3> <pre><code>#include &lt;stdlib.h&gt; #include &lt;stdio.h&gt; #include &lt;assert.h&gt; #define GST_BUFFER_SIZE(x) sizeof(x) #define GST_WARNING(x) fprintf(stderr, "%s\n", x) typedef struct GstBuffer { int value; } GstBuffer; typedef unsigned int guint; static GstBuffer *gst_buffer_try_new_and_alloc(int size) { GstBuffer *buf = malloc(sizeof(GstBuffer)); assert(buf != 0); buf-&gt;value = size; return buf; } static GstBuffer *gst_buffer_copy(const GstBuffer *buf) { GstBuffer *new_buf = malloc(sizeof(GstBuffer)); assert(new_buf != 0); new_buf-&gt;value = buf-&gt;value; return new_buf; } static void gst_buffer_unref(GstBuffer *buf) { buf-&gt;value = -1; } typedef struct _GstBUFFERQUEUE GstBufferQueue; struct _GstBUFFERQUEUE { GstBuffer *buf; guint buf_size; struct _GstBUFFERQUEUE *next; }; extern void enqueue_gstbuffer(GstBufferQueue **head, GstBufferQueue **tail, guint *queue_size, GstBuffer *buf); extern void dequeue_gstbuffer(GstBufferQueue **head, GstBufferQueue **tail, guint *queue_size, GstBuffer **buf); void enqueue_gstbuffer(GstBufferQueue **head, GstBufferQueue **tail, guint *queue_size, GstBuffer *buf) { if (*queue_size == 0) { *head = malloc(sizeof(GstBufferQueue)); (*head)-&gt;buf = gst_buffer_try_new_and_alloc(GST_BUFFER_SIZE(buf)); (*head)-&gt;buf = gst_buffer_copy(buf); *tail = *head; } else { if (((*tail)-&gt;next = malloc(sizeof(GstBufferQueue))) != 0) { (*tail)-&gt;next-&gt;buf = gst_buffer_try_new_and_alloc(GST_BUFFER_SIZE(buf)); (*tail)-&gt;next-&gt;buf = gst_buffer_copy(buf); (*tail) = (*tail)-&gt;next; } else { GST_WARNING("Error allocating memory for new buffer in queue"); } } (*tail)-&gt;next = NULL; (*queue_size)++; } void dequeue_gstbuffer(GstBufferQueue **head, GstBufferQueue **tail, guint *queue_size, GstBuffer **buf) { GstBufferQueue **tmpPtr = head; GstBufferQueue *nextPtr; nextPtr = (*head)-&gt;next; *buf = gst_buffer_try_new_and_alloc (GST_BUFFER_SIZE((*tmpPtr)-&gt;buf)); *buf = gst_buffer_copy((*tmpPtr)-&gt;buf); gst_buffer_unref((*tmpPtr)-&gt;buf); free((*tmpPtr)); *head = nextPtr; if ((*head) == NULL) (*tail) = NULL; (*queue_size)--; } int main(void) { GstBufferQueue *q_head = 0; GstBufferQueue *q_tail = 0; guint q_size = 0; for (int i = 0; i &lt; 10; i++) { GstBuffer *buf = gst_buffer_try_new_and_alloc(i + 100); enqueue_gstbuffer(&amp;q_head, &amp;q_tail, &amp;q_size, buf); printf("EQ: %d\n", buf-&gt;value); free(buf); if (i % 2 == 1) { GstBuffer *buf; dequeue_gstbuffer(&amp;q_head, &amp;q_tail, &amp;q_size, &amp;buf); printf("DQ: %d\n", buf-&gt;value); free(buf); } } while (q_size &gt; 0) { GstBuffer *buf; dequeue_gstbuffer(&amp;q_head, &amp;q_tail, &amp;q_size, &amp;buf); printf("DQ: %d\n", buf-&gt;value); free(buf); } printf("All done\n"); return(0); } </code></pre> <h3>Output</h3> <pre><code>EQ: 100 EQ: 101 DQ: 100 EQ: 102 EQ: 103 DQ: 101 EQ: 104 EQ: 105 DQ: 102 EQ: 106 EQ: 107 DQ: 103 EQ: 108 EQ: 109 DQ: 104 DQ: 105 DQ: 106 DQ: 107 DQ: 108 DQ: 109 All done </code></pre> <p>Note that the SSCCE code above leaks worse than a sieve. I've no plans to fix the leakages because they're in the code that simulates GST buffer management. Do check that your code does not suffer from the memory leaks.</p> <hr> <p>I think you should be packaging your 'queue' differently. What you call a <code>GstBufferQueue</code> should really be a <code>GstBufferQueueItem</code>, and your actual <code>GstBufferQueue</code> should contain the head and tail pointers, and the size. You'd pass a pointer to the (revised) <code>GstBufferQueue</code> to the <code>enqueue_gstbuffer()</code> and <code>dequeue_gstbuffer()</code> functions, instead of passing 3 separate parameters.</p> <pre><code>typedef struct GstBufferQueueItem GstBufferQueueItem; struct GstBufferQueueItem { GstBuffer *buf; guint buf_size; GstBufferQueueItem *next; }; typedef struct GstBufferQueue GstBufferQueue; struct GstBufferQueue { GstBufferQueueItem *head; GstBufferQueueItem *tail; guint size; }; // Uncompiled - but to give you an idea void dequeue_gstbuffer(GstBufferQueue *q, GstBuffer **buf) { GstBufferQueueItem *item = q-&gt;head; GstBufferQueueItem *next = item-&gt;next; *buf = gst_buffer_try_new_and_alloc(GST_BUFFER_SIZE(item-&gt;buf)); *buf = gst_buffer_copy(item-&gt;buf); gst_buffer_unref(item-&gt;buf); free(item); q-&gt;head = next; if (q-&gt;head == NULL) q-&gt;tail = NULL; q-&gt;size--; } </code></pre> <p>Note that these names avoid a leading underscore. Such names are dangerous. Names with underscore and an upper-case letter are reserved for the implementation for any purpose. Names with an underscore and a lower-case letter are reserved with different words, but using either is dodgy (and although the standards say little about underscore and a digit, don't play games with them — treat leading underscore as 'reserved for the system' unless you're writing 'the system').</p> <h3>ISO/IEC 9899:2011 §7.1.3 Reserved identifiers</h3> <blockquote> <ul> <li>All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.</li> <li>All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces.</li> </ul> </blockquote>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload