From: David Flynn <[email protected]>

Previously the decoder state machine is split into two parts:
 - from doing decoder_push()
 - from doing decoder_wait()
There are some issues with this design:
 - state from decoder_push can appear out-of-order with respect to
   decoder_wait().  This at worst, can lead to badness when dealing
   with concatenated sequences.
 - over complicates client code

Given previous patches remove the buffering and sync burden from client
code, it would be ideal to unify the state machine so that client code
becomes:
  decoder_push(data);
  do {
    switch(decoder_wait())
    {...}
  } while (...)

decoder_push() now returns the next state that decoder_wait is about
to return (if nothing else happens).

includes:
- decoder: fix 'unify the two partial ...'

Signed-off-by: David Flynn <[email protected]>
---
 schroedinger/schrodecoder.c |   52 ++++++++++++++++++++++++-------------------
 schroedinger/schrodecoder.h |    3 +-
 2 files changed, 31 insertions(+), 24 deletions(-)

diff --git a/schroedinger/schrodecoder.c b/schroedinger/schrodecoder.c
index 30984c1..acc85b4 100644
--- a/schroedinger/schrodecoder.c
+++ b/schroedinger/schrodecoder.c
@@ -342,6 +342,7 @@ schro_decoder_reset (SchroDecoder *decoder)
   decoder->next_frame_number = 0;
   decoder->have_frame_number = FALSE;
 
+  decoder->first_seqhdr = FALSE;
   decoder->end_of_stream = FALSE;
   decoder->flushing = FALSE;
   schro_async_unlock (decoder->async);
@@ -601,6 +602,11 @@ schro_decoder_need_output_frame (SchroDecoder *decoder)
 static int
 schro_decoder_get_status_locked (SchroDecoder *decoder)
 {
+  /* NB, this function should be `pure' (no sideeffects),
+   * since it is called in a context which should not update state */
+  if (decoder->first_seqhdr) {
+    return SCHRO_DECODER_FIRST_ACCESS_UNIT;
+  }
   if (schro_decoder_pull_is_ready_locked (decoder)) {
     return SCHRO_DECODER_OK;
   }
@@ -682,6 +688,10 @@ 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) {
+      /* clean up for next iteration */
+      decoder->first_seqhdr = 0;
+    }
     if (ret != SCHRO_DECODER_WAIT) {
       break;
     }
@@ -721,7 +731,7 @@ schro_decoder_set_flushing (SchroDecoder *decoder, int 
value)
   return SCHRO_DECODER_OK;
 }
 
-int
+void
 schro_decoder_push_old (SchroDecoder *decoder, SchroBuffer *buffer)
 {
   SchroUnpack unpack;
@@ -737,26 +747,21 @@ schro_decoder_push_old (SchroDecoder *decoder, 
SchroBuffer *buffer)
   }
 
   if (parse_code == SCHRO_PARSE_CODE_SEQUENCE_HEADER) {
-    int ret;
-
     SCHRO_INFO ("decoding sequence header");
     if (!decoder->sequence_header_buffer) {
       schro_decoder_parse_sequence_header(decoder, &unpack);
       decoder->sequence_header_buffer = schro_buffer_dup (buffer);
-
-      ret = SCHRO_DECODER_FIRST_ACCESS_UNIT;
+      decoder->first_seqhdr = TRUE;
     } else {
-      if (schro_decoder_compare_sequence_header_buffer (buffer,
+      if (!schro_decoder_compare_sequence_header_buffer (buffer,
             decoder->sequence_header_buffer)) {
-        ret = SCHRO_DECODER_OK;
       } else {
         schro_decoder_error (decoder, "sequence header changed");
-        ret = SCHRO_DECODER_ERROR;
       }
     }
 
     schro_buffer_unref (buffer);
-    return ret;
+    return;
   }
 
   if (parse_code == SCHRO_PARSE_CODE_AUXILIARY_DATA) {
@@ -773,12 +778,12 @@ schro_decoder_push_old (SchroDecoder *decoder, 
SchroBuffer *buffer)
     }
 
     schro_buffer_unref (buffer);
-    return SCHRO_DECODER_OK;
+    return;
   }
 
   if (SCHRO_PARSE_CODE_IS_PADDING(parse_code)) {
     schro_buffer_unref (buffer);
-    return SCHRO_DECODER_OK;
+    return;
   }
 
   if (SCHRO_PARSE_CODE_IS_END_OF_SEQUENCE (parse_code)) {
@@ -786,7 +791,7 @@ schro_decoder_push_old (SchroDecoder *decoder, SchroBuffer 
*buffer)
     schro_buffer_unref (buffer);
     decoder->end_of_stream = TRUE;
     decoder->flushing = TRUE;
-    return SCHRO_DECODER_EOS;
+    return;
   }
 
   if (SCHRO_PARSE_CODE_IS_PICTURE(parse_code)) {
@@ -794,21 +799,22 @@ schro_decoder_push_old (SchroDecoder *decoder, 
SchroBuffer *buffer)
     if (!decoder->sequence_header_buffer) {
       SCHRO_INFO ("no sequence header -- dropping picture");
       schro_buffer_unref (buffer);
-      return SCHRO_DECODER_OK;
+      return;
     }
 
-    return schro_decoder_iterate_picture (decoder, buffer, &unpack, 
parse_code);
+    schro_decoder_iterate_picture (decoder, buffer, &unpack, parse_code);
+    return;
   }
 
+  /* Unhandled parse unit */
   schro_buffer_unref (buffer);
-  return SCHRO_DECODER_ERROR;
+  /* xxx: some warning might be nice, although it is not a major error */
+  return;
 }
 
 int
 schro_decoder_push (SchroDecoder *decoder, SchroBuffer *buffer)
 {
-  int ret = SCHRO_DECODER_OK;
-  int x;
   /* 1. buffer is added to the decoder input queue.
    * 2. The synchronizer extracts (if possible) a data unit for parsing */
   if (buffer)
@@ -819,14 +825,14 @@ schro_decoder_push (SchroDecoder *decoder, SchroBuffer 
*buffer)
     buffer = schro_parse_sync (decoder->sps, decoder->input_buflist);
     /* has the syncroniser run out of buffer? */
     if (!buffer)
-      return ret;
-    x = schro_decoder_push_old (decoder, buffer);
-    ret = x != SCHRO_DECODER_OK ? x : ret;
+      break;
+    schro_decoder_push_old (decoder, buffer);
   }
-  return ret;
+  /* peek at the next state */
+  return schro_decoder_get_status_locked (decoder);
 }
 
-int
+void
 schro_decoder_iterate_picture (SchroDecoder *decoder, SchroBuffer *buffer, 
SchroUnpack *unpack, int parse_code)
 {
   SchroPicture *picture;
@@ -929,7 +935,7 @@ schro_decoder_iterate_picture (SchroDecoder *decoder, 
SchroBuffer *buffer, Schro
   schro_async_signal_scheduler (decoder->async);
   schro_async_unlock (decoder->async);
 
-  return SCHRO_DECODER_OK;
+  return;
 }
 
 void
diff --git a/schroedinger/schrodecoder.h b/schroedinger/schrodecoder.h
index ca43412..1030e0b 100644
--- a/schroedinger/schrodecoder.h
+++ b/schroedinger/schrodecoder.h
@@ -63,6 +63,7 @@ struct _SchroDecoder {
 
   int reorder_buffer_size;
 
+  int first_seqhdr;
   int end_of_stream;
   int flushing;
   int coded_order;
@@ -180,7 +181,7 @@ void schro_picture_unref (SchroPicture *picture);
 SchroPicture *schro_picturequeue_find (SchroPictureQueue *queue, 
SchroPictureNumber picture_number);
 void schro_picturequeue_delete (SchroPictureQueue *queue, SchroPictureNumber 
picture_number);
 
-int schro_decoder_iterate_picture (SchroDecoder *decoder, SchroBuffer *buffer, 
SchroUnpack *unpack, int parse_code);
+void schro_decoder_iterate_picture (SchroDecoder *decoder, SchroBuffer 
*buffer, SchroUnpack *unpack, int parse_code);
 void schro_decoder_parse_picture (SchroPicture *picture, SchroUnpack *unpack);
 void schro_decoder_parse_picture_header (SchroPicture *picture, SchroUnpack 
*unpack);
 void schro_decoder_parse_picture_prediction_parameters (SchroPicture *picture, 
SchroUnpack *unpack);
-- 
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