Indeed it seems GetDataLineStart works fine. I wonder though, how much time one cycle takes in total (image re-creation and display). Note that for very quick things in milliseconds, you need to run the operation 15 times and then divide the resulting time by 15. Because the time is measured by lumps of 15 ms so if it takes 12 ms you will get either that it took 0 ms or 15 ms.
I wonder if you need to free the Img object.
In fact you could do a Move to copy one whole line at once:
for y:= Img.Height-1 downto 1 do // shift image 1 row down (waterfall)
move(Img.GetDataLineStart(y-1)^, Img.GetDataLineStart(y)^, sizeof(TRGBTriple)*Img.Width );