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