static enum mp3_action
decode_next_frame_header(struct mp3_data *data, G_GNUC_UNUSED struct tag **tag)
{
	enum mad_layer layer;

	if ((data->stream).buffer == NULL
	    || (data->stream).error == MAD_ERROR_BUFLEN) {
		if (!mp3_fill_buffer(data))
			return DECODE_BREAK;
	}
	if (mad_header_decode(&data->frame.header, &data->stream)) {
		if ((data->stream).error == MAD_ERROR_LOSTSYNC &&
		    (data->stream).this_frame) {
			signed long tagsize = id3_tag_query((data->stream).
							    this_frame,
							    (data->stream).
							    bufend -
							    (data->stream).
							    this_frame);

			if (tagsize > 0) {
				if (tag && !(*tag)) {
					mp3_parse_id3(data, (size_t)tagsize,
						      tag);
				} else {
					mad_stream_skip(&(data->stream),
							tagsize);
				}
				return DECODE_CONT;
			}
		}
		if (MAD_RECOVERABLE((data->stream).error)) {
			return DECODE_SKIP;
		} else {
			if ((data->stream).error == MAD_ERROR_BUFLEN)
				return DECODE_CONT;
			else {
				g_warning("unrecoverable frame level error "
					  "(%s).\n",
					  mad_stream_errorstr(&data->stream));
				return DECODE_BREAK;
			}
		}
	}

	layer = data->frame.header.layer;
	if (!data->layer) {
		if (layer != MAD_LAYER_II && layer != MAD_LAYER_III) {
			/* Only layer 2 and 3 have been tested to work */
			return DECODE_SKIP;
		}
		data->layer = layer;
	} else if (layer != data->layer) {
		/* Don't decode frames with a different layer than the first */
		return DECODE_SKIP;
	}

	return DECODE_OK;
}
Exemple #2
0
static enum mp3_action
decodeNextFrame(struct mp3_data *data)
{
	if ((data->stream).buffer == NULL
	    || (data->stream).error == MAD_ERROR_BUFLEN) {
		if (!mp3_fill_buffer(data))
			return DECODE_BREAK;
	}
	if (mad_frame_decode(&data->frame, &data->stream)) {
#ifdef HAVE_ID3TAG
		if ((data->stream).error == MAD_ERROR_LOSTSYNC) {
			signed long tagsize = id3_tag_query((data->stream).
							    this_frame,
							    (data->stream).
							    bufend -
							    (data->stream).
							    this_frame);
			if (tagsize > 0) {
				mad_stream_skip(&(data->stream), tagsize);
				return DECODE_CONT;
			}
		}
#endif
		if (MAD_RECOVERABLE((data->stream).error)) {
			return DECODE_SKIP;
		} else {
			if ((data->stream).error == MAD_ERROR_BUFLEN)
				return DECODE_CONT;
			else {
				g_warning("unrecoverable frame level error "
					  "(%s).\n",
					  mad_stream_errorstr(&data->stream));
				return DECODE_BREAK;
			}
		}
	}

	return DECODE_OK;
}