mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 11:55:49 +00:00
bug 1429666 cubeb_resampler_speex: don't call data callback while draining r=padenot
MozReview-Commit-ID: 1XEzZjPGai9 --HG-- extra : rebase_source : 56be87525d46ed3850a15e8e4dd19804dd832408
This commit is contained in:
parent
a331a849a4
commit
88b88a2384
@ -1,7 +1,11 @@
|
||||
The source from this directory was copied from the cubeb
|
||||
git repository using the update.sh script. The only changes
|
||||
made were those applied by update.sh and the addition of
|
||||
Makefile.in build files for the Mozilla build system.
|
||||
made were those applied by update.sh, the addition of
|
||||
Makefile.in build files for the Mozilla build system,
|
||||
and the following patches, which may be overwritten when
|
||||
included upstream.
|
||||
https://github.com/kinetiknz/cubeb/pull/398/commits/c8e66dee61a35e6a6d54e3630e1668bdbd6984b4
|
||||
https://github.com/kinetiknz/cubeb/pull/398/commits/2ed979bc891cf1a7822799947a357d4d3b625964
|
||||
|
||||
The cubeb git repository is: git://github.com/kinetiknz/cubeb.git
|
||||
|
||||
|
@ -497,13 +497,15 @@ TEST(cubeb, resampler_output_only_noop)
|
||||
cubeb_resampler_destroy(resampler);
|
||||
}
|
||||
|
||||
long test_drain_data_cb(cubeb_stream * /*stm*/, void * /*user_ptr*/,
|
||||
long test_drain_data_cb(cubeb_stream * /*stm*/, void * user_ptr,
|
||||
const void * input_buffer,
|
||||
void * output_buffer, long frame_count)
|
||||
{
|
||||
EXPECT_TRUE(output_buffer);
|
||||
EXPECT_TRUE(!input_buffer);
|
||||
return frame_count - 10;
|
||||
auto cb_count = static_cast<int *>(user_ptr);
|
||||
(*cb_count)++;
|
||||
return frame_count - 1;
|
||||
}
|
||||
|
||||
TEST(cubeb, resampler_drain)
|
||||
@ -515,10 +517,11 @@ TEST(cubeb, resampler_drain)
|
||||
output_params.channels = 1;
|
||||
output_params.format = CUBEB_SAMPLE_FLOAT32NE;
|
||||
target_rate = 48000;
|
||||
int cb_count = 0;
|
||||
|
||||
cubeb_resampler * resampler =
|
||||
cubeb_resampler_create((cubeb_stream*)nullptr, nullptr, &output_params, target_rate,
|
||||
test_drain_data_cb, nullptr,
|
||||
test_drain_data_cb, &cb_count,
|
||||
CUBEB_RESAMPLER_QUALITY_VOIP);
|
||||
|
||||
const long out_frames = 128;
|
||||
@ -530,9 +533,9 @@ TEST(cubeb, resampler_drain)
|
||||
out_buffer, out_frames);
|
||||
} while (got == out_frames);
|
||||
|
||||
/* If the above is not an infinite loop, the drain was a success, just mark
|
||||
* this test as such. */
|
||||
ASSERT_TRUE(true);
|
||||
/* The callback should be called once but not again after returning <
|
||||
* frame_count. */
|
||||
ASSERT_EQ(cb_count, 1);
|
||||
|
||||
cubeb_resampler_destroy(resampler);
|
||||
}
|
||||
|
@ -145,27 +145,33 @@ cubeb_resampler_speex<T, InputProcessor, OutputProcessor>
|
||||
assert(!input_buffer && (!input_frames_count || *input_frames_count == 0) &&
|
||||
output_buffer && output_frames_needed);
|
||||
|
||||
long got = 0;
|
||||
T * out_unprocessed = nullptr;
|
||||
long output_frames_before_processing = 0;
|
||||
if (!draining) {
|
||||
long got = 0;
|
||||
T * out_unprocessed = nullptr;
|
||||
long output_frames_before_processing = 0;
|
||||
|
||||
/* fill directly the input buffer of the output processor to save a copy */
|
||||
output_frames_before_processing =
|
||||
output_processor->input_needed_for_output(output_frames_needed);
|
||||
/* fill directly the input buffer of the output processor to save a copy */
|
||||
output_frames_before_processing =
|
||||
output_processor->input_needed_for_output(output_frames_needed);
|
||||
|
||||
out_unprocessed =
|
||||
output_processor->input_buffer(output_frames_before_processing);
|
||||
out_unprocessed =
|
||||
output_processor->input_buffer(output_frames_before_processing);
|
||||
|
||||
got = data_callback(stream, user_ptr,
|
||||
nullptr, out_unprocessed,
|
||||
output_frames_before_processing);
|
||||
got = data_callback(stream, user_ptr,
|
||||
nullptr, out_unprocessed,
|
||||
output_frames_before_processing);
|
||||
|
||||
if (got < 0) {
|
||||
return got;
|
||||
if (got < output_frames_before_processing) {
|
||||
draining = true;
|
||||
|
||||
if (got < 0) {
|
||||
return got;
|
||||
}
|
||||
}
|
||||
|
||||
output_processor->written(got);
|
||||
}
|
||||
|
||||
output_processor->written(got);
|
||||
|
||||
/* Process the output. If not enough frames have been returned from the
|
||||
* callback, drain the processors. */
|
||||
return output_processor->output(output_buffer, output_frames_needed);
|
||||
@ -204,11 +210,16 @@ cubeb_resampler_speex<T, InputProcessor, OutputProcessor>
|
||||
::fill_internal_duplex(T * in_buffer, long * input_frames_count,
|
||||
T * out_buffer, long output_frames_needed)
|
||||
{
|
||||
if (draining) {
|
||||
// discard input and drain any signal remaining in the resampler.
|
||||
return output_processor->output(out_buffer, output_frames_needed);
|
||||
}
|
||||
|
||||
/* The input data, after eventual resampling. This is passed to the callback. */
|
||||
T * resampled_input = nullptr;
|
||||
/* The output buffer passed down in the callback, that might be resampled. */
|
||||
T * out_unprocessed = nullptr;
|
||||
size_t output_frames_before_processing = 0;
|
||||
long output_frames_before_processing = 0;
|
||||
/* The number of frames returned from the callback. */
|
||||
long got = 0;
|
||||
|
||||
@ -243,8 +254,12 @@ cubeb_resampler_speex<T, InputProcessor, OutputProcessor>
|
||||
resampled_input, out_unprocessed,
|
||||
output_frames_before_processing);
|
||||
|
||||
if (got < 0) {
|
||||
return got;
|
||||
if (got < output_frames_before_processing) {
|
||||
draining = true;
|
||||
|
||||
if (got < 0) {
|
||||
return got;
|
||||
}
|
||||
}
|
||||
|
||||
output_processor->written(got);
|
||||
|
@ -62,11 +62,11 @@ public:
|
||||
: channels(channels)
|
||||
{}
|
||||
protected:
|
||||
size_t frames_to_samples(size_t frames)
|
||||
size_t frames_to_samples(size_t frames) const
|
||||
{
|
||||
return frames * channels;
|
||||
}
|
||||
size_t samples_to_frames(size_t samples)
|
||||
size_t samples_to_frames(size_t samples) const
|
||||
{
|
||||
assert(!(samples % channels));
|
||||
return samples / channels;
|
||||
@ -157,6 +157,7 @@ private:
|
||||
cubeb_stream * const stream;
|
||||
const cubeb_data_callback data_callback;
|
||||
void * const user_ptr;
|
||||
bool draining = false;
|
||||
};
|
||||
|
||||
/** Handles one way of a (possibly) duplex resampler, working on interleaved
|
||||
@ -282,7 +283,7 @@ public:
|
||||
* exactly `output_frame_count` resampled frames. This can return a number
|
||||
* slightly bigger than what is strictly necessary, but it guaranteed that the
|
||||
* number of output frames will be exactly equal. */
|
||||
uint32_t input_needed_for_output(uint32_t output_frame_count)
|
||||
uint32_t input_needed_for_output(uint32_t output_frame_count) const
|
||||
{
|
||||
int32_t unresampled_frames_left = samples_to_frames(resampling_in_buffer.length());
|
||||
int32_t resampled_frames_left = samples_to_frames(resampling_out_buffer.length());
|
||||
@ -461,7 +462,7 @@ public:
|
||||
* @parameter frames_needed the number of frames one want to write into the
|
||||
* delay_line
|
||||
* @returns the number of frames one will get. */
|
||||
size_t input_needed_for_output(uint32_t frames_needed)
|
||||
size_t input_needed_for_output(uint32_t frames_needed) const
|
||||
{
|
||||
return frames_needed;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user