mpeg2_state_t mpeg2_parse (mpeg2dec_t * mpeg2dec) { int size_buffer, size_chunk, copied; if (mpeg2dec->action) { mpeg2_state_t state; state = mpeg2dec->action (mpeg2dec); if ((int)state > (int)STATE_INTERNAL_NORETURN) return state; } while (1) { while ((unsigned) (mpeg2dec->code - mpeg2dec->first_decode_slice) < mpeg2dec->nb_decode_slices) { size_buffer = mpeg2dec->buf_end - mpeg2dec->buf_start; size_chunk = (mpeg2dec->chunk_buffer + BUFFER_SIZE - mpeg2dec->chunk_ptr); if (size_buffer <= size_chunk) { copied = copy_chunk (mpeg2dec, size_buffer); if (!copied) { mpeg2dec->bytes_since_tag += size_buffer; mpeg2dec->chunk_ptr += size_buffer; return STATE_BUFFER; } } else { copied = copy_chunk (mpeg2dec, size_chunk); if (!copied) { /* filled the chunk buffer without finding a start code */ mpeg2dec->bytes_since_tag += size_chunk; mpeg2dec->action = seek_chunk; return STATE_INVALID; } } mpeg2dec->bytes_since_tag += copied; mpeg2_slice (&(mpeg2dec->decoder), mpeg2dec->code, mpeg2dec->chunk_start); mpeg2dec->code = mpeg2dec->buf_start[-1]; mpeg2dec->chunk_ptr = mpeg2dec->chunk_start; } if ((unsigned) (mpeg2dec->code - 1) >= 0xb0 - 1) break; if (seek_chunk (mpeg2dec) == STATE_BUFFER) return STATE_BUFFER; } mpeg2dec->action = mpeg2_seek_header; switch (mpeg2dec->code) { case 0x00: return mpeg2dec->state; case 0xb3: case 0xb7: case 0xb8: return (mpeg2dec->state == STATE_SLICE) ? STATE_SLICE : STATE_INVALID; default: mpeg2dec->action = seek_chunk; return STATE_INVALID; } }
mpeg2_state_t mpeg2_seek_header (mpeg2dec_t * mpeg2dec) { while (!(mpeg2dec->code == 0xb3 || ((mpeg2dec->code == 0xb7 || mpeg2dec->code == 0xb8 || !mpeg2dec->code) && mpeg2dec->sequence.width != (unsigned)-1))) if (seek_chunk (mpeg2dec) == STATE_BUFFER) return STATE_BUFFER; mpeg2dec->chunk_start = mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer; mpeg2dec->user_data_len = 0; return ((mpeg2dec->code == 0xb7) ? mpeg2_header_end (mpeg2dec) : mpeg2_parse_header (mpeg2dec)); }
mpeg2_state_t mpeg2_seek_header (mpeg2dec_t * mpeg2dec) { while (mpeg2dec->code != 0xb3 && ((mpeg2dec->code != 0xb7 && mpeg2dec->code != 0xb8 && mpeg2dec->code) || mpeg2dec->sequence.width == (unsigned)-1)) if (seek_chunk (mpeg2dec) == STATE_BUFFER) return STATE_BUFFER; mpeg2dec->chunk_start = mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer; mpeg2dec->user_data_len = 0; return (mpeg2dec->code ? mpeg2_parse_header (mpeg2dec) : mpeg2_header_picture_start (mpeg2dec)); }