Solved

How does Media Player work??

Posted on 2002-04-17
12
585 Views
Last Modified: 2010-04-04
I have asked similar questions before but still can't crack this one.

How does somthing like MS Media player display movies without flicker and at a good frame rate?  When I try to display a sequence of images it is much slower, flickers (sometimes), and is much slower in W2k or XP. I can't just use the Delphi media component because I need to display a sequence of images received across a network connection in a proprietry format rather than from a file.

I just need to know the technique Media Player uses for displaying images - or something better!?

John
0
Comment
Question by:jellison
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 3
  • 2
  • +3
12 Comments
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6947944
listening . . .

hint: use a tpanel as playing background
0
 
LVL 12

Expert Comment

by:Lee_Nover
ID: 6948349
well Media Player uses DirectShow
the best choise for DirectShow is DSPack from www.progdigy.com
you can (dis)play any media type supported by windows

if you send images over the network you can simply use TImage and use the LoadFromStream method to display the image
set the TImages DoubleBuffered property to true, that will get rid of the flickering
you can do it with any TWinControl
0
 
LVL 34

Expert Comment

by:Slick812
ID: 6948406
what sort of image display do U use? A TImage? I have had so many problems with a TImage and flicker that I almost never use a TImage any more. If you just draw on your Forms Canvas or use a TPaintBox for display, works better for animation. In animation display if you draw on a visible area twice (or more) then the monitors refresh rate will cause flicker when the first Draw is in a different refresh than the second draw. I'm not sure about the W2k and XP system differences, seems like it would be more a video card and monitor difference? Also, you don't say what sort of animation timing you use (if any), a TTimer does not work in animation timing. Here is some code for a graphics app's About Box Form, which uses a couple of Paint Boxes for scrolling text animations. I don't have time to redo this for you, but it has code in it for Paint Box animations and a muti-media timer. This timer starts when the form is activated.


unit about1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls, mmsystem;

{$R BACKGND.RES}

type
  TAbout = class(TForm)
    OKbutton: TButton;
    PaintBox1: TPaintBox;
    PaintBox2: TPaintBox;
    procedure FormCreate(Sender: TObject);
    procedure OKbuttonClick(Sender: TObject);
    procedure PaintBox1Paint(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure PaintBox2Paint(Sender: TObject);
  private
    { Private declarations }
    ScrollStr, TextStr: String;
    Backgnd1, Scroll1, TextBack: TBitmap;
    P1Rect: TRect;
    Wid, position, posit2, TextWidth, borderPos: Integer;
    Region1 : HRGN;
    TimerID: Cardinal;
    TimeCaps: TTimeCaps;
    procedure WMEraseBkgnd (var Msg : TMessage); message WM_ERASEBKGND;
    procedure MoveIt;
    procedure TextScroll;
    procedure DrawBorder;
  public
    { Public declarations }
  end;

var
  About: TAbout;

implementation

{$R *.DFM}

procedure TAbout.FormCreate(Sender: TObject);
var
X: Integer;
TempBit: TBitmap;
begin
{intialize variables}
position := PaintBox1.Width;
Wid := PaintBox1.Width;
posit2 := 1;
BorderPos := 0;
TimerID := 0;
ScrollStr := 'This is the about box to tell you how great this is, WOW!';
TextStr := 'you got Version 76543210.56789 build 65839 and a half . . . ';

Backgnd1 := TBitmap.Create;
{Backgnd1  is the About Form's Background}
Backgnd1.LoadFromResourceName(hInstance,'BACKGND');

TempBit := TBitmap.Create;
{TempBit  is the background for the Scroll1  bitmap}
TempBit.LoadFromResourceName(hInstance,'PARCH1');

Scroll1 := TBitmap.Create;
Scroll1.Canvas.Font.Name := 'SuperFont8t'{'MS Sans Serif'} {'Arial'};
{the "SuperFont8t" is here just to see what font will be used if
the font Name you set is not availible}
Scroll1.Canvas.Font.Size := 12;
Scroll1.Canvas.Font.Color := clBlue;
Scroll1.Width := Scroll1.Canvas.TextWidth(ScrollStr+'  ');
Scroll1.Height := Scroll1.Canvas.TextHeight('T')+8;
X := 0;
while X < Scroll1.Width do
  begin
  Scroll1.Canvas.Draw(X, 0, Tempbit);
  Inc(X, TempBit.Width);
  end;
Scroll1.Canvas.Brush.Style := bsClear;
Scroll1.Canvas.TextOut(Scroll1.Canvas.TextWidth(' '), 4, ScrollStr);
PaintBox1.Height := Scroll1.Height;
P1Rect:= PaintBox1.ClientRect;

FreeAndNil(TempBit);

TextBack := TBitmap.Create;
TextBack.Canvas.Font.Name := 'MS Serif';
TextBack.Canvas.Font.Size := 12;
TextBack.Canvas.Font.Color := clRed;
TextBack.Width := PaintBox2.Width;
TextBack.Height := TextBack.Canvas.TextHeight('T')+4;
BitBlt(TextBack.Canvas.Handle, 0, 0, TextBack.Width, TextBack.Height,
Backgnd1.Canvas.Handle, PaintBox2.Left, PaintBox2.Top, SRCCOPY);
PaintBox2.Height := TextBack.Height;

TextWidth := TextBack.Canvas.TextWidth(TextStr+'  ');

Region1 := CreateEllipticRgn(0,0,Width,Height);
SetWindowRgn(Handle, Region1, TRUE);
{the 2 lines above create a Region and set it to your
About form. Remove these 2 lines and the "DeleteObject(Region1);"
line in FormDestroy if you don't want a Shaped Form}

TimeGetDevCaps(@TimeCaps, sizeof(TimeCaps));
TimeBeginPeriod(TimeCaps.wPeriodMin);
{the 2 lines above are NEEDED to set up your MultiMedia Timer
which is much better for movement, animation, sprite drawing than
a TTimer. See the  FormActivate  procedure at TimeSetEvent() }

Canvas.Brush.Style := bsClear;
{bsClear is needed for the  DrawBorder}
{Canvas.Pen.Width := 2;}
end;

procedure TAbout.WMEraseBkGnd;
begin
{this is the Windows System message to Erase (redraw)
the forms Background, it seems like many delphi users use a
TImage as a forms background, but I have had so many problems
(flicker and overdraw) with that, I never use it as background anymore}
BitBlt(Msg.WParam, 0, 0, Width, Height,
Backgnd1.Canvas.Handle, 0, 0, SRCCOPY);
{this only works well on forms that can NOT be resized}
Msg.Result := 1;
end;

procedure TAbout.OKbuttonClick(Sender: TObject);
begin
timeKillEvent(TimerID);
Close;
end;

procedure TAbout.DrawBorder;
{there are many ways to do a moving border}
begin
if BorderPos > 2 then
BorderPos := 0;
case BorderPos of
0: Canvas.Pen.Color := clRed;
1: Canvas.Pen.Color := clYellow;
2: Canvas.Pen.Color := clAqua;
end;
Canvas.Ellipse(6,6,Width-6,Height-5);
case BorderPos of
0: Canvas.Pen.Color := clAqua;
1: Canvas.Pen.Color := clRed;
2: Canvas.Pen.Color := clYellow;
end;
Canvas.Ellipse(4,4,Width-4,Height-3);
case BorderPos of
0: Canvas.Pen.Color := clYellow;
1: Canvas.Pen.Color := clAqua;
2: Canvas.Pen.Color := clRed;
end;
Canvas.Ellipse(2,2,Width-2,Height-1);
Canvas.Pen.Color := clWhite;
Canvas.Ellipse(1,1,Width-1,Height);
Inc(BorderPos);
end;

procedure TAbout.PaintBox1Paint(Sender: TObject);
begin
PaintBox1.Canvas.Draw(0, 0, Scroll1);
DrawEdge(PaintBox1.Canvas.Handle, P1Rect, EDGE_SUNKEN, BF_RECT);
end;

procedure TAbout.MoveIt;
var
Pos1, Pos2: Integer;
begin
 if position > Scroll1.Width then
position := 1;
if position < Wid then
       begin
       Pos1 := Wid - (position);
       Pos2 := 0;
       end else
       begin
       Pos1 := 0;
       Pos2 := (position)-Wid;
       end;
     BitBlt(PaintBox1.Canvas.Handle, 0, 0, Wid, Scroll1.Height,
          Scroll1.Canvas.Handle, (Scroll1.Width-Wid)+position, 0, SRCCOPY);
     BitBlt(PaintBox1.Canvas.Handle, Pos1, 0, Wid, Scroll1.Height,
          Scroll1.Canvas.Handle, Pos2, 0, SRCCOPY);
     DrawEdge(PaintBox1.Canvas.Handle, P1Rect, EDGE_SUNKEN, BF_RECT);
     
     TextScroll;
     if (position mod 5) = 0 then DrawBorder else
     Sleep(1);
     Inc(position);

end;

procedure TAbout.TextScroll;
begin

if posit2 > TextWidth+PaintBox2.Width then
posit2 := 1;
BitBlt(PaintBox2.Canvas.Handle, 0, 0, TextBack.Width, TextBack.Height,
          TextBack.Canvas.Handle, 0, 0, SRCCOPY);
PaintBox2.Canvas.TextOut(PaintBox2.Width-posit2, 2, TextStr);
Inc(posit2);
end;

procedure TimerProc(uTimerID, uMessage: cardinal; dwUser, dw1, dw2: integer); stdcall;
begin
About.MoveIt;
end;

procedure TAbout.FormActivate(Sender: TObject);
var
Interval,Accur: Word;

begin
timeKillEvent(TimerID);
Interval := 26;
Accur := Interval div 2;
if Accur < TimeCaps.wPeriodMin then
Accur := TimeCaps.wPeriodMin;
if Accur > TimeCaps.wPeriodMax then
Accur := TimeCaps.wPeriodMax;
if Scroll1.Width > PaintBox1.Width+3 then
TimerID := TimeSetEvent(Interval, Accur, @TimerProc, 10, TIME_PERIODIC);

end;

procedure TAbout.FormDestroy(Sender: TObject);
begin
timeKillEvent(TimerID);
TimeEndPeriod(TimeCaps.wPeriodMin);
DeleteObject(Region1);
FreeAndNil(Scroll1);
FreeAndNil(Backgnd1);
FreeAndNil(TextBack);
end;

procedure TAbout.PaintBox2Paint(Sender: TObject);
begin
PaintBox2.Canvas.Font := TextBack.Canvas.Font;
PaintBox2.Canvas.Brush.Style := bsClear;
BitBlt(PaintBox2.Canvas.Handle, 0, 0, TextBack.Width, TextBack.Height,
          TextBack.Canvas.Handle, 0,0, SRCCOPY);
end;

end.


- - - - - - - - - - - - - - - - - - - - - - -

but if you only draw on a visible area once in a procedure then you should not have many flicker problems (Excluding a TImage). And if you use the paintbox animation, you may want to NOT have doubleBuffereing enabled.
Ask questions if you need help. Wes
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 9

Expert Comment

by:ginsonic
ID: 6949682
Set the ControlStyle to csOpaque.
0
 
LVL 9

Expert Comment

by:ginsonic
ID: 6949683
And I suggest to use a bitmap with same canvas dimensions and there paint all frame ( if you use many images for this frame ). Then paint this ( hidden ) bitmap into wished canvas .

I use this and allways work perfect .
0
 
LVL 1

Author Comment

by:jellison
ID: 6950170
Thanks everyone - especially Wes (again) for your comments.

I am going to give the points to Slick812 but I would like to keep it open for a little while longer. The use of an MMsystem timer and not using Timages seems to be key to things but I still have an issue with W2k and XP. I have a machine which I can boot up in 98SE or W2k or XP. I am running a test app which does a Stretchblt of two different images (one smaller than the dest, one bigger) and times the blt.
In 98 the two blts take around 11 and 20ms respectively - and consistently. In W2k they take 25 and 50ms respectively - but if you move the mouse over the image when it's painting the they rise to about 35 and 110ms and you can see it slows down. It was much worse than this but I have just put the latest ATI drivers on and that has improved things somewhat.
Is the W2k/XP Stretchblt slower that W98 or do I just need to give something more priority and/or different property settings?  If so, what are they?

John
0
 
LVL 34

Accepted Solution

by:
Slick812 earned 200 total points
ID: 6954988
I'm not aware of changing anything in the system for graphics functions to be more effecient in a certain Windo's system W2k or XP. Accoring to the MS hype for the W2k system, it's suppose to be more efficient for graphics than the Win 9x, but then there was the video card drivers problems, but it's been out long enough now that most all the cards have a W2k driver that works. What size of a rect (image) do you get the 20ms in Win 9x? Is it the same size in W2k?
0
 
LVL 1

Author Comment

by:jellison
ID: 6955701
It's exactly the same size - same program, same images.
It's almost as if the blt is being done in software rather than using the hardware acceleration features of the card - an ATI Rage Pro btw. And Windows is set to use max acceleration.
The destination rect is about 400x300. The 20ms image is a bit bigger so it's being reduced in the stretchblt.

John
0
 
LVL 1

Expert Comment

by:pnh73
ID: 9003334
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

Accept answer from Slick812

Please leave any comments here within the next seven days.
 
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
 
Paul (pnh73)
EE Cleanup Volunteer
0
 
LVL 1

Expert Comment

by:pnh73
ID: 9004803
Thank you for your reponse

Paul (pnh73)
EE Cleanup Volunteer
0
 
LVL 1

Author Comment

by:jellison
ID: 9005692
Thanks for the reminder. It must be a thankless task.
I was going to post an apology (which is what I am doing now!) but the new web page design is struggling to give me a decent size comment box in any browser except IE - and even IE is giving me a Java error :o|
Anyway apologies for not closing it when I should.
0
 
LVL 1

Expert Comment

by:pnh73
ID: 9006144
It is rather tedious. I have gone through ~ 150 posts today, and more are still to come!

Paul (pnh73)
EE Cleanup Volunteer
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
This is a high-level webinar that covers the history of enterprise open source database use. It addresses both the advantages companies see in using open source database technologies, as well as the fears and reservations they might have. In this…
In this video, viewers are given an introduction to using the Windows 10 Snipping Tool, how to quickly locate it when it's needed and also how make it always available with a single click of a mouse button, by pinning it to the Desktop Task Bar. Int…

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question