From: David Flynn <[email protected]>

There is a timelag between receiving an EOS at the input to the
decoder and the decoder state producing EOS.  In that time, it
would be nice if a user can continue to push data to the decoder.

This patch implements this.

NB, this patch does not implement any threaded decoding on
the subsequent sequence, only the parsing functions

includes:
 - decoder: delete all decoder instances at cleanup
 - decoder: add new instance at end of instance list
 - decoder: add new instance on push_end_of_stream

Signed-off-by: David Flynn <[email protected]>
---
 schroedinger/schrodecoder.c |   65 +++++++++++++++++++++++++++++++++++++++---
 schroedinger/schrodecoder.h |    6 ++++
 2 files changed, 66 insertions(+), 5 deletions(-)

diff --git a/schroedinger/schrodecoder.c b/schroedinger/schrodecoder.c
index 6f6c7ee..ec1138c 100644
--- a/schroedinger/schrodecoder.c
+++ b/schroedinger/schrodecoder.c
@@ -127,6 +127,7 @@ schro_decoder_instance_free (SchroDecoderInstance *instance)
     schro_buffer_unref (instance->sequence_header_buffer);
   }
 
+  /* DO NOT instance_free(instance->next), must be handled by caller if 
required */
   schro_free (instance);
 }
 
@@ -204,7 +205,11 @@ schro_decoder_free (SchroDecoder *decoder)
     schro_async_free (decoder->async);
   }
 
-  schro_decoder_instance_free (decoder->instance);
+  do {
+    SchroDecoderInstance *next = decoder->instance->next;
+    schro_decoder_instance_free (decoder->instance);
+    decoder->instance = next;
+  } while (decoder->instance);
 
   if (decoder->input_buflist) schro_buflist_free (decoder->input_buflist);
   schro_parse_sync_free (decoder->sps);
@@ -626,6 +631,10 @@ schro_decoder_get_status_locked (SchroDecoder *decoder)
   SchroDecoderInstance *instance = decoder->instance;
   /* NB, this function should be `pure' (no sideeffects),
    * since it is called in a context which should not update state */
+  if (!instance) {
+    /* No sequence has been started yet, please supply one */
+    return SCHRO_DECODER_NEED_BITS;
+  }
   if (instance->first_seqhdr) {
     return SCHRO_DECODER_FIRST_ACCESS_UNIT;
   }
@@ -711,12 +720,31 @@ schro_decoder_wait (SchroDecoder *decoder)
   schro_async_lock (decoder->async);
   while (1) {
     ret = schro_decoder_get_status_locked (decoder);
-    if (ret == SCHRO_DECODER_FIRST_ACCESS_UNIT) {
+    switch (ret) {
+    case SCHRO_DECODER_WAIT:
+      /* try again */
+      break;
+    case SCHRO_DECODER_EOS: {
+      /* delete the decoder instance -- it is finished with
+       * This is safe since for the status to be EOS
+       * there must be:
+       *  - no work left in the decoder queue
+       *  - no pictures left to retrieve
+       * Therefore there are no threads running in this instance.
+       */
+      SchroDecoderInstance *old = decoder->instance;
+      decoder->instance = decoder->instance->next;
+      schro_decoder_instance_free (old);
+      /* try again without waiting, to discover the next
+       * state: EOS never gets passed to the user */
+      continue;
+    }
+    case SCHRO_DECODER_FIRST_ACCESS_UNIT:
       /* clean up for next iteration */
       decoder->instance->first_seqhdr = 0;
-    }
-    if (ret != SCHRO_DECODER_WAIT) {
-      break;
+      goto exit;
+    default:
+      goto exit;
     }
 
     ret = schro_async_wait_locked (decoder->async);
@@ -728,6 +756,7 @@ schro_decoder_wait (SchroDecoder *decoder)
       //SCHRO_ASSERT(0);
     }
   }
+exit:
   schro_async_unlock (decoder->async);
 
   return ret;
@@ -736,8 +765,15 @@ schro_decoder_wait (SchroDecoder *decoder)
 int
 schro_decoder_push_end_of_stream (SchroDecoder *decoder)
 {
+  SchroDecoderInstance *instance = decoder->instance;
+
   decoder->instance->flushing = TRUE;
   decoder->instance->end_of_stream = TRUE;
+
+  /* create a new instance and attach to the last instance */
+  for (; instance->next; instance = instance->next);
+  instance->next = schro_decoder_instance_new (decoder);
+
   return SCHRO_DECODER_EOS;
 }
 
@@ -813,6 +849,9 @@ schro_decoder_push_old (SchroDecoderInstance *instance, 
SchroBuffer *buffer)
     schro_buffer_unref (buffer);
     instance->end_of_stream = TRUE;
     instance->flushing = TRUE;
+    /* create a new instance and attach to the last instance */
+    for (;instance->next; instance = instance->next);
+    instance->next = schro_decoder_instance_new (instance->decoder);
     return;
   }
 
@@ -837,6 +876,22 @@ schro_decoder_push_old (SchroDecoderInstance *instance, 
SchroBuffer *buffer)
 int
 schro_decoder_push (SchroDecoder *decoder, SchroBuffer *buffer)
 {
+  SchroDecoderInstance *instance = decoder->instance;
+  /* decoder->instance is safe:
+   *  - decoder is created with an instance
+   *  - instances are created eachtime an EOS is inserted
+   *  - instances are deleted when EOS is pulled.
+   * => Next instance is created before previous one is
+   *    destroyed.
+   * Assumptions:
+   *  - Only examined case where wait() and push() are called
+   *    from same thread
+   */
+  while (instance->next) {
+    instance = instance->next;
+  }
+  /* instance is now the next instance to send data to */
+
   /* 1. buffer is added to the decoder input queue.
    * 2. The synchronizer extracts (if possible) a data unit for parsing */
   if (buffer)
diff --git a/schroedinger/schrodecoder.h b/schroedinger/schrodecoder.h
index 2c98901..b99ab8c 100644
--- a/schroedinger/schrodecoder.h
+++ b/schroedinger/schrodecoder.h
@@ -57,6 +57,12 @@ struct _SchroDecoder {
   SchroBufferList *input_buflist;
   SchroParseSyncState *sps;
 
+  /* The state required to decode a particular sequence.
+   * - New instances should be created whenever an EOS
+   *   is detected at the input to the decoder
+   * - Old instances should be deleted whenever their
+   *   state would cause an EOS to be emitted
+   */
   SchroDecoderInstance *instance;
 };
 
-- 
1.5.6.5


------------------------------------------------------------------------------
This SF.net email is sponsored by:
SourcForge Community
SourceForge wants to tell your story.
http://p.sf.net/sfu/sf-spreadtheword
_______________________________________________
Schrodinger-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/schrodinger-devel

Reply via email to