
"Roll Your Own GFA BASIC Program 5" by Troy H. Cheek on May 11, 2009
(This week's article will only make sense if you started at part 1.)
If InStr(buf$, "VIDEO_MPEG2_I_L I/L") > 0
Interlaced% = 1 ' needs to be deinterlaced with HandBrake
ElseIf InStr(buf$, "VIDEO_MPEG2_PROG Prog") > 0
Interlaced% = 0 ' no deinterlacing needed
Else
Interlaced% = -1 ' don't know what this one is
EndIf
GSpot does a pretty good job of detecting if a video file is interlaced or progressive with just a quick scan of the headers. It does a better job with a detailed scan of the entire file, but the scan-then-exit thing doesn't work properly for me when I use that option. The interlaced video created most of the time by most of my television tuners just doesn't look right to me unless deinterlaced, even though I'm sure there are some video purists screaming about how I'm losing half the resolution by doing so. Hey, if it's interlaced, the resolution wasn't there to begin with.
HandBrake is what I use to deinterlace videos. Indeed, it does pretty much all the conversion. HandBrake's deinterlace gives pretty good results at its fastest settings, and I can't really see much improvement when I use the slower ones. It also has an automatic decombing setting that's faster than the slowest deinterlace settings, slower than the fastest, and produces almost perfect results. It scans each frame of video and only deinterlaces the frames (or perhaps even parts of frames) where interlacing is visible. It only throws away half the resolution when it makes the picture look better. However, no matter how I fiddle with the settings, I can't quite get it to work right for me. It sometimes misses little things, which wouldn't be a problem if the little things weren't things that I notice immediately. If most of the scene is static or nearly so, but there's one little thing moving like a dog in the background or an actor speaking, HandBrake's decombing will decide that since most of the scene isn't showing any interlacing, it doesn't need to filter the dog's legs or the actor's lips. I end up with a perfect scene except for that tiny little part that's flickering, which draws my attention right to it.
Of course, deinterlacing when not necessary is even worse, hence the check.
The check also helps out in that most of my television tuners create interlaced video. One of the ones that doesn't also creates video which HandBrake chokes on. A video flagged as not interlaced is also a video flagged as needing extra processing before being passed to HandBrake.
Finally, if GSpot found that the video file is neither interlaced nor progressive, the file gets flagged with a negative number. I'm not sure this has ever happened. A few times, my program seemed to hang or call HandBrake with the wrong parameters, and it seemed to be caused by not finding the interlace information in the GSpot log, but naturally once I put this sanity check in I never had that particular problem again.
a% = InStr(buf$, "VIDEO_SIZE_X")
a$ = Mid$(buf$, a% + 31, 4)
Xres% = Val(a$)
a% = InStr(buf$, "VIDEO_SIZE_Y")
a$ = Mid$(buf$, a% + 31, 4)
Yres% = Val(a$)
GSpot is also pretty good about detecting the resolution of the video file. It can't be perfect because MPEG-2 is apparently a streaming file format which can contain video frames of varying resolutions within it. Still, if the video starts out at 720x480, it probably stays that way. Actual resolution may vary from display resolution depending on the pixel aspect ratio. However, HandBrake handles all of that. I just need to know the video size so I can detect if it's HDTV or not. I get a few digital channels here, and some of then occasionally broadcast in high definition, which means mindblowingly huge files containing a zillion times more information than is necessary to make the video look good on even my largest television. If I can recognize the resolution, I can tell HandBrake to scale things down a bit. More on that later.
Open EZMFilename$ for Append As # 2
Print # 2; Time$; " ";
If Interlaced% = 1
Print # 2; "Interlaced video at"; Xres%; "x"; Yres%
Else If Interlaced% = 0
Print # 2; "Progressive video at"; Xres%; "x"; Yres%
Else
Print # 2; "Unknown! video at"; Xres%; "x"; Yres%
Do : Sleep : Until Me Is Nothing
End
EndIf
Close # 2
This is a combination of logging and error catching. I want to save the original resolution and interlace status in case I need to check them later. When I first started fiddling, I'd have HD files that weren't scaled down or SD (standard definition) which were, neither of which should have happened, but it was hard to track down the problem without knowing these exact stats. Naturally, once I added this part, the scaling problems disappeared.
However, if the video is flagged as neither interlaced nor progressive, the program simply stops. I don't know how to handle these videos yet. I leave the program running so the next time I check the computer, I know that it has stopped here. I need to go back and add a command to show the window. Naturally, once I added this part, there haven't been any unknown videos for me to examine.
The Do/Until structure there just keeps the program asleep until the main window itself ("Me") has been closed. I really love the syntax there. Almost natural language computing.
I also need to point out the sloppy programming there with the Close file statement. It is found outside of the End/If structure. That means that if there is an unknown type of video file, the log file is left open until the program ends by me closing the window. The End command closes all open files, so the file still gets closed. But if the computer loses power or the program ends abnormally while this loop is just cycling, the log file might get corrupted.
Next week, we'll look at the run time of the video files.