+static int need_bad_data_delay(struct private_mp3dec_data *pmd,
+ size_t bytes_available)
+{
+ if (!(pmd->flags & MP3DEC_FLAG_BAD_DATA))
+ return 0;
+ if (pmd->flags & MP3DEC_FLAG_DECODE_STARTED)
+ return 0;
+ if (bytes_available >= pmd->input_len_barrier)
+ return 0;
+ if (tv_diff(now, &pmd->stream_start_barrier, NULL) > 0)
+ return 0;
+ return 1;
+}
+
+/*
+ * Returns negative on serious errors, zero if the error should be ignored and
+ * positive on bad data pointer errors at stream start.
+ */
+static int handle_decode_error(struct private_mp3dec_data *pmd, size_t len)
+{
+ const struct timeval delay = {0, 60 * 1000};
+ if (!MAD_RECOVERABLE(pmd->stream.error)
+ && pmd->stream.error != MAD_ERROR_BUFLEN) {
+ PARA_ERROR_LOG("%s\n", mad_stream_errorstr(&pmd->stream));
+ return -E_MAD_FRAME_DECODE;
+ }
+ PARA_DEBUG_LOG("%s\n", mad_stream_errorstr(&pmd->stream));
+ if (pmd->stream.error != MAD_ERROR_BADDATAPTR)
+ return 0;
+ if (pmd->flags & MP3DEC_FLAG_DECODE_STARTED)
+ return 0;
+ /*
+ * Bad data pointer at stream start. Defer decoding until the amount of
+ * data we are about to skip is available again, but wait at most 60ms.
+ */
+ pmd->flags |= MP3DEC_FLAG_BAD_DATA;
+ pmd->input_len_barrier = len;
+ tv_add(now, &delay, &pmd->stream_start_barrier);
+ return 1;
+}
+
+static size_t used_mad_buffer_bytes(struct mad_stream *s, size_t max)