aboutsummaryrefslogtreecommitdiff
path: root/src/filter/replay_gain_filter_plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/filter/replay_gain_filter_plugin.c')
-rw-r--r--src/filter/replay_gain_filter_plugin.c120
1 files changed, 60 insertions, 60 deletions
diff --git a/src/filter/replay_gain_filter_plugin.c b/src/filter/replay_gain_filter_plugin.c
index 583a09f9..8e01cb75 100644
--- a/src/filter/replay_gain_filter_plugin.c
+++ b/src/filter/replay_gain_filter_plugin.c
@@ -23,7 +23,6 @@
#include "filter_internal.h"
#include "filter_registry.h"
#include "audio_format.h"
-#include "pcm_buffer.h"
#include "pcm_volume.h"
#include "replay_gain_info.h"
#include "replay_gain_config.h"
@@ -32,6 +31,10 @@
#include <assert.h>
#include <string.h>
+#include <libavutil/channel_layout.h>
+#include <libavutil/frame.h>
+#include <libavutil/samplefmt.h>
+
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "replay_gain"
@@ -69,8 +72,6 @@ struct replay_gain_filter {
unsigned volume;
struct audio_format audio_format;
-
- struct pcm_buffer buffer;
};
static inline GQuark
@@ -141,67 +142,67 @@ replay_gain_filter_open(struct filter *_filter,
(struct replay_gain_filter *)_filter;
filter->audio_format = *audio_format;
- pcm_buffer_init(&filter->buffer);
return &filter->audio_format;
}
-static void
-replay_gain_filter_close(struct filter *_filter)
-{
- struct replay_gain_filter *filter =
- (struct replay_gain_filter *)_filter;
-
- pcm_buffer_deinit(&filter->buffer);
-}
-
-static const void *
-replay_gain_filter_filter(struct filter *_filter,
- const void *src, size_t src_size,
- size_t *dest_size_r, GError **error_r)
+static AVFrame *replay_gain_filter_filter(struct filter *_filter, AVFrame *src)
{
- struct replay_gain_filter *filter =
- (struct replay_gain_filter *)_filter;
- bool success;
- void *dest;
- enum replay_gain_mode rg_mode;
-
- /* check if the mode has been changed since the last call */
- rg_mode = replay_gain_get_real_mode();
-
- if (filter->mode != rg_mode) {
- g_debug("replay gain mode has changed %d->%d\n", filter->mode, rg_mode);
- filter->mode = rg_mode;
- replay_gain_filter_update(filter);
- }
-
- *dest_size_r = src_size;
-
- if (filter->volume == PCM_VOLUME_1)
- /* optimized special case: 100% volume = no-op */
- return src;
-
- dest = pcm_buffer_get(&filter->buffer, src_size);
-
- if (filter->volume <= 0) {
- /* optimized special case: 0% volume = memset(0) */
- /* XXX is this valid for all sample formats? What
- about floating point? */
- memset(dest, 0, src_size);
- return dest;
- }
-
- memcpy(dest, src, src_size);
-
- success = pcm_volume(dest, src_size, filter->audio_format.format,
- filter->volume);
- if (!success) {
- g_set_error(error_r, replay_gain_quark(), 0,
- "pcm_volume() has failed");
- return NULL;
- }
-
- return dest;
+ struct replay_gain_filter *filter =
+ (struct replay_gain_filter *)_filter;
+ int ret;
+ enum replay_gain_mode rg_mode;
+
+ /* check if the mode has been changed since the last call */
+ rg_mode = replay_gain_get_real_mode();
+
+ if (filter->mode != rg_mode) {
+ g_debug("replay gain mode has changed %d->%d\n", filter->mode, rg_mode);
+ filter->mode = rg_mode;
+ replay_gain_filter_update(filter);
+ }
+
+ /* optimized special case: 100% volume = no-op */
+ if (filter->volume == PCM_VOLUME_1)
+ return src;
+
+ /* optimized special case: 0% volume = memset(0) */
+ if (filter->volume <= 0) {
+ AVFrame *dst = av_frame_alloc();
+ if (!dst) {
+ av_frame_free(&src);
+ return NULL;
+ }
+
+ dst->nb_samples = src->nb_samples;
+ dst->format = src->format;
+ dst->channel_layout = src->channel_layout;
+ av_frame_copy_props(dst, src);
+ av_frame_free(&src);
+
+ ret = av_frame_get_buffer(dst, 32);
+ if (ret < 0)
+ return NULL;
+
+ av_samples_set_silence(dst->extended_data, 0, dst->nb_samples,
+ av_get_channel_layout_nb_channels(dst->channel_layout),
+ dst->format);
+ return dst;
+ }
+
+ ret = av_frame_make_writable(src);
+ if (ret < 0) {
+ av_frame_free(&src);
+ return NULL;
+ }
+
+ ret = pcm_volume(src->data[0], src->linesize[0], filter->audio_format.format, filter->volume);
+ if (!ret) {
+ g_warning("pcm_volume() has failed");
+ return NULL;
+ }
+
+ return src;
}
const struct filter_plugin replay_gain_filter_plugin = {
@@ -209,7 +210,6 @@ const struct filter_plugin replay_gain_filter_plugin = {
.init = replay_gain_filter_init,
.finish = replay_gain_filter_finish,
.open = replay_gain_filter_open,
- .close = replay_gain_filter_close,
.filter = replay_gain_filter_filter,
};