---

Here the first initial draft of an AVFrame based api for avresample.

What it does:

 - Provides a way to configure avr from input and output frames (and a dict for 
future proofing)
 - Provides a mean convert from AVFrame to AVFrame
 - Let you be lazy and just call the convert function and have the 
configuration and even the
   output frame buffers setup happening in the same functions

What does not do:
 - Manage reconfigurations implicitly (avscale would)
 - Resize the output frame buffer to be optimal if is already set.

Open question/missing bits:
 - It currently sets the output nb_samples but does not reset to the max value 
on the next iteration
 - Output reconfiguration is gory, Input is not so much, do we want to support 
it?
 - The patch introduces two AVERRORs, not sure how much reuse would see.

 libavresample/utils.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 87 insertions(+)

diff --git a/libavresample/utils.c b/libavresample/utils.c
index 35bee42..67cc7a5 100644
--- a/libavresample/utils.c
+++ b/libavresample/utils.c
@@ -506,6 +506,93 @@ int attribute_align_arg 
avresample_convert(AVAudioResampleContext *avr,
                                   current_buffer);
 }

+int avresample_config(AVAudioResampleContext *avr, AVFrame *out, AVFrame *in,
+                      AVDictionary **opts)
+{
+    int ret;
+
+    if (avresample_is_open(avr)) {
+        avresample_close(avr);
+    }
+
+    avr->in_channel_layout  = in->channel_layout;
+    avr->out_channel_layout = out->channel_layout;
+    avr->in_sample_rate     = in->sample_rate;
+    avr->out_sample_rate    = out->sample_rate;
+    avr->in_sample_fmt      = in->format;
+    avr->out_sample_fmt     = out->format;
+
+    if ((ret = av_opt_set_dict(avr, opts)) < 0)
+        return ret;
+
+    return avresample_open(avr);
+}
+
+int config_changed(AVAudioResampleContext *avr, AVFrame *out, AVFrame *in)
+{
+    int ret = 0;
+    if (avr->in_channel_layout != in->channel_layout ||
+        avr->in_sample_rate    != in->sample_rate ||
+        avr->in_sample_fmt     != in->format) {
+        ret |= AVRESAMPLE_INPUT_CHANGED;
+    }
+
+    if (avr->out_channel_layout != out->channel_layout ||
+        avr->out_sample_rate    != out->sample_rate ||
+        avr->out_sample_fmt     != out->format) {
+        ret |= AVRESAMPLE_OUTPUT_CHANGED;
+    }
+
+    return ret;
+}
+
+int convert_frame(AVAudioResampleContext *avr, AVFrame *out, AVFrame *in)
+{
+    int out_size, out_linesize, out_channels;
+    int out_samplebytes = av_get_bytes_per_sample(out->format);
+    int ret;
+
+    out_channels = av_get_channel_layout_nb_channels(out->channel_layout);
+
+    ret = avresample_convert(avr, out->extended_data, out->linesize[0],
+                             in->nb_samples,
+                             in->extended_data, in->linesize[0],
+                             in->nb_samples);
+
+    if (ret > 0) {
+        out->nb_samples = ret;
+        return 0;
+    }
+
+    return ret;
+}
+
+int avresample_convert_frame(AVAudioResampleContext *avr,
+                             AVFrame *out, AVFrame *in)
+{
+    int ret;
+
+    if (!avresample_is_open(avr)) {
+        if ((ret = avresample_config(avr, out, in, NULL)) < 0)
+            return ret;
+        if ((ret = avresample_open(avr)) < 0)
+            return ret;
+    } else {
+        // return as is or reconfigure for input changes?
+        if ((ret = config_changed(avr, out, in)))
+            return ret;
+    }
+
+    if (!out->linesize[0]) {
+        if ((ret = av_frame_get_buffer(out, 0)) < 0) {
+            avresample_close(avr);
+            return ret;
+        }
+    }
+
+    return convert_frame(avr, out, in);
+}
+
 int avresample_get_matrix(AVAudioResampleContext *avr, double *matrix,
                           int stride)
 {
--
1.8.5.2 (Apple Git-48)

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to