Требуется помощь при просмотре кода.(дерзко) (с) - PullRequest
4 голосов
/ 18 октября 2010
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 * selected = NULL;... если (данные! = выделено) я в замешательстве .. какова цель этого?я не видел, что выделено изменилось

Q2.как вы можете видеть, CP-> write_audio будет вызывать do_write, который будет вызывать CP-> write_audio.когда это закончится?

Ответы [ 2 ]

1 голос
/ 20 октября 2010

Q1: пусто * выделено = 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 не равно нулю (обычно это) и (ii) с выводом COP->buffer_free ()

0 голосов
/ 18 октября 2010

В output_write_audio () у вас есть переменная new, которая установлена ​​в

gfloat * new = g_malloc (sizeof (gfloat) * samples);

и затем:

allocated = new;

Таким образом, время от времени устанавливается для выделенного массива сэмплов с плавающей запятой. Мне кажется, что выделенный объект будет освобожден время от времени, даже если в нем будет значение NULL. Если вы можете запустить код, вы можете проверить это, вставив функцию-обертку вокруг g_free (), которая может отслеживать вызовы и определять, вызван ли он с аргументом NULL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...