From 5e0117b4441f257fcb1aab48b42a787567ebcbe6 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sun, 14 Feb 2010 20:36:31 +0100 Subject: [PATCH] replay_gain_info: allocate the struct statically Don't allocate each replay_gain_info object on the heap. Those objects who held a pointer now store a full replay_gain_info object. This reduces the number of allocations and heap fragmentation. --- src/decoder/_flac_common.c | 9 +++---- src/decoder/flac_metadata.c | 15 ++++------- src/decoder/flac_metadata.h | 7 +++-- src/decoder/mad_decoder_plugin.c | 39 +++++++++++----------------- src/decoder/mpcdec_decoder_plugin.c | 15 +++++------ src/decoder/vorbis_decoder_plugin.c | 24 ++++++----------- src/decoder/wavpack_decoder_plugin.c | 25 ++++++------------ src/replay_gain_info.c | 27 ------------------- src/replay_gain_info.h | 22 +++++++++------- src/replay_gain_state.c | 21 ++++++--------- 10 files changed, 71 insertions(+), 133 deletions(-) diff --git a/src/decoder/_flac_common.c b/src/decoder/_flac_common.c index 6e28792ec..b642121ba 100644 --- a/src/decoder/_flac_common.c +++ b/src/decoder/_flac_common.c @@ -116,7 +116,7 @@ void flac_metadata_common_cb(const FLAC__StreamMetadata * block, if (data->unsupported) return; - struct replay_gain_info *rgi; + struct replay_gain_info rgi; switch (block->type) { case FLAC__METADATA_TYPE_STREAMINFO: @@ -124,11 +124,8 @@ void flac_metadata_common_cb(const FLAC__StreamMetadata * block, break; case FLAC__METADATA_TYPE_VORBIS_COMMENT: - rgi = flac_parse_replay_gain(block); - if (rgi != NULL) { - decoder_replay_gain(data->decoder, rgi); - replay_gain_info_free(rgi); - } + if (flac_parse_replay_gain(&rgi, block)) + decoder_replay_gain(data->decoder, &rgi); if (data->tag != NULL) flac_vorbis_comments_to_tag(data->tag, NULL, diff --git a/src/decoder/flac_metadata.c b/src/decoder/flac_metadata.c index 2ee1d8234..926cd3af7 100644 --- a/src/decoder/flac_metadata.c +++ b/src/decoder/flac_metadata.c @@ -56,13 +56,13 @@ flac_find_float_comment(const FLAC__StreamMetadata *block, return true; } -struct replay_gain_info * -flac_parse_replay_gain(const FLAC__StreamMetadata *block) +bool +flac_parse_replay_gain(struct replay_gain_info *rgi, + const FLAC__StreamMetadata *block) { - struct replay_gain_info *rgi; bool found = false; - rgi = replay_gain_info_new(); + replay_gain_info_init(rgi); if (flac_find_float_comment(block, "replaygain_album_gain", &rgi->tuples[REPLAY_GAIN_ALBUM].gain)) @@ -77,12 +77,7 @@ flac_parse_replay_gain(const FLAC__StreamMetadata *block) &rgi->tuples[REPLAY_GAIN_TRACK].peak)) found = true; - if (!found) { - replay_gain_info_free(rgi); - rgi = NULL; - } - - return rgi; + return found; } /** diff --git a/src/decoder/flac_metadata.h b/src/decoder/flac_metadata.h index 5c5c6445e..3cc333617 100644 --- a/src/decoder/flac_metadata.h +++ b/src/decoder/flac_metadata.h @@ -20,9 +20,11 @@ #ifndef MPD_FLAC_METADATA_H #define MPD_FLAC_METADATA_H +#include #include struct tag; +struct replay_gain_info; static inline unsigned flac_duration(const FLAC__StreamMetadata_StreamInfo *stream_info) @@ -31,8 +33,9 @@ flac_duration(const FLAC__StreamMetadata_StreamInfo *stream_info) stream_info->sample_rate; } -struct replay_gain_info * -flac_parse_replay_gain(const FLAC__StreamMetadata *block); +bool +flac_parse_replay_gain(struct replay_gain_info *rgi, + const FLAC__StreamMetadata *block); void flac_vorbis_comments_to_tag(struct tag *tag, const char *char_tnum, diff --git a/src/decoder/mad_decoder_plugin.c b/src/decoder/mad_decoder_plugin.c index 87dfbeabd..379cb9b8a 100644 --- a/src/decoder/mad_decoder_plugin.c +++ b/src/decoder/mad_decoder_plugin.c @@ -300,17 +300,17 @@ static int parse_rva2(struct id3_tag * tag, struct replay_gain_info * replay_gai #endif #ifdef HAVE_ID3TAG -static struct replay_gain_info * -parse_id3_replay_gain_info(struct id3_tag *tag) +static bool +parse_id3_replay_gain_info(struct replay_gain_info *replay_gain_info, + struct id3_tag *tag) { int i; char *key; char *value; struct id3_frame *frame; bool found = false; - struct replay_gain_info *replay_gain_info; - replay_gain_info = replay_gain_info_new(); + replay_gain_info_init(replay_gain_info); for (i = 0; (frame = id3_tag_findframe(tag, "TXXX", i)); i++) { if (frame->nfields < 3) @@ -341,15 +341,9 @@ parse_id3_replay_gain_info(struct id3_tag *tag) free(value); } - if (!found) { + return found || /* fall back on RVA2 if no replaygain tags found */ - found = parse_rva2(tag, replay_gain_info); - } - - if (found) - return replay_gain_info; - replay_gain_info_free(replay_gain_info); - return NULL; + parse_rva2(tag, replay_gain_info); } #endif @@ -408,11 +402,9 @@ static void mp3_parse_id3(struct mp3_data *data, size_t tagsize, } if (data->decoder != NULL) { - struct replay_gain_info *tmp_rgi = - parse_id3_replay_gain_info(id3_tag); - if (tmp_rgi != NULL) { - decoder_replay_gain(data->decoder, tmp_rgi); - replay_gain_info_free(tmp_rgi); + struct replay_gain_info rgi; + if (parse_id3_replay_gain_info(&rgi, id3_tag)) { + decoder_replay_gain(data->decoder, &rgi); data->found_replay_gain = true; } } @@ -879,15 +871,14 @@ mp3_decode_first_frame(struct mp3_data *data, struct tag **tag) if (data->decoder != NULL && !data->found_replay_gain && lame.track_gain) { - struct replay_gain_info *rgi - = replay_gain_info_new(); - rgi->tuples[REPLAY_GAIN_TRACK].gain = lame.track_gain; - rgi->tuples[REPLAY_GAIN_TRACK].peak = lame.peak; - decoder_replay_gain(data->decoder, rgi); - replay_gain_info_free(rgi); + struct replay_gain_info rgi; + replay_gain_info_init(&rgi); + rgi.tuples[REPLAY_GAIN_TRACK].gain = lame.track_gain; + rgi.tuples[REPLAY_GAIN_TRACK].peak = lame.peak; + decoder_replay_gain(data->decoder, &rgi); } } - } + } if (!data->max_frames) return false; diff --git a/src/decoder/mpcdec_decoder_plugin.c b/src/decoder/mpcdec_decoder_plugin.c index 92f0cad84..e41ae779d 100644 --- a/src/decoder/mpcdec_decoder_plugin.c +++ b/src/decoder/mpcdec_decoder_plugin.c @@ -154,7 +154,6 @@ mpcdec_decode(struct decoder *mpd_decoder, struct input_stream *is) long bit_rate = 0; mpc_uint32_t vbr_update_acc; mpc_uint32_t vbr_update_bits; - struct replay_gain_info *replay_gain_info = NULL; enum decoder_command cmd = DECODE_COMMAND_NONE; data.is = is; @@ -205,13 +204,13 @@ mpcdec_decode(struct decoder *mpd_decoder, struct input_stream *is) return; } - replay_gain_info = replay_gain_info_new(); - replay_gain_info->tuples[REPLAY_GAIN_ALBUM].gain = info.gain_album * 0.01; - replay_gain_info->tuples[REPLAY_GAIN_ALBUM].peak = info.peak_album / 32767.0; - replay_gain_info->tuples[REPLAY_GAIN_TRACK].gain = info.gain_title * 0.01; - replay_gain_info->tuples[REPLAY_GAIN_TRACK].peak = info.peak_title / 32767.0; - decoder_replay_gain(mpd_decoder, replay_gain_info); - replay_gain_info_free(replay_gain_info); + struct replay_gain_info replay_gain_info; + replay_gain_info_init(&replay_gain_info); + replay_gain_info.tuples[REPLAY_GAIN_ALBUM].gain = info.gain_album * 0.01; + replay_gain_info.tuples[REPLAY_GAIN_ALBUM].peak = info.peak_album / 32767.0; + replay_gain_info.tuples[REPLAY_GAIN_TRACK].gain = info.gain_title * 0.01; + replay_gain_info.tuples[REPLAY_GAIN_TRACK].peak = info.peak_title / 32767.0; + decoder_replay_gain(mpd_decoder, &replay_gain_info); decoder_initialized(mpd_decoder, &audio_format, is->seekable, diff --git a/src/decoder/vorbis_decoder_plugin.c b/src/decoder/vorbis_decoder_plugin.c index 0163ca9ff..25e91c142 100644 --- a/src/decoder/vorbis_decoder_plugin.c +++ b/src/decoder/vorbis_decoder_plugin.c @@ -134,14 +134,13 @@ vorbis_comment_value(const char *comment, const char *needle) return NULL; } -static struct replay_gain_info * -vorbis_comments_to_replay_gain(char **comments) +static bool +vorbis_comments_to_replay_gain(struct replay_gain_info *rgi, char **comments) { - struct replay_gain_info *rgi; const char *temp; bool found = false; - rgi = replay_gain_info_new(); + replay_gain_info_init(rgi); while (*comments) { if ((temp = @@ -165,12 +164,7 @@ vorbis_comments_to_replay_gain(char **comments) comments++; } - if (!found) { - replay_gain_info_free(rgi); - rgi = NULL; - } - - return rgi; + return found; } static const char *VORBIS_COMMENT_TRACK_KEY = "tracknumber"; @@ -334,7 +328,6 @@ vorbis_stream_decode(struct decoder *decoder, if (current_section != prev_section) { char **comments; - struct replay_gain_info *new_rgi; vi = ov_info(&vf, -1); if (vi == NULL) { @@ -352,11 +345,10 @@ vorbis_stream_decode(struct decoder *decoder, comments = ov_comment(&vf, -1)->user_comments; vorbis_send_comments(decoder, input_stream, comments); - new_rgi = vorbis_comments_to_replay_gain(comments); - if (new_rgi != NULL) { - decoder_replay_gain(decoder, new_rgi); - replay_gain_info_free(new_rgi); - } + + struct replay_gain_info rgi; + if (vorbis_comments_to_replay_gain(&rgi, comments)) + decoder_replay_gain(decoder, &rgi); prev_section = current_section; } diff --git a/src/decoder/wavpack_decoder_plugin.c b/src/decoder/wavpack_decoder_plugin.c index ec0bc5d8d..efed98851 100644 --- a/src/decoder/wavpack_decoder_plugin.c +++ b/src/decoder/wavpack_decoder_plugin.c @@ -256,13 +256,13 @@ wavpack_tag_float(WavpackContext *wpc, const char *key, float *value_r) return true; } -static struct replay_gain_info * -wavpack_replaygain(WavpackContext *wpc) +static bool +wavpack_replaygain(struct replay_gain_info *replay_gain_info, + WavpackContext *wpc) { - struct replay_gain_info *replay_gain_info; bool found = false; - replay_gain_info = replay_gain_info_new(); + replay_gain_info_init(replay_gain_info); found |= wavpack_tag_float( wpc, "replaygain_track_gain", @@ -281,13 +281,7 @@ wavpack_replaygain(WavpackContext *wpc) &replay_gain_info->tuples[REPLAY_GAIN_ALBUM].peak ); - if (found) { - return replay_gain_info; - } - - replay_gain_info_free(replay_gain_info); - - return NULL; + return found; } /* @@ -554,7 +548,6 @@ wavpack_filedecode(struct decoder *decoder, const char *fname) { char error[ERRORLEN]; WavpackContext *wpc; - struct replay_gain_info *replay_gain_info; wpc = WavpackOpenFileInput( fname, error, @@ -568,11 +561,9 @@ wavpack_filedecode(struct decoder *decoder, const char *fname) return; } - replay_gain_info = wavpack_replaygain(wpc); - if (replay_gain_info != NULL) { - decoder_replay_gain(decoder, replay_gain_info); - replay_gain_info_free(replay_gain_info); - } + struct replay_gain_info replay_gain_info; + if (wavpack_replaygain(&replay_gain_info, wpc)) + decoder_replay_gain(decoder, &replay_gain_info); wavpack_decode(decoder, wpc, true); diff --git a/src/replay_gain_info.c b/src/replay_gain_info.c index 33e29e8e3..76bd98acd 100644 --- a/src/replay_gain_info.c +++ b/src/replay_gain_info.c @@ -20,33 +20,6 @@ #include "config.h" #include "replay_gain_info.h" -#include - -struct replay_gain_info * -replay_gain_info_new(void) -{ - struct replay_gain_info *ret = g_new(struct replay_gain_info, 1); - - for (unsigned i = 0; i < G_N_ELEMENTS(ret->tuples); ++i) { - ret->tuples[i].gain = INFINITY; - ret->tuples[i].peak = 0.0; - } - - return ret; -} - -struct replay_gain_info * -replay_gain_info_dup(const struct replay_gain_info *src) -{ - return g_memdup(src, sizeof(*src)); -} - -void -replay_gain_info_free(struct replay_gain_info *info) -{ - g_free(info); -} - float replay_gain_tuple_scale(const struct replay_gain_tuple *tuple, float preamp) { diff --git a/src/replay_gain_info.h b/src/replay_gain_info.h index 2465a250e..c61bac387 100644 --- a/src/replay_gain_info.h +++ b/src/replay_gain_info.h @@ -40,17 +40,19 @@ struct replay_gain_info { struct replay_gain_tuple tuples[2]; }; -struct replay_gain_info * -replay_gain_info_new(void); +static inline void +replay_gain_tuple_init(struct replay_gain_tuple *tuple) +{ + tuple->gain = INFINITY; + tuple->peak = 0.0; +} -/** - * Duplicate a #replay_gain_info object. - */ -struct replay_gain_info * -replay_gain_info_dup(const struct replay_gain_info *src); - -void -replay_gain_info_free(struct replay_gain_info *info); +static inline void +replay_gain_info_init(struct replay_gain_info *info) +{ + replay_gain_tuple_init(&info->tuples[REPLAY_GAIN_ALBUM]); + replay_gain_tuple_init(&info->tuples[REPLAY_GAIN_TRACK]); +} static inline bool replay_gain_tuple_defined(const struct replay_gain_tuple *tuple) diff --git a/src/replay_gain_state.c b/src/replay_gain_state.c index 4d494c62d..cfb2ce120 100644 --- a/src/replay_gain_state.c +++ b/src/replay_gain_state.c @@ -30,7 +30,7 @@ struct replay_gain_state { enum replay_gain_mode mode; - struct replay_gain_info *info; + struct replay_gain_info info; float scale; }; @@ -43,7 +43,7 @@ replay_gain_state_new(float preamp, float missing_preamp) state->preamp = preamp; state->scale = state->missing_preamp = missing_preamp; state->mode = REPLAY_GAIN_OFF; - state->info = NULL; + replay_gain_info_init(&state->info); return state; } @@ -53,9 +53,6 @@ replay_gain_state_free(struct replay_gain_state *state) { assert(state != NULL); - if (state->info != NULL) - replay_gain_info_free(state->info); - g_free(state); } @@ -64,11 +61,11 @@ replay_gain_state_calc_scale(struct replay_gain_state *state) { assert(state != NULL); - if (state->mode == REPLAY_GAIN_OFF || state->info == NULL) + if (state->mode == REPLAY_GAIN_OFF) return; const struct replay_gain_tuple *tuple = - &state->info->tuples[state->mode]; + &state->info.tuples[state->mode]; if (replay_gain_tuple_defined(tuple)) { g_debug("computing ReplayGain scale with gain %f, peak %f", tuple->gain, tuple->peak); @@ -98,12 +95,10 @@ replay_gain_state_set_info(struct replay_gain_state *state, { assert(state != NULL); - if (state->info != NULL) - replay_gain_info_free(state->info); - - state->info = info != NULL - ? replay_gain_info_dup(info) - : NULL; + if (info != NULL) + state->info = *info; + else + replay_gain_info_init(&state->info); replay_gain_state_calc_scale(state); }