代码审查所需的帮助。 (大胆)(C)

时间:2010-10-18 10:44:37

标签: c

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。什么时候会结束?

2 个答案:

答案 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_audiooutput_write_audio不可分割吗?这个想法的两个原因:对于缓冲和非缓冲情况都有相同的写处理程序似乎很奇怪,并且在COP->buffer_free之前调用->write_audio,因此它可以根据需要改变COP要做。

如果失败了,那么longjmp是可能的:代码中的所有g_unsleepnew_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参数调用。