ThinkMeta LogoDeutsch
English
LAME: Asynchronous frame processing

Uncompressed frames pass several stages during the encoding process. They are shown in the following picture:

Frame-Bearbeitung in LAME

The processing of one frame depends on the results of his predecessor.

The pseudo code (imperative) is as follows:

MP3EncodeFrames(frames)
{
  frames[0] = InitializeFirstFrame();

  for (f = 1; f < frames.count; ++f) {
    SampleConverter(frames[f], frames[f - 1]);
    ReplayGain(frames[f], frames[f - 1]);
    PsychoAcoustics(frames[f], frames[f - 1]);
    MDCT(frames[f], frames[f - 1]);
    Quantizer(frames[f], frames[f - 1]);
    BitStream(frames[f], frames[f - 1]);
  }
}

The search for parallelizable elements in this code is hardly reasonable, because one frame is processed in less than 1 msec on current processors.
Also the loop cannot be parallelized because of the dependencies.

It looks different if an asynchronous programming language is used: In this case, the function "MP3EncodeFrames" can be written in a way, where the potential for parallelization becomes visible – even if finally no parallelization is possible:

MP3EncodeFrames(frames)
{
  frames[0] = InitializeFirstFrame();

  SampleConverter(frames);
  ReplayGain(frames);
  PsychoAcoustics(frames);
  MDCT(frames);
  Quantizer(frames);
  BitStream(frames);
}

And representative for the other asynchronous tasks:

SampleConverter(frames)
{
  for (f = 1; f < frames.count; ++f)
    SampleConverter(frames[f], frames[f - 1]);
}

The processing times of the particular tasks are in the range of seconds, thus, a possible parallelization may lead to a significant performance gain.

Implementation in fpMP3:
"MP3EncodeFrames" was implemented as C++ class "LAMEEncoder". Parts of the function were moved to the class "MP3EncodingTask" for organizational reasons.