static void do_write (void * data, gint samples)
{
void * allocated = NULL;
samples = flow_execute (get_postproc_flow (), 0, & data, sizeof (gfloat) *
samples, FMT_FLOAT, effect_rate, effect_channels) / sizeof (gfloat);
if (data != allocated)
{
g_free (allocated);
allocated = NULL;
}
apply_software_volume (data, output_channels, samples / output_channels);
if (output_format != FMT_FLOAT)
{
void * new = g_malloc (FMT_SIZEOF (output_format) * samples);
audio_to_int (data, new, output_format, samples);
data = new;
g_free (allocated);
allocated = new;
}
if (output_format == FMT_S16_NE)
{
samples = flow_execute (get_legacy_flow (), 0, & data, 2 * samples,
output_format, output_rate, output_channels) / 2;
if (data != allocated)
{
g_free (allocated);
allocated = NULL;
}
}
if (COP->buffer_free == NULL)
COP->write_audio (data, FMT_SIZEOF (output_format) * samples);
else
{
while (1)
{
gint ready = COP->buffer_free () / FMT_SIZEOF (output_format);
ready = MIN (ready, samples);
COP->write_audio (data, FMT_SIZEOF (output_format) * ready);
data = (char *) data + FMT_SIZEOF (output_format) * ready;
samples -= ready;
if (samples == 0)
break;
g_usleep (50000);
}
}
g_free (allocated);
}
//This function is where COP->write_audio point to.
static void output_write_audio (void * data, gint size)
{
gint samples = size / FMT_SIZEOF (decoder_format);
void * allocated = NULL;
LOCK;
frames_written += samples / decoder_channels;
UNLOCK;
if (decoder_format != FMT_FLOAT)
{
gfloat * new = g_malloc (sizeof (gfloat) * samples);
audio_from_int (data, decoder_format, new, samples);
data = new;
g_free (allocated);
allocated = new;
}
apply_replay_gain (data, samples);
vis_runner_pass_audio (frames_written * 1000 / decoder_rate, data, samples,
decoder_channels);
new_effect_process ((gfloat * *) & data, & samples);
if (data != allocated)
{
g_free (allocated);
allocated = NULL;
}
do_write (data, samples);
g_free (allocated);
}
Q1:void * allocated = NULL; ... if(数据!=已分配) 我很困惑..这是什么目的?我没有看到分配被更改
Q2。你可以看到CP-> write_audio将调用do_write,它将调用CP-> write_audio。什么时候会结束?
答案 0 :(得分:1)
Q1:void * allocated = NULL; ......如果(数据!=分配)我很困惑..这个目的是什么?我没有看到分配被更改
data
的地址作为参数传递给flow_execute
。因此,该过程可以使data
成为NULL
指针,这会使测试失败。同样,data
在进入时可能是NULL
。
使用allocated
似乎有点奇怪,但我的直觉是这两次发生,就是跟踪flow_execute
是否改变data
的存储方式,这将是导致allocated
不再等于data
。然后可以执行后处理。一个猜测。
Q2。你可以看到CP-> write_audio将调用do_write,它将调用CP-> write_audio。什么时候会结束?
看起来很奇怪。另一个猜测:你确定COP->write_audio
与output_write_audio
不可分割吗?这个想法的两个原因:对于缓冲和非缓冲情况都有相同的写处理程序似乎很奇怪,并且在COP->buffer_free
之前调用->write_audio
,因此它可以根据需要改变COP要做。
如果失败了,那么longjmp是可能的:代码中的所有g_unsleep
和new_effect_process
,似乎都不可能,但这对于处理事情来说是一种丑陋的方式。如果我们谈论的是脏代码,那些看起来像程序的东西就可能是伪装的宏......
do_write
将从while-true循环中断,取决于满足的一些复杂条件,如果(i)COP->buffer_free
为非null(它“通常和(ii)涉及{的输出{1}}
答案 1 :(得分:0)
在output_write_audio()中,你有变量new
,它被设置为
gfloat * new = g_malloc (sizeof (gfloat) * samples);
然后:
allocated = new;
因此,对一个已分配的float样本数组分配一次。在我看来,即使在它中有一个NULL值,分配也会偶尔释放一次。 如果你可以运行代码,可以通过在g_free()周围插入一个包装器函数来检查这个问题,它可以跟踪对它的调用并告诉它是否用NULL参数调用。