Video Playback Help...

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
ADePSP
Posts: 58
Joined: Thu Jul 13, 2006 9:07 pm

Video Playback Help...

Post by ADePSP »

Hi, I need to add some video playback to my app... Very simple, just a rolling credits vid that plays at the end...

What is the easiest way to do this...? I'm using C and not C++ so could anyone point me at any libraries I need to download and a straight forward example of doing it in C...

I'm hopeing I just need to drop in some .h and .c files in my folder and link to them, svn some component down from the net and grab some converter to change my vid into the correct format and i'm away... Tell me it's that simple...

Like I say, I don't care which format... I just want the easiest to use...

Thanks for your help,
ADePSP
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

For scrolling credits, don't use a video, use a static image and scroll that from top of the screen to bottom (or whatever direction you want). It saves memory, is faster and a thousand times easier to implement than video playback. There's no way of just including a header and linking a lib, then have instant video playback. Video playback is much much more than loading a image and display it.
As I already told you, the currently simplest approach at some animated video playback is probably the library from Kojima. Though it does not provide very good compression ratios, it's very easy to use if you have just some basic image displaying knowledge.
ADePSP
Posts: 58
Joined: Thu Jul 13, 2006 9:07 pm

Post by ADePSP »

Raphael wrote:For scrolling credits, don't use a video, use a static image and scroll that from top of the screen to bottom (or whatever direction you want). It saves memory, is faster and a thousand times easier to implement than video playback. There's no way of just including a header and linking a lib, then have instant video playback. Video playback is much much more than loading a image and display it.
As I already told you, the currently simplest approach at some animated video playback is probably the library from Kojima. Though it does not provide very good compression ratios, it's very easy to use if you have just some basic image displaying knowledge.
Thanks, that sounds like a good idea... The reason I wanted video really is i'm making a series of tutorials based on what i've learned in the last two weeks making this app for all the new people who recently downgraded (like myself) and have found it very hard to find straight forward examples and help aimed at them (and obviously video playback would be a nice one to include)...

Cheers man, the scrolling image should work perfectly for my current needs...

ADe
adrahil
Posts: 274
Joined: Thu Mar 16, 2006 1:55 am

Post by adrahil »

Raphael wrote:There's no way of just including a header and linking a lib, then have instant video playback.
Isn't there a way with sceVideo*/vshBridge* yet for direct video playing from file?
ADePSP
Posts: 58
Joined: Thu Jul 13, 2006 9:07 pm

Post by ADePSP »

adrahil wrote:
Raphael wrote:There's no way of just including a header and linking a lib, then have instant video playback.
Isn't there a way with sceVideo*/vshBridge* yet for direct video playing from file?
There must be mate mustn't there...? I suspect nobody has written an include to wrap it all up... or nobody has posted one anywhere...
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

adrahil wrote:
Raphael wrote:There's no way of just including a header and linking a lib, then have instant video playback.
Isn't there a way with sceVideo*/vshBridge* yet for direct video playing from file?
No. There are functions that decode a stream into an RGB framebuffer (the ones from MagiKs PMF player) but you still need to read in the file correctly and provide the buffers timed correctly to the decoder function, as well as handle the display update. All the basic functionality for loading the needed prx's, setting up the decoder and decoding single frames is inside the avc.c file in PMP Mod AVC.
You can write your own file reader and buffer feeder then you get the single header include out-of-the-box playback.
ADePSP
Posts: 58
Joined: Thu Jul 13, 2006 9:07 pm

Post by ADePSP »

Well, Raphael, your idea sounded great but as soon as I load my image, 480x1923 at only 29K it crashes the PSP...

Any idea why...? Not like it's a big file...?????

Here is the VERY cut down code I was using missing all the other stuff and it came down to the fact that loadImage crashes with that file...??????

Code: Select all

void ShowScreen_Credits() {

  Image* background;
  char buffer[200];

  sprintf(buffer, "images/credits.png");
  background = loadImage(buffer);       // crashes here

  freeImage(background);

}
Here's the basic credits.png I was using as an example...????

http://www.cheatsync.net/credits.png

Little help...
ADe
User avatar
Jim
Posts: 476
Joined: Sat Jul 02, 2005 10:06 pm
Location: Sydney
Contact:

Post by Jim »

29kb on disk, 3.5Mb in memory, assuming 32bpp.

Jim
AnonymousTipster
Posts: 197
Joined: Fri Jul 01, 2005 2:50 am

Post by AnonymousTipster »

If you're using the GU, you'll need to break it down into 512x512 max chunks - the GU won't render above 512 dimensions. That won't cause the crash, but you might as well cut it down sooner than later.
Don't put that texture in VRAM either, it won't fit.
ADePSP
Posts: 58
Joined: Thu Jul 13, 2006 9:07 pm

Post by ADePSP »

@Jim, i've got 77K png files I load without problem and your ratio sounds like a major exageration there... I load whole piles of True Type font text over that also without a single problem...

@AnonymousTipster, The 77K png file (mentioned above) screen I load as a background that works perfectly is 480x272 and also loads without any problems what so ever...

I believe the height of the image is too much for the function to deal with so i'll probably have to split the png into 480x272 images and half way through loading one, load the next and so forth... What a pain in the ass this is... Oh for a library and code like this,

Code: Select all

void ShowScreen_Credits() {

  int i;
  mpeg* MyVid;
  char filename[200];
  
  sprintf(filename,"myvideo.mpeg");
  MyVid = MPEG_LOAD(filename);

  MPEG_PLAY(MyVid);

  while (1) {

     if (MPEG_ATENDOFSTREAM(MyVid) == 1) {
        break;
     }

     for &#40;i=0; i<5; i++&#41; &#123;
        sceDisplayWaitVblankStart&#40;&#41;;
     &#125;

  &#125;

  MPEG_FREE&#40;MyVid&#41;;

&#125;
Somebody must have something like this... If not, why the hell not...?

ADe
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

ADePSP wrote:@Jim, i've got 77K png files I load without problem and your ratio sounds like a major exageration there... I load whole piles of True Type font text over that also without a single problem...
The png isn't compressed anymore when loaded into ram, so Jim isn't exaggerating. 480x1923x32bit = 3692160byte = 3.6MB, and that won't fit in VRAM for sure. I doubt though that your loading function crashes, but your program crashes when you try to actually draw that big image, since graphics.c uses the gu for some of the image drawing, and the gu is restricted to 512x512 pixel images max. There are some ways around though.
Either write your own simple and dirty image blitter. Should be pretty straightforward and there are dozens of tutorials on generic blitters out there.
Some pseudo code anyway:

Code: Select all

function blit&#40; source, sx, sy, sw, sh, sdw, dest, dx, dy, ddw &#41;
source += sx + sy*sdw
dest += dx + dy*ddw
for y = 0 to sh
   for x=0 to sw
     dest++ = source++
   source += sdw
   dest += ddw
parameters sx, sy, sw, sh set the source rect you want to draw, sdw and ddw are the buffer widths of source and dest. dx and dy set the position where the image should be blitted to.
With this you can load your 480x1923 image normally, and then just set the source rect you want to blit accordingly.

Code: Select all

   for loop=0 to maxloops
      pos += 1
      if pos > img.height-272
        height = img.height-pos
      else
        height = 272
      blit&#40; img, 0, pos, 480, height, dest, 0, 0 &#41;
The other way using gu is pretty much alike, just that you increase the texture pointer to the starting pos before you send it to the gu.

Code: Select all

void ShowScreen_Credits&#40;&#41; &#123;

  int i;
  mpeg* MyVid;
  char filename&#91;200&#93;;
  
  sprintf&#40;filename,"myvideo.mpeg"&#41;;
  MyVid = MPEG_LOAD&#40;filename&#41;;

  MPEG_PLAY&#40;MyVid&#41;;

  while &#40;1&#41; &#123;

     if &#40;MPEG_ATENDOFSTREAM&#40;MyVid&#41; == 1&#41; &#123;
        break;
     &#125;

     for &#40;i=0; i<5; i++&#41; &#123;
        sceDisplayWaitVblankStart&#40;&#41;;
     &#125;

  &#125;

  MPEG_FREE&#40;MyVid&#41;;

&#125;
Somebody must have something like this... If not, why the hell not...?

ADe
I said no, so why don't you get it? Don't insist so much on other people doing the hard work for you and make it fool-proof, just so you can use everything without a hassle. If you really want something special done, then give it a try to learn yourself to do it.
You won't be getting anywhere if you don't take the effort to dive into something complex to understand it yourself.

Programming is not like playing LEGO.
ADePSP
Posts: 58
Joined: Thu Jul 13, 2006 9:07 pm

Post by ADePSP »

Raphael wrote:
ADePSP wrote:@Jim, i've got 77K png files I load without problem and your ratio sounds like a major exageration there... I load whole piles of True Type font text over that also without a single problem...
The png isn't compressed anymore when loaded into ram, so Jim isn't exaggerating. 480x1923x32bit = 3692160byte = 3.6MB, and that won't fit in VRAM for sure. I doubt though that your loading function crashes, but your program crashes when you try to actually draw that big image, since graphics.c uses the gu for some of the image drawing, and the gu is restricted to 512x512 pixel images max. There are some ways around though.
Either write your own simple and dirty image blitter. Should be pretty straightforward and there are dozens of tutorials on generic blitters out there.
Some pseudo code anyway:

Code: Select all

function blit&#40; source, sx, sy, sw, sh, sdw, dest, dx, dy, ddw &#41;
source += sx + sy*sdw
dest += dx + dy*ddw
for y = 0 to sh
   for x=0 to sw
     dest++ = source++
   source += sdw
   dest += ddw
parameters sx, sy, sw, sh set the source rect you want to draw, sdw and ddw are the buffer widths of source and dest. dx and dy set the position where the image should be blitted to.
With this you can load your 480x1923 image normally, and then just set the source rect you want to blit accordingly.

Code: Select all

   for loop=0 to maxloops
      pos += 1
      if pos > img.height-272
        height = img.height-pos
      else
        height = 272
      blit&#40; img, 0, pos, 480, height, dest, 0, 0 &#41;
The other way using gu is pretty much alike, just that you increase the texture pointer to the starting pos before you send it to the gu.

Code: Select all

void ShowScreen_Credits&#40;&#41; &#123;

  int i;
  mpeg* MyVid;
  char filename&#91;200&#93;;
  
  sprintf&#40;filename,"myvideo.mpeg"&#41;;
  MyVid = MPEG_LOAD&#40;filename&#41;;

  MPEG_PLAY&#40;MyVid&#41;;

  while &#40;1&#41; &#123;

     if &#40;MPEG_ATENDOFSTREAM&#40;MyVid&#41; == 1&#41; &#123;
        break;
     &#125;

     for &#40;i=0; i<5; i++&#41; &#123;
        sceDisplayWaitVblankStart&#40;&#41;;
     &#125;

  &#125;

  MPEG_FREE&#40;MyVid&#41;;

&#125;
Somebody must have something like this... If not, why the hell not...?

ADe
I said no, so why don't you get it? Don't insist so much on other people doing the hard work for you and make it fool-proof, just so you can use everything without a hassle. If you really want something special done, then give it a try to learn yourself to do it.
You won't be getting anywhere if you don't take the effort to dive into something complex to understand it yourself.

Programming is not like playing LEGO.
I know, i'm actually a 29 year old software developer and have programmed for 8 years but mainly work at high levels like Visual Basic, Java, .net, asp and PHP projects and mainly writing components and web stuff... This low level stuff wasn't in the training program but doesn't look as hard as it's made out to be...

I'll check over your blit ideas and see what I can do with that (thanks man) and by the way I already increased the flib includes (that someone bothered to make to help others use fonts easily) so it works 10x faster by loading the .ttf files into memory before rendering them...

I just expected after comming to the homebrew scene so late that a lot of the hard work would already have been done i.e. includes and tutorials made available for others to use... Seems not...

...By the way, programming is exactly like LEGO... You normally just keep building on top of more and more complicated structures... Seems a shame all we have to work with here is individual bricks and the odd small wall...? :D

ADe
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

ADePSP wrote: I just expected after comming to the homebrew scene so late that a lot of the hard work would already have been done i.e. includes and tutorials made available for others to use... Seems not...
Actually, most of the *really* hard work has already been done. There wouldn't be any possibility to write anything for us, if the guys here didn't take the effort to reverse engineer the whole SDK (apart from very few things which aren't found yet). I wouldn't say learning to use the sceMpeg functions to get video playback is really hard. It may take some time, but it's not something one couldn't do if he really wanted.
Fitting such stuff into such High-Level fool-proof but totally limited interfaces just to make every noob happy isn't something I'd like to do, and I could imagine others being my opinion there too.
...By the way, programming is exactly like LEGO... You normally just keep building on top of more and more complicated structures... Seems a shame all we have to work with here is individual bricks and the odd small wall...? :D
ADe
Well, I suppose LEGO to be something were you have tons of blocks lying around you, which someone magically has created before, then you just pick the one's you want and stiff them together and they magically fit.
In programming it's not possible to use every code snippet from others this way. You either need to understand why and how the other's code works and fit it to your program (thus theoretically enabling you to recreate the code yourself) or just completely write everything on your own and make it fit thereby.
Well, actually at high-level programming it's more like that (since the APIs control all the connection of different code parts), so maybe that's the reason you're insisting on such a video playback solution ;)

I myself pretty much hate having to stick to the ways others thought how programming parts should communicate. I found much of ugly implementations (I only say Windows API) which led me back to lower level programming and PSP is very nice in this manner :)
ADePSP
Posts: 58
Joined: Thu Jul 13, 2006 9:07 pm

Post by ADePSP »

Just wanted to say thanks to those who helped... I got my credits screen working by loading in 5 (count them) png files into memory and the scrolling them up using the following code...

Thanks people...

Code: Select all

void ShowScreen_Credits&#40;&#41; &#123;

  waitForButtonRelease&#40;0&#41;;

  int i = 0; 
  SceCtrlData pad;  
  Image* background&#91;5&#93;;
  char buffer&#91;200&#93;;
  int numScreens = 5;
  int current = 0;
  int next = 1;
  int currentY = 0;
  int nextY = 272;

  sprintf&#40;buffer, "images/credits_blank.png"&#41;;
  background&#91;0&#93; = loadImage&#40;buffer&#41;; 

  sprintf&#40;buffer, "images/credits1.png"&#41;;
  background&#91;1&#93; = loadImage&#40;buffer&#41;; 

  sprintf&#40;buffer, "images/credits2.png"&#41;;
  background&#91;2&#93; = loadImage&#40;buffer&#41;; 

  sprintf&#40;buffer, "images/credits3.png"&#41;;
  background&#91;3&#93; = loadImage&#40;buffer&#41;; 

  background&#91;4&#93; = background&#91;0&#93;; 

  while &#40;next < numScreens&#41; &#123; 

     blitAlphaImageToScreen&#40;0,currentY,480,272-currentY,background&#91;current&#93;,0,0&#41;;
     if &#40;nextY < 272&#41; &#123;
        blitAlphaImageToScreen&#40;0,0,480,272-nextY,background&#91;next&#93;,0,nextY&#41;;
     &#125;
     flipScreen&#40;&#41;;
     sceKernelDelayThread&#40;1200&#41;;

     sceCtrlReadBufferPositive&#40;&pad, 1&#41;; 
 
     if &#40;pad.Buttons != 0&#41; &#123;
        break;
     &#125; 

     for &#40;i=0; i<2; i++&#41; &#123;
        sceDisplayWaitVblankStart&#40;&#41;;
     &#125;

     currentY++;
     nextY--;

     if &#40;nextY == 0&#41; &#123;
        current++;
        next++;
        currentY = 1;
        nextY = 271;
     &#125;

  &#125;

  blitAlphaImageToScreen&#40;0,0,480,272,background&#91;0&#93;,0,0&#41;;
  flipScreen&#40;&#41;;
  waitForButtonRelease&#40;0&#41;;

  freeImage&#40;background&#91;0&#93;&#41;;
  freeImage&#40;background&#91;1&#93;&#41;;
  freeImage&#40;background&#91;2&#93;&#41;;
  freeImage&#40;background&#91;3&#93;&#41;;

&#125;
Not sure why I could load 5 screens in at the start with no problem but to load one big pic with all of them in causes a crash but nevermind... This works...

ADe
User avatar
dot_blank
Posts: 498
Joined: Wed Sep 28, 2005 8:47 am
Location: Brasil

Post by dot_blank »

most likely cuz your large image exceeded the
GUs' texture limit which is 512x512 so if it had
dimensions of 480x2145 then it would crash
10011011 00101010 11010111 10001001 10111010
Kojima
Posts: 275
Joined: Mon Jun 26, 2006 3:49 am

Post by Kojima »

I've done scrolling credits lots of times (I love the hollywood feel of it) and I've never needed movies or images. What I suggest doing is, writing a font renderer, be it truefront or bitmap based(I used bitmap personally) and then just write a simple credits system that scrolls the text up and down and clips them.

The upside of this is you can add fx, or scale the fonts based on screen position to give it a more dynamic feel.

just an idea.
Samstag
Posts: 5
Joined: Thu Nov 24, 2005 10:41 am

Post by Samstag »

ADePSP wrote:Not sure why I could load 5 screens in at the start with no problem but to load one big pic with all of them in causes a crash but nevermind...
Because you're dereferencing a NULL pointer in your calls to blitAlphaImageToScreen().

if(background == NULL) yourImageIsInvalid();
Post Reply