I have a camcorder that records AVCHD (ie x264 1080p) video which I can then put on an SD card and play in my blu-ray player. This is very handy for showing home movies to my family that I've recorded.
But what about my older HDV movies? It is much less convenient to hook up my older HDV camera and play the digital tapes on my TV. I'd much rather use the same SD card trick that I use with my newer camcorder.
Here's how to convert HDV videos to a format that will work on my blu-ray player (and presumably others) and also my newer camcorder.
1 - download MultiAVCHD (see http://www.afterdawn.com/guides/archive/create_avchd_and_blu-ray_discs_with_multiavchd.cfm for a guide) . I am using build 771.
2 - Get the test program and install dependency libs/programs from this link: http://multiforum.deanbg.com/viewtopic.php?f=7&t=17
Make sure the test program is passing all its tests.
3 - from the "Settings" tab, I used all defaults (except the destination folder). You can mess with 64-bit x264 if you are brave.
4 - click on the "media" tab and "Add Video files". Add your .m2t files you extracted with your HDV camera.
5 - your .m2t files should show up in a window below the "Add Video Files" button. Select them all (might have to do this one by one) and click "Transcode"
6 - Change the "Resize" drop-down in the upper right to 1920x1080 (I had to scroll down). UPDATE: Changing the resize default of 1440x1080 may not be necessary.
7 - The bitrate for mine defaulted to about 25000, I just left it at this default.
8 - As for quality, I've tried both "1 pass Turbo" and "2 pass VHQ" and both worked. So if you are in a hurry, use 1-pass, if you want quality, use 2 pass.
9 - click "Apply"
10 - close the "properties" dialog by clicking "ok"
11 - click "Start"
12 - a new dialog will pop up. Choose "TV / Camcorder (NTSC / 60 Hz)"
13 - good luck!
Friday, December 28, 2012
Saturday, December 22, 2012
More data on "REPEAT" command behavior
So today I pulled out a random disc from my collection and it turned out to be Cliff Hanger. I haven't played this disc in literally 10 years so I was nervous to see how it had held up. Fortunately, it seems to be in the same condition it was 10 years ago; no rot!
This is the first time I've captured the VBI on Cliff Hanger, and I learned (to my surprise) that all of the frame numbers are stored in the second field of each frame, which is the same "trick" that Firefox and Freedom Fighter use (although I have to admit, I have never understood what the benefit of doing this is). So it turns out that this disc was a good test for this situation.
Again, I told it to do two passes and to stop on frame 298 (because there is where a natural break in Cliffy's attract mode is).
When it gets to the track that houses frame 298, it displays the first field (which contains no frame number). Then it displays the VBI for the second field (which DOES have the frame number 298) and displays the first few lines of the field, and then black. For the purposes of Dexter, I feel comfortable always displaying a completely black field in this case.
It seems pretty evident that when the frame number is read from the VBI, that the search is intended to take place ASAP and no further fields are intended to be displayed.
Now, what does it do on the second pass?
It overshoots by 1 frame every time.
So in this case, if I tell it to stop on frame 298, it will stop on frame 299. I've tested this by telling it to stop on frames 298, 299, and 300 and it always overshoots by 1.
Next I am going to test on a disc with conventional VBI (ie the frame numbers on the first field instead of the second) and hopefully with all of this data, I will be able to come up with an algorithm for predicting whether it will stop on the requested frame over overshoot by 1.
UPDATE : Just tried Dragon's Lair 2 disc and it is organized the same way as Cliff Hanger, with the frame number appearing on the second field. Maybe something is wrong on my end!
UPDATE #2 : Just tried Time Traveler and the frame numbers come on the first field of the frame. The disc still overruns by 1 frame when pausing. So it looks like the 2:3 pulldown case is an exception which I will need to study a bit more before I can predict how it will behave.
UPDATE #3 : I just went back to the 2:3 pulldown disc and noticed it is also overrunning by 1 frame, but the frame it overruns into has no frame number which is why it appears to not overrun. So that settles it. It will always overrun into the next track no matter what! Now to code this up and write some unit tests...
This is the first time I've captured the VBI on Cliff Hanger, and I learned (to my surprise) that all of the frame numbers are stored in the second field of each frame, which is the same "trick" that Firefox and Freedom Fighter use (although I have to admit, I have never understood what the benefit of doing this is). So it turns out that this disc was a good test for this situation.
Again, I told it to do two passes and to stop on frame 298 (because there is where a natural break in Cliffy's attract mode is).
When it gets to the track that houses frame 298, it displays the first field (which contains no frame number). Then it displays the VBI for the second field (which DOES have the frame number 298) and displays the first few lines of the field, and then black. For the purposes of Dexter, I feel comfortable always displaying a completely black field in this case.
It seems pretty evident that when the frame number is read from the VBI, that the search is intended to take place ASAP and no further fields are intended to be displayed.
Now, what does it do on the second pass?
It overshoots by 1 frame every time.
So in this case, if I tell it to stop on frame 298, it will stop on frame 299. I've tested this by telling it to stop on frames 298, 299, and 300 and it always overshoots by 1.
Next I am going to test on a disc with conventional VBI (ie the frame numbers on the first field instead of the second) and hopefully with all of this data, I will be able to come up with an algorithm for predicting whether it will stop on the requested frame over overshoot by 1.
UPDATE : Just tried Dragon's Lair 2 disc and it is organized the same way as Cliff Hanger, with the frame number appearing on the second field. Maybe something is wrong on my end!
UPDATE #2 : Just tried Time Traveler and the frame numbers come on the first field of the frame. The disc still overruns by 1 frame when pausing. So it looks like the 2:3 pulldown case is an exception which I will need to study a bit more before I can predict how it will behave.
UPDATE #3 : I just went back to the 2:3 pulldown disc and noticed it is also overrunning by 1 frame, but the frame it overruns into has no frame number which is why it appears to not overrun. So that settles it. It will always overrun into the next track no matter what! Now to code this up and write some unit tests...
Friday, December 21, 2012
How "REPEAT" command on LDP-1450 works (detailed)
I didn't want to do any guesswork about how the REPEAT command works on the LDP-1450 so I set up a video capture of a disc running through a REPEAT sequence, complete with VBI lines.
First I search to frame 1 (0x43 0x30 0x30 0x30 0x30 0x31 0x40).
While in STILL frame mode, I issued a REPEAT command using the following bytes:
0x44 0x30 0x30 0x33 0x00 0x00 0x40 (from current position, play til frame 300)
0x30 0x32 0x40 (play through this sequence 2 times)
What this means is:
From frame 1, play until frame 300, then seek back to frame 1, and play again until frame 300 then pause in still mode.
But there are some unanswered questions. Will it really pause exactly on frame 300? And when it searches back to frame 1, will we see any of frame 300 before it performs the search?
Hence the reason for me video capture.
Here is what happens:
The full frame 1 is displayed (which makes sense since it was previously STILL'd) as are all the frame up to and including frame 299. Then the VBI data for the field where frame 300 begins is displayed (I captured it successfully) but the image itself is blanked out and a search begins. So the actual frame 300 is never shown.
On the second pass (the final pass), it's a little different.
Not only is the full frame 300 displayed, but the disc doesn't pause until it gets to frame 301. (this struck me as a bit odd but I verified it on a real LDP-1450 so I don't know what to say except it must be right).
UPDATE : This behavior is different depending on which frame we tell it to repeat to. And the disc I am testing with is a 2:3 pulldown disc which seems to have an effect. If the frame number occurs in the second field of the frame, the STILL pauses on that frame. But if the frame number occurs in the first field of the frame, it pauses on the next frame. At least that's what I've observed. I guess I will need to test with some other discs.
Thursday, December 20, 2012
Added some more LDP-1450 commands
In order to add support for text overlay to my LDP-1450 code, I decided to get Dexter working with Dragon's Lair 2. As it turns out, Dragon's Lair 2 sends a bunch of commands upon bootup to the LDP-1450 to make sure it is in a sane default state. I don't actually have to do any processing of these commands (like I said they just put the player into a default state which I am already in) but I do need to acknowledge them anyway. The commands I now acknowledge include:
0x62 (motor on)
0x6E (CX on)
0x27 (video on)
0x28 (picture stop code enable)
0x55 (frame mode)
0x24 (audio on)
Dragon's Lair 2 also issues a 0x67 (status inquiry) command which I do not have documentation for. I confirmed (by using my real LDP-1450) that when the player is playing, it will return 0x80 0x00 0x10 0x00 0x01 and when the player is paused (still frame mode) it will return 0x80 0x00 0x10 0x00 0x20. I can't think of what other state the player possibly could be in except maybe in the middle of a search and playing backward or at a different speed. I am not sure how much I need to explore this since DL2 probably just wants to know if the disc is playing or paused and other games probably don't care at all. I guess this is one thing I can leave barely implemented for now and add richer support for later if it becomes required.
After adding the bare bones status inquiry response, I can get wookin' on the text overlay stuff.
Wednesday, December 19, 2012
Dexter can now emulate a Sony LDP-1450!
I've been working hard (lately) on adding support for players that use a serial interface and the first one I decided to tackle was the Sony LDP-1450 (and 1000A).
I haven't quite finished with this. The items left to be done are:
- Add support for the "repeat" command which is used in some games
- Add support for the text overlay used in Dragon's Lair 2 and Space Ace '91 (this should be fun, I am looking forward to it)
I haven't quite finished with this. The items left to be done are:
- Add support for the "repeat" command which is used in some games
- Add support for the text overlay used in Dragon's Lair 2 and Space Ace '91 (this should be fun, I am looking forward to it)
Tuesday, December 18, 2012
How voltage divider works
I spend a lot of time trying to figure out how a "voltage divider" works, so I've written down everything I've learned and am uploading it here. I am using a voltage divider to hook the Dexter board up to the Raspberry Pi so this info is relevant to Dexter.
Monday, December 17, 2012
Worked on serial I/O over the weekend, verified LDP-1450 command
I improved the serial I/O code over the weekend for Dexter and optimized it a bit more. I also plugged in my real LDP-1450 to my PC and wrote a small "game" driver to talk to it. My main purpose was to test the "repeat" command on the 1450 to see if it behaved similarly as it does on the LDP-1000A (which I do not have). I did indeed verify that the "repeat" command seems to be identical on the 1450 as it is on the 1000A. I also discovered that the 1450 won't work correctly if DTR is disabled. I am trying to move in the direction of adding support to Dexter for the 1000A/1450 players. But "real life" stuff keeps getting in the way. Maybe I'll have some more time over the holiday vacation coming up.
Tuesday, November 27, 2012
Been doing some video capturing lately
I've been capturing some S-VHS tapes lately and this gave me a chance to try out the Neat Video plugin which I bought a while ago. It does quite a good job of cleaning up the noise from these old analog tapes. I wonder if it could also handle Super8? Here is just a quick screenshot of my preliminary results. You can see the difference.
Saturday, November 24, 2012
There may be hope for USB just yet...
In talking with one of the Raspberry Pi guys, I've learned that the USB performance problems I am seeing are related to the FTDI chip I chose to put on the Dexter board. This means that it is possible that using another vendor's chip may solve this issue.
He says: "Looking at your post I see you were hitting the high CPU issue, which is inevitable with the FTDI serial adaptor. Was this the only issue?
I'm pretty sure that Gordon has a non-FTDI serial apator that doesn't suffer the high CPU effect. I'll try and find out exactly what is was."
He says: "Looking at your post I see you were hitting the high CPU issue, which is inevitable with the FTDI serial adaptor. Was this the only issue?
I'm pretty sure that Gordon has a non-FTDI serial apator that doesn't suffer the high CPU effect. I'll try and find out exactly what is was."
What this means is that for rev2 of the Dexter board, the only way to use it with a Raspberry Pi will be to hook into the pins on the pi itself using the same method I used (which is not the most convenient but it works!). I will probably post the steps I took for this method later, but using a PC to test still works fine so no one should be blocked in their testing :)
For the next (final?) revision of the Dexter PCB, hopefully another USB<->serial chip will surface so that the USB port can be used with the Raspberry Pi. The good news is that the rev2 Dexter board is still and will be very useful for testing going forward since it works fine with a PC and I still have a lot of firmware code to write for it.
Thursday, November 22, 2012
Dexter's USB port is too slow with the Raspberry Pi
Well, after writing some new code to bypass the /dev/ttyUSB0 path on the Raspberry Pi and instead use the direct method of http://www.intra2net.com/en/developer/libftdi/ , I have sadly observed the same problem exists for both methods; performance goes down the drain and the Pi cannot play the video at the full speed. So for now, the only method that exists for getting the video playing full speed on the Pi is using the pin headers on the Pi. This actually works great BUT I am wondering how this solution could possibly work for a consumer version of Dexter. This will have to be something to think about.
Wednesday, November 21, 2012
Dexter/Raspberry Pi sound issues resolved
After doing some final tests today, I've decided to call sound "finished" on the Raspberry Pi. It is playing fine now with no stuttering. Occasional stuttering is still possible if serial communication has random errors; this is still rare though.
Next step is getting the Dexter USB port working without performance penalties on the Raspberry Pi. After that, then I would say the Pi is ready for people to start testing with Dexter.
Next step is getting the Dexter USB port working without performance penalties on the Raspberry Pi. After that, then I would say the Pi is ready for people to start testing with Dexter.
Monday, October 8, 2012
Still working on audio
I've been a little busy since my last update but suffice it to say that I am still working on reliably ensuring a minimum level of audio quality. I've basically got all the code written and am currently trying to decide the appropriate size for buffers (including how much silence to prebuffer). I am not understanding the results I am seeing so far (it appears that I need to prebuffer at least an empty buffer that is twice as big as the hardware audio buffer which does not make sense to me so I am looking for defects in my code). If anyone has any science behind proper prebuffering, I would be glad to refer to it.
Monday, September 24, 2012
Audio frequency problem resolved!
The latest Raspberry Pi firmware update does indeed resolve the audio frequency issue I was seeing. My test laserdisc image file (with a continuous sine wave as the audio) now sounds smooth with no breaks or pops.
This audio testing reminded me of another audio issue that has been reported to me in the past: when the sound initially starts playing, it does not seem to be properly buffered because it kind of stutters before it gets going. I will look into this next. My design should've prevented this from happening so I am curious why it's not working :)
This audio testing reminded me of another audio issue that has been reported to me in the past: when the sound initially starts playing, it does not seem to be properly buffered because it kind of stutters before it gets going. I will look into this next. My design should've prevented this from happening so I am curious why it's not working :)
Tuesday, September 18, 2012
Pi audio issues improved
Some smart people have been working on improving the Pi's audio problems and they've made some progress (see thread linked in my previous blog entry). I am using the latest experimental firmware and re-running my audio tests to see how accurate 44.1khz mode will be. If it is very accurate, I won't need to mess around with any resampling.
Sunday, September 16, 2012
pi losing 2 samples every 512?
It looks like the pi (currently) has a defect in the audio where it drops 2 samples for every 512 which align quite closely to my own readings. See this thread:
So at this point, it would make more sense for me to try to help these guts resolve this 2 sample drop issue. If I can't, then it would make sense for me to perhaps modify my code to _insert_ 2 samples for every 512 to compensate. That would not be a very expensive hack CPU-wise so I could probably pull it off. It would mean that the audio artifacts would still be present (2 missing samples is definitely noticeable even at this frequency) but at least the audio would tend to stay in sync for much longer (I hope).
Monday, September 10, 2012
Still working on sound
This morning I worked a bit more on getting sound smooth on the Raspberry Pi. I made a laserdisc image file where the audio is just a continuous sine wave playing "middle C". I observed two things:
a) when played with Dexter, the sound pops regularly so there must be a defect in my code somewhere
b) when played with ALSA test code, the sound is steady but there is a background buzzing noise that should not be present; this may be related to immature ALSA drivers
I will try it again later with "omxplayer" which is supposedly a high-performance media player to see if I can get the kind of sound I want, and if I can, I will just use the same approach for my stuff as they do.
a) when played with Dexter, the sound pops regularly so there must be a defect in my code somewhere
b) when played with ALSA test code, the sound is steady but there is a background buzzing noise that should not be present; this may be related to immature ALSA drivers
I will try it again later with "omxplayer" which is supposedly a high-performance media player to see if I can get the kind of sound I want, and if I can, I will just use the same approach for my stuff as they do.
Sunday, September 9, 2012
Got sound working with Dexter+Raspberry Pi
Yesterday I finished writing the ALSA sound code to work with Dexter and the Raspberry Pi. Upon execution, the sound proved a bit choppy (although the video still played full speed!) so I think the problem may be my interpretation of how sound buffers work in ALSA. I'll have to play around with that. Also, it could be because the slow "mix_c" function is being called which I should be able to eliminate pretty easily (no mixing is needed).
Here is oprofile's output:
samples % image name symbol name
300 12.1310 dexter.bin mix_c()
288 11.6458 [vectors] (tgid:2686 range:0xffff0000-0xffff1000) [vectors] (tgid:2686 range:0xffff0000-0xffff1000)
197 7.9660 dexter.bin LoopCommon::Think()
121 4.8928 dexter.bin better_select(int, select_type, unsigned int)
88 3.5584 dexter.bin update_soundbuffer(unsigned int)
70 2.8306 dexter.bin listener::Think(unsigned int)
55 2.2240 dexter.bin OMXComponent::WaitForGeneric(list<boost::shared_ptr<IEvent>> const&, unsigned int)
52 2.1027 dexter.bin PlatformRPI::SoundPause()
51 2.0623 dexter.bin listenerThread::MainLoop()
50 2.0218 dexter.bin main
45 1.8197 dexter.bin MpoThreadMutex::Lock()
42 1.6983 dexter.bin VideoObjectUtil::RenderIfNeeded(bool)
39 1.5770 dexter.bin MpoThreadMutex::UnlockEx()
38 1.5366 dexter.bin JPEGOpenMax::DecompressJPEGStart(unsigned char const*, unsigned int, unsigned char const*, unsigne
d int)
38 1.5366 dexter.bin MpoPipeEx::NonBlockingRead(void*, unsigned int, unsigned int*)
38 1.5366 dexter.bin VideoObjectGLES2::DrawRGBA()
36 1.4557 dexter.bin ldp_img::OnVBlankStopped()
31 1.2535 dexter.bin boost::detail::sp_counted_base::destroy()
31 1.2535 dexter.bin game::PreThink(unsigned int)
Here is oprofile's output:
samples % image name symbol name
300 12.1310 dexter.bin mix_c()
288 11.6458 [vectors] (tgid:2686 range:0xffff0000-0xffff1000) [vectors] (tgid:2686 range:0xffff0000-0xffff1000)
197 7.9660 dexter.bin LoopCommon::Think()
121 4.8928 dexter.bin better_select(int, select_type, unsigned int)
88 3.5584 dexter.bin update_soundbuffer(unsigned int)
70 2.8306 dexter.bin listener::Think(unsigned int)
55 2.2240 dexter.bin OMXComponent::WaitForGeneric(list<boost::shared_ptr<IEvent>> const&, unsigned int)
52 2.1027 dexter.bin PlatformRPI::SoundPause()
51 2.0623 dexter.bin listenerThread::MainLoop()
50 2.0218 dexter.bin main
45 1.8197 dexter.bin MpoThreadMutex::Lock()
42 1.6983 dexter.bin VideoObjectUtil::RenderIfNeeded(bool)
39 1.5770 dexter.bin MpoThreadMutex::UnlockEx()
38 1.5366 dexter.bin JPEGOpenMax::DecompressJPEGStart(unsigned char const*, unsigned int, unsigned char const*, unsigne
d int)
38 1.5366 dexter.bin MpoPipeEx::NonBlockingRead(void*, unsigned int, unsigned int*)
38 1.5366 dexter.bin VideoObjectGLES2::DrawRGBA()
36 1.4557 dexter.bin ldp_img::OnVBlankStopped()
31 1.2535 dexter.bin boost::detail::sp_counted_base::destroy()
31 1.2535 dexter.bin game::PreThink(unsigned int)
Wednesday, September 5, 2012
Raspberry Pi + Dexter looks like a winning combo!
Good news, I hacked Dexter to use the Raspberry Pi's GPIO UART (bypassing the USB port) just to see if it would work and the results are _very_ encouraging. It would appear that the Pi is fast enough to meet Dexter's performance demands. I'll know more when I hook up audio, but I think I will spend a bit of time trying to resolve the USB port issues because I really want to use that USB port! :)
Monday, September 3, 2012
Sunday, September 2, 2012
Raspberry pi + Dexter improvements
Getting better!
Saturday, September 1, 2012
Dexter working with Raspberry Pi
It's not quite full speed (yet) but after much work I present a video showing Dexter working with the Raspberry Pi.
Here is what the current profiler shows:
% cumulative self self total
time seconds seconds calls s/call s/call name
8.79 0.96 0.96 5111 0.00 0.00 VideoObjectGLES2::LoadRGBAField(void const*, unsigned int)
8.24 1.86 0.90 247893 0.00 0.00 serial_rx_char_waiting()
4.21 2.32 0.46 5112 0.00 0.00 listener::Think(unsigned int)
2.93 2.64 0.32 numstr::ToStr(unsigned int, int, unsigned int)
1.65 2.82 0.18 20472 0.00 0.00 OMXComponent::WaitForGeneric(std::list<boost::shared_ptr<IEvent>, std::allocator<boost::shared_ptr<IEvent> > > const&, unsigned int)
1.65 3.00 0.18 1 0.18 0.45 VBIParse::VerifyVBIData(std::vector<VBI_s, std::allocator<VBI_s> >&, std::list<std::string, std::allocator<std::string> >&, std::list<std::string, std::allocator<std::string> >&, bool)
1.56 3.17 0.17 1 0.17 0.23 VBIParse::LoadVBIData(void const*, unsigned int)
1.47 3.33 0.16 126502 0.00 0.00 SerialStream::Read(void*, unsigned int, unsigned int)
1.24 3.47 0.14 5112 0.00 0.00 JPEGOpenMax::DecompressJPEGStart(unsigned char const*, unsigned int, unsigned char const*, unsigned int)
1.19 3.60 0.13 40869 0.00 0.00 OMXComponent::Lock()
1.10 3.72 0.12 5112 0.00 0.00 JPEGOpenMax::WaitJPEGDecompressorReady(unsigned char**)
1.10 3.84 0.12 5111 0.00 0.00 VideoObjectGLES2::DrawRGBA()
1.10 3.96 0.12 numstr::ToUint32(char const*, int)
1.05 4.07 0.12 70380 0.00 0.00 boost::detail::sp_counted_base::weak_release()
1.05 4.19 0.12 70366 0.00 0.00 boost::detail::sp_counted_base::sp_counted_base()
0.92 4.29 0.10 202784 0.00 0.00 VBIParse::GetBestLine1718(unsigned int&, unsigned int, unsigned int, unsigned int)
0.92 4.39 0.10 138872 0.00 0.00 boost::detail::sp_counted_base::release()
0.82 4.48 0.09 121390 0.00 0.00 serial_rx()
0.73 4.56 0.08 5112 0.00 0.00 Queue32::Push(unsigned int const*, unsigned int, void* (*)(void*, void const*, unsigned int))
0.73 4.64 0.08 MpoContainer::ReadHeader()
0.69 4.71 0.08 5112 0.00 0.00 audio_write_buf(void const*, unsigned int, void* (*)(void*, void const*, unsigned int), unsigned int)
0.69 4.79 0.08 5112 0.00 0.00 VideoObjectUtil::RenderIfNeeded(bool)
0.64 4.86 0.07 34507 0.00 0.00 boost::detail::sp_counted_impl_pd<unsigned char*, boost::checked_array_deleter<unsigned char> >::dispose()
0.64 4.93 0.07 12133 0.00 0.00 listener::ProcessPacket()
0.64 5.00 0.07 10247 0.00 0.00 OMXComponent::WaitForEvent(OMX_EVENTTYPE, unsigned long, unsigned long, unsigned int)
0.64 5.07 0.07 5113 0.00 0.00 OMXComponent::WaitForEventOrEmpty(OMX_EVENTTYPE, unsigned long, unsigned long, OMX_BUFFERHEADERTYPE const*, unsigned int)
Here is what the current profiler shows:
% cumulative self self total
time seconds seconds calls s/call s/call name
8.79 0.96 0.96 5111 0.00 0.00 VideoObjectGLES2::LoadRGBAField(void const*, unsigned int)
8.24 1.86 0.90 247893 0.00 0.00 serial_rx_char_waiting()
4.21 2.32 0.46 5112 0.00 0.00 listener::Think(unsigned int)
2.93 2.64 0.32 numstr::ToStr(unsigned int, int, unsigned int)
1.65 2.82 0.18 20472 0.00 0.00 OMXComponent::WaitForGeneric(std::list<boost::shared_ptr<IEvent>, std::allocator<boost::shared_ptr<IEvent> > > const&, unsigned int)
1.65 3.00 0.18 1 0.18 0.45 VBIParse::VerifyVBIData(std::vector<VBI_s, std::allocator<VBI_s> >&, std::list<std::string, std::allocator<std::string> >&, std::list<std::string, std::allocator<std::string> >&, bool)
1.56 3.17 0.17 1 0.17 0.23 VBIParse::LoadVBIData(void const*, unsigned int)
1.47 3.33 0.16 126502 0.00 0.00 SerialStream::Read(void*, unsigned int, unsigned int)
1.24 3.47 0.14 5112 0.00 0.00 JPEGOpenMax::DecompressJPEGStart(unsigned char const*, unsigned int, unsigned char const*, unsigned int)
1.19 3.60 0.13 40869 0.00 0.00 OMXComponent::Lock()
1.10 3.72 0.12 5112 0.00 0.00 JPEGOpenMax::WaitJPEGDecompressorReady(unsigned char**)
1.10 3.84 0.12 5111 0.00 0.00 VideoObjectGLES2::DrawRGBA()
1.10 3.96 0.12 numstr::ToUint32(char const*, int)
1.05 4.07 0.12 70380 0.00 0.00 boost::detail::sp_counted_base::weak_release()
1.05 4.19 0.12 70366 0.00 0.00 boost::detail::sp_counted_base::sp_counted_base()
0.92 4.29 0.10 202784 0.00 0.00 VBIParse::GetBestLine1718(unsigned int&, unsigned int, unsigned int, unsigned int)
0.92 4.39 0.10 138872 0.00 0.00 boost::detail::sp_counted_base::release()
0.82 4.48 0.09 121390 0.00 0.00 serial_rx()
0.73 4.56 0.08 5112 0.00 0.00 Queue32::Push(unsigned int const*, unsigned int, void* (*)(void*, void const*, unsigned int))
0.73 4.64 0.08 MpoContainer::ReadHeader()
0.69 4.71 0.08 5112 0.00 0.00 audio_write_buf(void const*, unsigned int, void* (*)(void*, void const*, unsigned int), unsigned int)
0.69 4.79 0.08 5112 0.00 0.00 VideoObjectUtil::RenderIfNeeded(bool)
0.64 4.86 0.07 34507 0.00 0.00 boost::detail::sp_counted_impl_pd<unsigned char*, boost::checked_array_deleter<unsigned char> >::dispose()
0.64 4.93 0.07 12133 0.00 0.00 listener::ProcessPacket()
0.64 5.00 0.07 10247 0.00 0.00 OMXComponent::WaitForEvent(OMX_EVENTTYPE, unsigned long, unsigned long, unsigned int)
0.64 5.07 0.07 5113 0.00 0.00 OMXComponent::WaitForEventOrEmpty(OMX_EVENTTYPE, unsigned long, unsigned long, OMX_BUFFERHEADERTYPE const*, unsigned int)
Friday, August 31, 2012
Raspberry Pi JPEG decoding to RGB now
After spending what feels like nearly a week, I've successfully got the Pi decoding to RGBA instead of YV12. This was a lot harder than it sounds because I had to add on a hardware "resizer" to the hardware "decoder". It is the resizer which is doing the colorspace conversion from YV12 to RGBA. Getting these two to interact with each other was quite tricky despite having example source code to refer to. But it's all working now so the next step is to add support for RGBA surfaces to my existing GLES2 code and then modify my LDImage code also work with RGBA surfaces in addition to the YUV444 surfaces that it already supports. Finally, I need to copy the pi's reference EGL code into the dexter code to make my GLES2 code work on the pi.
And then... video should work!
And then... video should work!
Tuesday, August 28, 2012
The YV12->YUV444 method is the culprit!
So my software implementation of an algorithm to convert a YV12 image to a YUV444 image is apparently dog slow so I will need to take steps to eliminate this (either by sending the YV12 image to GLES2 or using hardware to convert the image to RGB instead).
With the YV12->YUV444 algorithm active, here is the benchmark:
With the YV12->YUV444 algorithm active, here is the benchmark:
pi@raspberrypi ~/vldp-hw/src/unit_tests $ ./daphne_test.bin
Starting test jpeg1_rpi
Total time: 3573 ms (83.963056 FPS)
Stopping test jpeg1_rpi (3610 ms)
Commenting it out (and thus breaking functionality) here is the benchmark:
pi@raspberrypi ~/vldp-hw/src/unit_tests $ ./daphne_test.bin
Starting test jpeg1_rpi
Total time: 1635 ms (183.486239 FPS)
Stopping test jpeg1_rpi (1671 ms)
These are release builds. 83 FPS is actually still acceptable but seeing that it should be 183 FPS otherwise tells me that I should still try and optimize.
OpenMAX JPEG decoder working inside Dexter code
I've successfully gotten the OpenMAX JPEG decoder working inside Dexter code, although it does not yet render to the screen (just to a buffer). There is some extra software overhead that was not present before and this is causing it to still run too slow to play at full speed (currently 49.97 FPS and it needs to be over 60) but I still have quite a few optimizations I can apply to get it up to speed. Here's a comparison right now using libjpeg vs hardware:
pi@raspberrypi ~/vldp-hw/src/unit_tests $ ./daphne_test_dbg.bin
Starting test jpeg1_libjpeg
Total time: 16128 ms (18.601190 FPS)
Stopping test jpeg1_libjpeg (16147 ms)
pi@raspberrypi ~/vldp-hw/src/unit_tests $ ./daphne_test_dbg.bin
Starting test jpeg1_rpi
Total time: 6003 ms (49.975012 FPS)
Stopping test jpeg1_rpi (6034 ms)
Friday, August 24, 2012
Got abbreviated JPEG converted to full JPEG and ran benchmark
I read a little bit of the JPEG specification documents -- enough to accomplish my goal of converting an abbreviated JPEG and JPEG header buffer back to a full JPEG -- and logged my findings here . I then re-ran the benchmark on one of these 640x240 files and came up with this with this result:
pi@raspberrypi /opt/vc/src/hello_pi/hello_jpeg $ ./hello_jpeg.bin nukeme.jpg
time_T is 4
Total elapsed milliseconds: 1562
Total frames decoded: 300
Total frames / second is 192.061460
pi@raspberrypi /opt/vc/src/hello_pi/hello_jpeg $ ./hello_jpeg.bin nukeme.jpg
time_T is 4
Total elapsed milliseconds: 1562
Total frames decoded: 300
Total frames / second is 192.061460
That's looking great. It needs to be 59.94 frames per second and it is 192. So it's more than 3X as fast as it needs to be. This is looking very good.
Now I need to modify some of the LDImage code to use OpenMAX instead of libjpeg.
Thursday, August 23, 2012
Hardware decoding more than fast enough!
I've modified my test JPEG decode program to loop through 300 frames in as rapid succession as possible and the results are _very_ encouraging!
pi@raspberrypi /opt/vc/src/hello_pi/hello_jpeg $ ./hello_jpeg.bin lair1.jpg
Total elapsed milliseconds: 2346
Total frames decoded: 300
Total frames / second is 127.877238
pi@raspberrypi /opt/vc/src/hello_pi/hello_jpeg $ ./hello_jpeg.bin lair1.jpg
Total elapsed milliseconds: 2346
Total frames decoded: 300
Total frames / second is 127.877238
The source JPEG is 640x480 in size. The .ldimg JPEGs are 640x240 or 720x240 in size since they are fields instead of frames and they need to decode at 59.94 frames per second to run at full speed. So in other words, the hardware JPEG decoder is more than adequate to the task! (it would need to be decoding at 29.97 frames per second and it is running at 127.9 so that is awesome!)
Difference between full JPEG and headers+abbreviated
The libjpeg library I have been using supports creating "abbreviated" JPEGs which basically means that one can create a sequence of JPEGs that all share the same headers. This cuts down on disk size. This is what I have done with the .LDIMG file format. But now that I am working with hardware decoders that apparently have no concept of this, it becomes my challenge to recreate the original "full" JPEG from the "headers" and the "abbreviated" JPEG. Here is a file compare of how the headers and abbreviated content relate to the full. As you may be able to see, it appears that a careful algorithm can do this reconstruction fairly simply without having to understand the JPEG header format at all. At least, that's my hope as I do not want to spend time understanding the JPEG header.
Wednesday, August 22, 2012
Got basic hardware accelerated JPEG decoding working on Raspberry Pi!
I've got OpenMAX hardware JPEG decoding working on the Raspberry Pi! I wrote a bunch of .cpp/.h files to make doing the OpenMAX API calls nice and organized so I should be able to use this in the Dexter source code.
Things left to do before I can say that the JPEG decoding problem is conquered:
- decode multiple images in sequence and verify that the speed is acceptable.
- decode the "abbreviated" JPEGs that I am using inside the LDImage file format. The pi hardware can't handle these abbreviated JPEGs so I will need to figure out how to construct a "regular" JPEG from the "abbreviated" JPEG. Concatenating the JPEG headers with the abbreviated JPEG does not do the trick unfortunately.
- (optional) decode to RGBA format instead of YV12 just to see if I can. Then I can easily compare the pixel values with what I see inside something like GIMP.
Here's all of the files I wrote to accomplish this (it's an impressive amount of work in a short period of time!)
Things left to do before I can say that the JPEG decoding problem is conquered:
- decode multiple images in sequence and verify that the speed is acceptable.
- decode the "abbreviated" JPEGs that I am using inside the LDImage file format. The pi hardware can't handle these abbreviated JPEGs so I will need to figure out how to construct a "regular" JPEG from the "abbreviated" JPEG. Concatenating the JPEG headers with the abbreviated JPEG does not do the trick unfortunately.
- (optional) decode to RGBA format instead of YV12 just to see if I can. Then I can easily compare the pixel values with what I see inside something like GIMP.
Here's all of the files I wrote to accomplish this (it's an impressive amount of work in a short period of time!)
pi@raspberrypi /opt/vc/src/hello_pi/hello_jpeg $ ls -l *.cpp *.h
-rw-r--r-- 1 pi pi 5983 Aug 23 03:19 hello_jpeg.cpp
-rw-r--r-- 1 pi pi 139 Aug 22 17:33 ILocker.h
-rw-r--r-- 1 pi pi 166 Aug 22 19:15 ILogger.h
-rw-r--r-- 1 pi pi 820 Aug 22 17:11 Locker.cpp
-rw-r--r-- 1 pi pi 496 Aug 22 16:54 Locker.h
-rw-r--r-- 1 pi pi 128 Aug 22 19:31 Logger.cpp
-rw-r--r-- 1 pi pi 159 Aug 22 19:29 Logger.h
-rw-r--r-- 1 pi pi 381 Aug 22 17:07 MyDeleter.h
-rw-r--r-- 1 pi pi 6111 Aug 23 03:16 OMXComponent.cpp
-rw-r--r-- 1 pi pi 3136 Aug 23 03:10 OMXComponent.h
-rw-r--r-- 1 pi pi 1365 Aug 22 19:26 OMXCore.cpp
-rw-r--r-- 1 pi pi 826 Aug 22 19:26 OMXCore.h
And here is what it looks like to run my hello_jpeg.bin program on an arbitrary JPEG:
pi@raspberrypi /opt/vc/src/hello_pi/hello_jpeg $ ./hello_jpeg.bin lair1.jpg
Got event: 0
Got event: 0
Got event: 0
Got event: 0
Got event: 0
Got EmptyBufferDone
Got EmptyBufferDone
Got event: 3
Width: 640 Height: 480 Output Color Format: 20 Buffer Size: 460800
Got event: 0
Got event: 4
Got FillBufferDone
Color format "20" is YUV420Planar mode.
pi@raspberrypi /opt/vc/src/hello_pi/hello_jpeg $ ls -l output.raw
-rw-r--r-- 1 pi pi 460800 Aug 23 04:36 output.raw
This means that the file is organized with the Y plane coming first at a full resolution of 640x480, 8 bits per pixel. So that takes up 307200 bytes. Then comes the V plane (I believe) at a half resolution of 320x480, so that is 76800 bytes. Then the U plane, also at half resolution of 320x480 for another 76800. 307200 + 76800 + 76800 does indeed equal 460800 bytes. So it appears to be wookin' perfectly!
Monday, August 20, 2012
Raspberry Pi is awesome!
I got a power supply for the Raspberry Pi and tried it out tonight. It is awesome! I love it much more than the Beagleboard already.
- Doesn't need X to render to the TV (GLES2 or video hardware decoding)
- Boots up faster than the Beagleboard
- Defaults to TV-out mode upon bootup
- You can run the GLES2/video apps over SSH and debug with GDB without crashing the whole thing.
- Much, much cheaper than the Beagleboard!
All in all, I am very optimistic about the Raspberry Pi doing everything Dexter needs it to do!
I will continue to learn the OpenMAX API and hope to have something really cool to show soon. :)
Belated CAX report
I had this conversation saved in my text editor so before I lose it I will post it here. It's Warren talking about Firefox being shown running Dexter at this year's CAX (which I did not attend).
<Warren_O> I think the highpoint of the show was when Owen Rubin played Firefox, and remarked on how smoothly / seamlessly it played.
<Warren_O> it played beautifully the entire time we had it running, which was most of the show
<zaphX> No plobels at all?
<Warren_O> I think saw a few short freezes, which were probably due to the Windows 7 PC, and what looked like occasional single-field overruns (or under?)
<Warren_O> we're not sure if they were due to the game itself, or if dexter didn't process the skip commands until the next field
<Warren_O> but it played ASSOME
<Warren_O> We ran it briefly on a real VP931, and it looked crappy by comparison
<Warren_O> it did skip properly, but IIRC you could still tell that something was happening
<Warren_O> and then it crapped out :)
<Warren_O> when we tried switching discs to see if that was the problem, the lid interlock broke, so it wouldn't spin up anymore
<Warren_O> (Doug Jeffreys had fixed the interlock just before the show, so I guess it still wasn't quite right.)
<Warren_O> Unfortunately, this happened just before I was going to hook up my logic analyzer
<Warren_O> (I was finishing up soldering the passthrough adapter when this happened)
<Warren_O> I think the highpoint of the show was when Owen Rubin played Firefox, and remarked on how smoothly / seamlessly it played.
<Warren_O> it played beautifully the entire time we had it running, which was most of the show
<zaphX> No plobels at all?
<Warren_O> I think saw a few short freezes, which were probably due to the Windows 7 PC, and what looked like occasional single-field overruns (or under?)
<Warren_O> we're not sure if they were due to the game itself, or if dexter didn't process the skip commands until the next field
<Warren_O> but it played ASSOME
<Warren_O> We ran it briefly on a real VP931, and it looked crappy by comparison
<Warren_O> it did skip properly, but IIRC you could still tell that something was happening
<Warren_O> and then it crapped out :)
<Warren_O> when we tried switching discs to see if that was the problem, the lid interlock broke, so it wouldn't spin up anymore
<Warren_O> (Doug Jeffreys had fixed the interlock just before the show, so I guess it still wasn't quite right.)
<Warren_O> Unfortunately, this happened just before I was going to hook up my logic analyzer
<Warren_O> (I was finishing up soldering the passthrough adapter when this happened)
Friday, August 17, 2012
Beagleboard or Raspberry Pi will need hardware JPEG decoding
I've optimized the software JPEG decoding on the Beagleboard as much as I possibly can (using the libjpeg-turbo library) and also profiled Dexter. With no JPEG decoding running but everything else active, it was using about 9-10% cpu which is acceptable.
Here is what the profile shows as using all of the resources on the Beagleboard:
(with no JPEG decoding running the two methods taking up all the time are listener::Think and update_soundbuffer)
(with no JPEG decoding running the two methods taking up all the time are listener::Think and update_soundbuffer)
CPU: ARM Cortex-A8, speed 0 MHz (estimated)
Counted CPU_CYCLES events (Number of CPU cycles) with a unit mask of 0x00 (No unit mask) count 100000
samples % image name symbol name
968187 32.7438 dexter.bin h2v2_fancy_upsample
745262 25.2046 dexter.bin null_convert
614287 20.7750 dexter.bin decode_mcu
365378 12.3570 dexter.bin jsimd_idct_ifast_neon
95491 3.2295 dexter.bin decompress_onepass
22163 0.7495 dexter.bin jsimd_idct_ifast
16686 0.5643 dexter.bin jpeg_make_d_derived_tbl
14974 0.5064 dexter.bin __jsimd_idct_ifast_neon_from_thumb
13994 0.4733 dexter.bin sep_upsample
8031 0.2716 dexter.bin process_data_context_main
6007 0.2032 dexter.bin jpeg_fill_bit_buffer
5789 0.1958 dexter.bin jpeg_read_scanlines
4332 0.1465 dexter.bin listener::Think(unsigned int)
3232 0.1093 dexter.bin read_markers
3147 0.1064 dexter.bin start_pass
2507 0.0848 dexter.bin LDImageJPEG::DecompressAbbreviated(void*, unsigned char const*, unsigned int, bool)
2256 0.0763 dexter.bin jinit_master_decompress
2078 0.0703 dexter.bin ldp_img::OnVBlankStopped()
1904 0.0644 dexter.bin jpeg_huff_decode
1899 0.0642 dexter.bin LoopCommon::Think()
1799 0.0608 dexter.bin alloc_small
1678 0.0567 dexter.bin VideoObjectGLES2::LoadYUV444Field(void const*, unsigned int)
1563 0.0529 dexter.bin audio_write_buf(void const*, unsigned int, void* (*)(void*, void const*, unsigned int), unsigned int)
1377 0.0466 dexter.bin get_sof
1372 0.0464 dexter.bin serial_rx_char_waiting()
1255 0.0424 dexter.bin mpom::read_lile64(void*)
1192 0.0403 dexter.bin start_pass_main
1164 0.0394 dexter.bin SerialStream::Read(void*, unsigned int, unsigned int)
1157 0.0391 dexter.bin serial_rx()
1149 0.0389 dexter.bin consume_markers
1074 0.0363 dexter.bin MpoContainer::JumpToBlob(unsigned long long)
1062 0.0359 dexter.bin jinit_upsampler
1053 0.0356 dexter.bin mpo_read(void*, unsigned int, unsigned int*, mpo_io*)
1041 0.0352 dexter.bin jzero_far
982 0.0332 dexter.bin numstr::my_strlen(char const*)
974 0.0329 dexter.bin LDImageJPEGThreadStart(void*)
963 0.0326 dexter.bin fullsize_upsample
909 0.0307 dexter.bin LDImage::LoadVideoFieldStart()
854 0.0289 dexter.bin jpeg_read_header
814 0.0275 dexter.bin MpoContainer::StartReadBlob(unsigned int&)
763 0.0258 dexter.bin jinit_color_deconverter
762 0.0258 dexter.bin jpeg_calc_output_dimensions
729 0.0247 dexter.bin jinit_d_coef_controller
727 0.0246 dexter.bin examine_app0
721 0.0244 dexter.bin update_soundbuffer(unsigned int)
699 0.0236 dexter.bin MpoPipe::BlockingWrite(void const*, unsigned int, unsigned int*)
697 0.0236 dexter.bin main
691 0.0234 dexter.bin prepare_for_output_pass
673 0.0228 dexter.bin listener::ProcessPacket()
Thursday, August 16, 2012
Beagleboard video working.. kinda..
I've got the GLES2 code working "perfectly" on the Beagleboard now. The two problems are that I have only been able to get it rendering in a window on a desktop (instead of fullscreen) and it is far too slow right now. But this does represent fantastic progress because I had to write and rewrite a lot of code to get this far. Just having the correct image displayed with graphical overlay is huge.
Saturday, August 11, 2012
Beagleboard can see Dexter's serial port!
For fun I just tried plugging Dexter into the Beagleboard and I was very happy to see that it autodetected the USB serial port. I was able to see some Dexter chatter using minicom. This was expected but is still very exciting. It validates my decision to use a USB serial port on the Dexter board instead of a traditional DB9 port (which are rapidly becoming obsolete).
[68528.769439] usb 1-2.3: new full speed USB device using ehci-omap and address 4
[68528.973022] usbcore: registered new interface driver usbserial
[68528.973175] USB Serial support registered for generic
[68528.981475] usbcore: registered new interface driver usbserial_generic
[68528.981506] usbserial: USB Serial Driver core
[68529.004516] USB Serial support registered for FTDI USB Serial Device
[68529.008178] ftdi_sio 1-2.3:1.0: FTDI USB Serial Device converter detected
[68529.008605] usb 1-2.3: Detected FT232RL
[68529.008636] usb 1-2.3: Number of endpoints 2
[68529.008636] usb 1-2.3: Endpoint 1 MaxPacketSize 64
[68529.008666] usb 1-2.3: Endpoint 2 MaxPacketSize 64
[68529.008666] usb 1-2.3: Setting MaxPacketSize 64
[68529.010101] usb 1-2.3: FTDI USB Serial Device converter now attached to ttyUSB0
[68529.016174] usbcore: registered new interface driver ftdi_sio
[68529.016204] ftdi_sio: v1.6.0:USB FTDI Serial Converters Driver
Tuesday, August 7, 2012
Thayer's Quest fully working with Dexter now
I am ready to declare Thayer's Quest fully working with Dexter now after having fixed the left/right audio issue.
Wednesday, August 1, 2012
Lots of progress!
What does a vacation involving a laptop and a lack of internet result in? Major progress on Dexter! :)
The first thing I did was add support for left/right audio when used in conjunction with .ldimg files (which is what Thayer's Quest needs to function properly). This actually turned out to be a decent amount of work since it had not been implemented at all, and I had to implement it in such a way so that both .ldimg code and legacy VLDP code could share it. So I got that working and I am very pleased with the results.
Then in order to test it, I had to fix a bunch of problems in Daphne's Thayer's Quest driver that I broke when I did things like rip out SDL. Since Thayer's Quest uses a keyboard, I had to design a completely new (and abstract) way to pass keyboard events to a game driver. I'm happy to say that Thayer's Quest is running nicely once again (minus the speech synth which I still need to hook up)
I then decided to tackle something that's been bugging me for a long time and that is to clean up the IVideoObject interface. This interface has been around for a while in my personal code but I've never released it to the public (because it is only in WIP code). But I've done enough work on it that it was growing to monstrous proportions and so I spent quite a bit of time splitting it up into smaller interfaces. This will be very beneficial when it comes time to port the dexter viewer to something like beagleboard or raspberry pi so it was a good investment.
Lastly, I did more work on the VP931 interpreter and am pleased with how it is coming along. I am going to write a plethora of unit tests to make sure it is behaving exactly like the original VP931 behaved (using MAME/firefox as a reference so hopefully MAME is mostly correct) even though I do not have documentation on what the status codes mean. This is the best way I can think of to add support for those status codes without documentation. It will take some time but should be quite stable in the end.
The one thing MAME can't provide me with is details on what the interface does during disc spin-up time and non-instant seek time. If anyone with a real Firefox machine could somehow sniff this for me, it would be pretty awesome and the clock is actually ticking since these players are almost all universally dead.
The first thing I did was add support for left/right audio when used in conjunction with .ldimg files (which is what Thayer's Quest needs to function properly). This actually turned out to be a decent amount of work since it had not been implemented at all, and I had to implement it in such a way so that both .ldimg code and legacy VLDP code could share it. So I got that working and I am very pleased with the results.
Then in order to test it, I had to fix a bunch of problems in Daphne's Thayer's Quest driver that I broke when I did things like rip out SDL. Since Thayer's Quest uses a keyboard, I had to design a completely new (and abstract) way to pass keyboard events to a game driver. I'm happy to say that Thayer's Quest is running nicely once again (minus the speech synth which I still need to hook up)
I then decided to tackle something that's been bugging me for a long time and that is to clean up the IVideoObject interface. This interface has been around for a while in my personal code but I've never released it to the public (because it is only in WIP code). But I've done enough work on it that it was growing to monstrous proportions and so I spent quite a bit of time splitting it up into smaller interfaces. This will be very beneficial when it comes time to port the dexter viewer to something like beagleboard or raspberry pi so it was a good investment.
Lastly, I did more work on the VP931 interpreter and am pleased with how it is coming along. I am going to write a plethora of unit tests to make sure it is behaving exactly like the original VP931 behaved (using MAME/firefox as a reference so hopefully MAME is mostly correct) even though I do not have documentation on what the status codes mean. This is the best way I can think of to add support for those status codes without documentation. It will take some time but should be quite stable in the end.
The one thing MAME can't provide me with is details on what the interface does during disc spin-up time and non-instant seek time. If anyone with a real Firefox machine could somehow sniff this for me, it would be pretty awesome and the clock is actually ticking since these players are almost all universally dead.
Monday, July 16, 2012
Sneaky Thayer's Quest defect
I've been trying to track down a Thayer's Quest crash but the debugger has been flagging the wrong location. It has flagged this spot as the source of the problem:
However, after pulling out my hair, I finally found that the problem is actually here:
Frustrating.. but at least I found it and can move on.
Thursday, July 5, 2012
Working on Thayer's Quest audio
The video player I wrote for Dexter currently does not support isolating either the left or right audio channel like Thayer's Quest requires. I have been working on adding support for this.
Saturday, June 23, 2012
Thayer's Quest works!!
Thanks to Shaun Wood, my Thayer's Quest is now working once again.
I was able to hook Dexter up to it and debug my problem and now it is working.
The only thing left to do with Thayer's Quest is make the left/right audio channel stuff work properly which is probably what I'll work on next since I've got momentum.
Friday, June 22, 2012
Dexter DIAGNOSE button working!I
Thursday, June 21, 2012
Dexter DIAGNOSE button coming soon
The DIAGNOSE button on the rev2 Dexter boards has not been hooked up. I am about to change that so that you can press the DIGANOSE button and get verbose logging. This may help with troubleshooting problems with games like Thayer's Quest.
Wednesday, June 13, 2012
Thayer's Quest sounding good
It sounds like Shaun Wood has made some progress fixing my Thayer's Quest board. This is great news. If he is successful, then I should be able to fix Dexter to work with Thayer's Quest.
Sunday, June 10, 2012
Thayer's Quest sent off for repair
I finally stopped procrastinating and sent off my Thayer's Quest boardset (and disc) for repairs. My fingers are crossed!
Friday, May 11, 2012
Thayer's Quest blockage (and detailed pics)
Welp, I erased the original TQ EPROMs and reprogrammed them and it did not solve the problem. So I am stumped. This is very discouraging.
I did take a bunch of pictures of my TQ board so that I don't have to take the top board off to see what's on the bottom board again (it is a huge pain to get it back together).
This means that my fix for Thayer's Quest on Dexter is delayed indefinitely. :(
Tuesday, May 8, 2012
EPROM programmer arrived
The EPROM programmer has arrived as you can see.
That's the good news.
The bad news is I read both of my Thayer's Quest EPROMs and they had no errors on them. They matched the Thayer's Quest ROM images that everyone has. Oddly enough, they were placed on the board as you see them in the pictures; without proper protection from UV light. So may last hope is to try to erase them and reprogram them and see if that changes anything. I've got a sinking feeling in my stomach that it won't make any difference though.
Monday, May 7, 2012
EPROM programmer should be here today
My EPROM programmer should be waiting for me when I get home from work today. I will post my findings regarding my TQ ROMs as soon as I have the data myself.
Friday, May 4, 2012
Ordered EPROM programmer
Well, I still haven't been able to get my Thayer's Quest board to work which means that I can't fix the Dexter firmware to work with Thayer's Quest.
I decided that it's time I had my own tools to verify/write my EPROMs. So I have ordered the necessary tools to program and erase my EPROMs. I am going to try reading my Thayer's Quest ROMs and comparing them to known good dumps. I am really hoping to find some discrepancies. If the ROMs are good then I will be forced to ship my boards to someone more knowledgeable than I.
Monday, April 30, 2012
Having trouble with Thayer's Quest
So I hooked up my Thayer's Quest boardset to my Dragon's Lair cabinet tonight and it's not booting up.
I used to have this working and the boardset has done nothing but sit in a box for 5+ years (actually probably closer to 10 years) so I can't imagine that something is damaged. I took a few pictures of my setup. Hopefully someone can see what I am doing wrong. The scoreboard doesn't get initialized either, it just comes up as you see.
Wednesday, April 18, 2012
Still alive!
I'm still alive! Sorry for the lack of Dexter updates lately.
Friday, March 16, 2012
Hard drive benchmarks
Tuesday, March 13, 2012
Dragon's Lair testing on Dexter rev 2
One thing I noticed when we were demo'ing Dexter rev 1 at CAX last year was that sometimes certain incorrect frames would show up at the beginning of scenes. What I wasn't sure of was whether the incorrect frame was due to overrun or due to the ROM seeking to the wrong starting position. Well, I have pretty solid evidence now that the ROM appears to be seeking to the wrong starting position for some of the scenes, such as the "colored balls" scene. My logging clearly shows that it is seeking to frame 26042 which you can see in this screenshot is the combination of the end of the previous scene and the beginning of the next. The thing that puzzles me, however, is, "Why have I never noticed this before?" Surely this must happen on original hardware but I've never noticed it. Has anyone else?
Here's the relevant log snippet:
lair: -> FF
lair: <- E4
lair: -> 8F
lair: <- 64
lair: -> FF
lair: <- E4
lair: -> 6F
lair: <- 64
lair: -> FF
lair: <- E4
lair: -> 3F
lair: <- 64
lair: -> FF
lair: <- E4
lair: -> 2F
lair: <- 64
lair: -> FF
lair: <- E4
lair: -> 8F
lair: <- 64
lair: -> FF
lair: <- E4
lair: -> F7
Search to 26042 received
Edit: Added frame 22738 which is another example.
Friday, March 9, 2012
New PC toys
My main PC is slowly dying (hard drive access is getting excruciatingly slow) and it's probably 4 years old by now so it's time to get some new hardware. Here's what I've ordered:
- Intel Core i5-2400 Sandy Bridge 3.1GHz (3.4GHz Turbo Boost) LGA 1155 95W Quad-Core CPU
- GIGABYTE GA-Z68XP-UD3 LGA 1155 Intel Z68 HDMI SATA 6Gb/s USB 3.0 ATX Intel Motherboard
- 8GB of DDR3 2133 RAM (I'll upgrade to 16GB later)
- Crucial M4 CT064M4SSD2 2.5" 64GB SATA III MLC Internal Solid State Drive (for OS)
- 500GB 7200rpm conventional hard drive for apps and temporary storage
AM EXCITED!
- Intel Core i5-2400 Sandy Bridge 3.1GHz (3.4GHz Turbo Boost) LGA 1155 95W Quad-Core CPU
- GIGABYTE GA-Z68XP-UD3 LGA 1155 Intel Z68 HDMI SATA 6Gb/s USB 3.0 ATX Intel Motherboard
- 8GB of DDR3 2133 RAM (I'll upgrade to 16GB later)
- Crucial M4 CT064M4SSD2 2.5" 64GB SATA III MLC Internal Solid State Drive (for OS)
- 500GB 7200rpm conventional hard drive for apps and temporary storage
AM EXCITED!
Sunday, March 4, 2012
Neil playing Firefox with Dexter
Neil successfully plays a game of Firefox using Dexter rev 2 prototype (at least I think that's what he is doing, I've never played the game myself so I don't know). This is exciting because it proves that Dexter is a viable solution to replace the unreliable and rare VP931 laserdisc player. Now if we can see that Dexter works for Freedom Fighter, then that will be even better!
Saturday, March 3, 2012
Dexter software released to testers
The long-awaited day is finally here. I've released some working Dexter software to the rev 2 testers. Woohoo!
Friday, March 2, 2012
Console finally working!
When I decoupled SDL from Daphne, I broke the console. I've finally got it working again (mostly had to rewrite it from scratch). What a pain! So glad it's done. I will be using this same code on the Dexter media server so all that effort will pay off :)
Thursday, March 1, 2012
LD-V1000 port working again, media server progress made
I did some more tests in my garage this morning after applying Warren's suggested fix and am pleased to say the LD-V1000 port on the rev2 is working perfectly now :)
I also made some more progress on the media server and it should be ready Real Soon Now for rev2 testing.
I also made some more progress on the media server and it should be ready Real Soon Now for rev2 testing.
Wednesday, February 29, 2012
Debugged LD-V1000 port
This morning I tried hooking up the rev2 Dexter board to my dragon's lair and noticed I was getting a spamfest of seek errors even without powering on the dragon's lair.
I hooked up my handy AVR dragon (hardware debugger) and noticed that sometimes the data from the ld-v1000 port would return 0xFF (expected) and sometimes it would randomly return 0xF7 (unexpected). This meant that pin A3 was sometimes 0 and sometimes 1 when it should always be 1. And since it was supposed to be using an internal pull-up resistor to force the value to 1 when unconnected, I concluded that something was pulling it down to GND.
Looking at the layout, I noticed that A3 passes through our NAND IC and concluded that this must be randomly pulling it to GND. Warren suggests that if I explicitly set one of the NAND inputs to 0 that it should fix the problem (I was not doing this).
I hooked up my handy AVR dragon (hardware debugger) and noticed that sometimes the data from the ld-v1000 port would return 0xFF (expected) and sometimes it would randomly return 0xF7 (unexpected). This meant that pin A3 was sometimes 0 and sometimes 1 when it should always be 1. And since it was supposed to be using an internal pull-up resistor to force the value to 1 when unconnected, I concluded that something was pulling it down to GND.
Looking at the layout, I noticed that A3 passes through our NAND IC and concluded that this must be randomly pulling it to GND. Warren suggests that if I explicitly set one of the NAND inputs to 0 that it should fix the problem (I was not doing this).
Tuesday, February 28, 2012
Did some more work on the media server
Last night I did some more work on the media server to get it closer to being ready for use by the rev 2 testers. The reason it isn't as usable right now as it was during CAX is because I removed SDL from most of the code in preparation to port it to the Beagleboard and I've had to rewrite some of the stuff that this impacted.
Friday, February 24, 2012
Thursday, February 23, 2012
Can anyone loan me Firefox hardware?
I want to work on the firmware for the VP931 emulation on the Dexter rev 2 board but I don't have anything to test it with. If someone has some firefox hardware that I could borrow during this development period, that would be helpful. I would prefer something that is easier to setup.
Monday, February 20, 2012
Friday, February 17, 2012
Laserdisc image encoding frontend finished!
My frontend for encoding laserdisc images is finished!
Just so everyone knows I will not be releasing this program to the public. It is still very technical to use and so I will only be giving it to a few others who know what they are doing. The last thing we need is some bonehead getting his hands on this program, making a bad image, and then convincing others to mirror it all over the internet. It's happened before.
Monday, February 13, 2012
More work on laserdisc image encoding
I've been working more on getting the laserdisc image encoding ready for Dexter rev 2 testing. I ran into a snag in that .NET's ability to pipe stdout and stderr from child processes is severely crippled. It buffers 4k blocks before sending _anything_ to the caller which is ridiculously inadequate. This issue diverts me from what I'd rather be working on.
Friday, February 10, 2012
Been working on laserdisc images
I've been working on my laserdisc image file format the past few days. This is the file format that will be used with Dexter (most likely) so I've been trying to make it "final" so people can start using it.
Wednesday, February 8, 2012
My first MySQL stored procedure!
I had to write a stored procedure (it is dexter related, believe it or not) and after much trial and error, here is the finished result. I post it here for my own reference more than anything in case I need to do it again some day:
And to view the stored procedure after it's been entered in, you do this:
To see all the stored procedures on the DB, do this query:
DELIMITER $$
DROP PROCEDURE IF EXISTS FixIDsProc $$
CREATE PROCEDURE `FixIDsProc`()
BEGIN
DECLARE no_more_rows INT DEFAULT 0;
DECLARE idx INT DEFAULT 1;
DECLARE strName TEXT;
DECLARE my_cursor CURSOR FOR
SELECT `dn_name` FROM `discids` ORDER BY `discids`.`dn_name` ASC;
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET no_more_rows = 1;
OPEN my_cursor;
FETCH my_cursor INTO strName;
REPEAT
UPDATE `discids` SET `id` = idx WHERE `dn_name` = strName;
SET idx = idx + 1;
FETCH my_cursor INTO strName;
UNTIL no_more_rows = 1
END REPEAT;
CLOSE my_cursor;
END $$
DELIMITER ;
And to view the stored procedure after it's been entered in, you do this:
SHOW CREATE PROCEDURE FixIDsProc\G
To see all the stored procedures on the DB, do this query:
SELECT ROUTINE_TYPE, ROUTINE_NAME, ROUTINE_SCHEMA FROM INFORMATION_SCHEMA.ROUTINES;
Monday, February 6, 2012
Friday, February 3, 2012
Reworked serial transmit code
Yesterday, I reworked the code responsible for transmitting serial data from the dexter board. I haven't tested it yet on real hardware (just the simulator) but it should be a big improvement over the previous code. It should achieve close to maximum throughput _and_ it can be disabled during timing-critical sections of program flow. Only thing that remains is testing it on real hardware.
Oh and my JTAG debugging pins should arrive today some time so I won't have to rely on the simulator much longer.
Oh and my JTAG debugging pins should arrive today some time so I won't have to rely on the simulator much longer.
Wednesday, February 1, 2012
Mode button working, MAX video chip working
If you bought a rev 2 prototype board, I have some good news for you. Everything on the board that I've tested so far works according to design. This is great news because when I had the prototype boards made, I didn't know whether they would work. It was a risk that, so far, is paying off.
Components I've verified to be working:
- USB interface to PC (works after wire swap)
- AVR microcontroller
- LM1881 (well almost)
- MAX video chip
- s-video input
- BNC video output
- LED driver chip
- LEDs
- reset and mode buttons
Components I have not yet tested:
- LD-V1000 port
- DB25 port
- PR-8210 port with optocoupler
- MAX222 IC's
- PR8210A helper IC (NAND gates)
- solid state relay
Tuesday, January 31, 2012
Optimized transmit buffer, started hooking up MODE button
I've modified the Dexter program a little bit so that the transmit buffer gets emptied using interrupts rather than polling to see when it's time to send another byte. This should have the effect of faster transmit speed. It also may throw off critical timing so I will have to do some tests and may have to disable it if it is a problem.
I also started hooking up the MODE button to make the LDP choice cycle when you press it. This is not finished yet.
I also started hooking up the MODE button to make the LDP choice cycle when you press it. This is not finished yet.
Monday, January 30, 2012
I've finished soldering my rev2 prototype board!
I've finished soldering on all the parts (well except for the JTAG pin headers which I don't have due to a shipping error with digikey). As you can see, all of the LEDs work except for the PR-8210 LED which I soldered on backward, then ripped up one of the pads trying to remove it. DOH! I haven't tried "animating" the LEDs yet but the fact that they all work suggests that the LED driver chip we chose is working properly.
Saturday, January 28, 2012
USB wiring problem fixed! "Hello world" program works!
Indeed the TX and RX lines were backwards on the Dexter board so after performing a manual swap of those two lines, the Dexter board is now sending out to the serial port just fine. Here's a simple "hello world" program I wrote working correctly.
Friday, January 27, 2012
Looks like usb chip may be miswired
Looks like there may be a problem with the FTDI USB chip's "wiring". I was having trouble getting a simple "hello world" program running so I dug deeper and found this page which clearly shows that the TX/RX pins on the AVR should be opposite of the TX/RX pins on the FT232RL. I think I have this backwards. I will consult with Warren and Neil for the best way to fix this. It could be as simple as soldering two wires from the via's near the FTDI chip to the AVR's pins and then cutting two traces but we must proceed cautiously before performing surgery.
All rev2 prototype Dexter boards are sold
I neglected to mention this earlier, but all of the rev2 prototypes are sold. Thanks to all buyers who helped move this project forward!
Almost finished!
Thursday, January 26, 2012
Made more soldering progress
Wednesday, January 25, 2012
Dexter USB chip works!!
I went ahead and bought a through-hole 4.7uF cap to replace the surface mount one I lost this morning. The soldering is a total hack job but the good news is I just plugged in the dexter board to my Windows 7 box and it not only detected the USB chip correctly but also was able to auto install the drivers! This is a very good sign! Once I finish the soldering I can hopefully see the coveted greeting from the AVR.
Did some more soldering, lost C15
I did some more soldering this morning and got all of the 0.1uF caps installed. I just have a few caps left to solder before I move on to resistors. Unfortunately, as I was trying to get C15 out of its plastic housing I dropped it on the floor and can't find it which makes me very sad. Hopefully I can find a local place that sells these things.
Tuesday, January 24, 2012
A new forum for rev 2 prototype discussion
I've made a new forum to discuss the rev 2 prototype for those who have purchased boards. You can find it at this link. This is so that we can consolidate the discussion in one place. I will be putting all the info I have about assembling and using the rev 2 board there, although much of what I put there will probably link back to this blog :)
If you bought a rev 2 board and do not have access, you may need to create an account on the daphne message board and then tell me what your account is.
If you bought a rev 2 board and do not have access, you may need to create an account on the daphne message board and then tell me what your account is.
Monday, January 23, 2012
LED direction / orientation
Here's a picture showing the correct way to orient the LEDs when soldering.
It also shows the worlds worst soldering job by yours truly. I really hope to get better as I go along :)
UPDATE : I've added part of the datasheet that shows which side is 'pad' 1 and which side is 2.
Sunday, January 22, 2012
Started soldering, the LED works!
Saturday, January 21, 2012
Here's where the parts go on the board
Here's a picture showing where all of the parts go on the board for those who ordered a board and now need to solder on parts.
Apologies for this super high res picture. Most of the resistors and caps have super small text. If I figure out a way to resize the text on everything without having to redo each individual component, I will release a smaller pic.
Direct link to pic: here.
23 Jan 2012 UPDATE : the direct link has changed as I have added some more labels that were missing and also made a note not to install C26.
Apologies for this super high res picture. Most of the resistors and caps have super small text. If I figure out a way to resize the text on everything without having to redo each individual component, I will release a smaller pic.
Direct link to pic: here.
23 Jan 2012 UPDATE : the direct link has changed as I have added some more labels that were missing and also made a note not to install C26.
Subscribe to:
Posts (Atom)