Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Звук, графика и видео > Перестает обновляться TImage из потока


Автор: TechnoMag 19.2.2016, 12:32
Пишу плейер с использованием bass.dll, визуализацию звука взял из примеров bass с некоторыми упрощениями.

Обновление TImage происходит из потока. 
Проблема в том, что через какое-то время обновление TImage не происходит. Поток при этом работает, и никаких ошибок в лог не пишет (я здесь намеренно убрал строки логирования). TFFTData bass выдает без ошибок.
Интервал "замерзания" не предсказуем.
Использование BitBlt дает тот же эффект.
Пробовал рандомно рисовать прямоугольник без вызовов фнукций bass - тот же эффект.


Код

procedure TForm1.drawVisualEffect(const x, y, width, height: integer; {CanvasHandle:HWND}dCanvas: TCanvas); 
var
  Rect1:TRect;
begin
  //BitBlt(PaintBox1.Canvas.Handle, 0, 0, Width, Height, CanvasHandle, 0, 0, srccopy);
    Rect1 := Rect(x, y, width, height);
    Image1.Canvas.CopyRect(Rect1, dCanvas, Rect1);
end;

procedure TSpectrum.UpdateView;
begin
  if FVisual<>nil then
    FVisual.drawVisualEffect(0, 0, VisBuff.Width, VisBuff.Height, VisBuff.Canvas);
end;

procedure TSpectrum.Draw(FFTData : TFFTData; X, Y : Integer);
        var i, YPos : LongInt; YVal : Single;
       begin

          VisBuff.Canvas.Pen.Color := PenColor;

                     VisBuff.Canvas.Pen.Color := PenColor;
                     VisBuff.Canvas.Brush.Color := PenColor;
                     VisBuff.Canvas.Rectangle(0, 0, 10, Random(20));


          //BitBlt(FPaintBoxHandle, 0, 0, VisBuff.Width, VisBuff.Height, VisBuff.Canvas.Handle, 0, 0, srccopy)
       end;

procedure TSpectrum.Execute;
var
  FFTFata : TFFTData;
begin
  inherited;
  while not Terminated do
  begin
     if Terminated then
         exit;
     
     if (FStream<>0) and
        (BASS_ChannelIsActive(FStream) = BASS_ACTIVE_PLAYING) then
     begin
        try
          BASS_ChannelGetData(FStream, @FFTFata, BASS_DATA_FFT1024);
          Draw(FFTFata, 0, 0);
          synchronize(UpdateView);
        except
          on E:Exception do
            TLogger.sendError('draw error: ' + E.messsage);
        end;
     end;
     sleep(200);
  end;
end;



Автор: Alexeis 19.2.2016, 14:19
VisBuff это TBitMap? Вообще неоконные компоненты плохо подходят для отрисовки в динамике. Криво это работает. А с потоком еще сложнее. Перед отрисовкой в потоке нужно залочить канвас, чтобы графический дескриптор не уничтожили до окончания отрисовки. И в потоке нельзя делать ничего такого, что связанно с отсылкой сообщений окну. Этот момент не так очевиден, поскольку что делает VCL внутри так сразу не скажешь. Более типичен подход, когда вычисляют в дополнительном потоке, а рисуют в главном.

Автор: TechnoMag 20.2.2016, 15:58
Да, VisBuff - это TBitmap. А какой компонент тогда посоветуете?
Как можно было бы еще реализовать механизм визуализации? Видимо я не стой точки зрения смотрю....

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)