Well done on the release. I'm not sure if I have time to contribute directly at the moment but I can give a few pointers which should prove helpful. I take it you found the import recorder fix that I contributed which does improve support for HDMI capture devices. The fix is not complete although I have listed most of the issues that are still to be solved. This is mainly live tv, channel changer script and correct handling of HDPVR2 I frame detection (tripped up by the HDPVR I frame detection code). I think that back to back recordings may also be affected although I haven't personally tested this as I use sequential dual tuner import which is something entirely different.
The good news is most of the basic stuff is quite easy to fix and all the time is in identifying the problems so you get the expensive bit for free
Initialisation sequence
This issue actually turned out to be difficult to identify, not because it is complex but because it was related to unexpected behaviour of the STB and therefore getting mixed in with the setting adjustments. It may not affect all STBs but it affects mine so maybe others too. When the HDPVR2 is first powered on it behaves differently towards the STB than after it is initialised. I suspect this is because the EDID block is not loaded and hence the STB uses more compatible settings which is ironic because my STB ignores almost all of the EDID, even basic stuff like what modes are actually supported. Somewhere down the line this leads to a sub optimal colour space conversion which can mostly be seen with darker gradients as it introduces a colour cast to some of the macro blocks. As mentioned in my review gradients can already tend to be blocky but this makes them appear much noisier than they otherwise would be.
There are 2 basic solutions that I can suggest.
- Init option to purely load firmware and EDID and then terminate the app. You could put this in the bootup script but would need to ensure you only plug in the STB after the HDPVR2 initialisation is complete. This also affects the way the LEDs are lit on the USB device so you can normally see when it is complete.
- Use a set of script hooks to be completed by the end user. Firstly to power on the HDPVR2 and then to power on the connected device only after the EDID is available. Finally to power both devices off again after capture is complete.
EDID excerpt
Code: Select all
Video data block
VIC 16 1920x1080@60Hz (native)
VIC 34 1920x1080@30Hz
VIC 32 1920x1080@24Hz
VIC 05 1920x1080i@60Hz
VIC 04 1280x720@60Hz
VIC 20 1920x1080i@50Hz
VIC 19 1280x720@50Hz
VIC 03 720x480@60Hz
VIC 18 720x576@50Hz
VIC 02 720x480@60Hz
VIC 17 720x576@50Hz
VIC 07 1440x480i@60Hz
VIC 22 1440x576i@50Hz
VIC 06 1440x480i@60Hz
VIC 21 1440x576i@50Hz
VIC 01 640x480@60Hz
HDMI handshaking
The original HDPVR2 app seems to have a botched approach to determining whether or not a stable HDMI signal is available. Although you can read several related timing registers from the ADV7482 none that I tried were especially helpful (there must be something useful available in there). The easiest approach therefore appears to be to inspect the returned vertical frequency. Obviously if you don't initialise the Magnum DXT with the correct timing details you will either get a bad encoding or crash the app. Also as mentioned in the review the HDPVR2 app does not monitor the HDMI frontend for any changes so you have to ensure a stable HDMI signal throughout the capture.
I gave this a bit of thought and the easiest solution is probably just to poll the reported vertical frequency until it is stable for a certain time period. I think that the STB may do a resync (if it is on) after the HDPVR2 is initialised, mine however always appears to keep the original EDID information from when it was first connected i.e. even if it was supposedly in standby mode (hence the above recommendation).
The basic loop would be something like...
Code: Select all
receiverHDMIParams_t vp;
do{
rxDev.getHDMIParams(&vp);
/* do check */
wrapSleep_ms(recheck_ms);
last_vf=vp.vFreq;
}while(retry<max_retry);
/* check valid etc.*/
AC3 pass through via HDMI
AC3 support via HDMI seems to be a bug bear. It's actually very easy to add support although detecting whether the HDMI data stream contains AC3 may not be trivial as the related info packets didn't contain anything useful which may also be the norm. I would therefore recommend a source setting (HDMI / SPDIF) and an on/off setting such as force on / force off / HD only (SD channels don't typically contain AC3 although no reason why they can't). The last option is obviously only useful if your STB is set to match the source resolution.
The basic code should be...
Code: Select all
hapi->set_param(&_Param, "AudioCapSource", 3); // 0: LR, 1:SPDIF, 2:SDI, 3: HDMI
hapi->set_param(&_Param, "AudioPassthru", 1);
hapi->set_param(&_Param, "AudioCodecOutputFormat", 2); /* AC3 */
hapi->set_param(&_Param, "AudioStreamID", 189); /* AC3/DTS */
There is also a further SPDIF related setting I haven't used myself
Code: Select all
hapi->set_param(&_Param, "AudioCapSPDIFInput", 0); // 0:COAX, 1: 19977, 2: AES_EBU, 3: opTICAL
I frame handling
The default settings for the HDPVR2 app produce mixed IDR / non IDR keyframes. I think a solution to this may be as easy as counting the number of IDR keyframes in the first n frames but falling back to the original code if the amount is below a certain threshold.
The code that needs to be adjusted is in mythcommflagplayer.cpp
Code: Select all
// H.264 recordings from an HD-PVR contain IDR keyframes,
// which are the only valid cut points for lossless cuts.
// However, DVB-S h.264 recordings may lack IDR keyframes, in
// which case we need to allow non-IDR I-frames. If we get
// far enough into the rebuild without having created any
// seektable entries, we can assume it is because of the IDR
// keyframe setting, and so we rewind and allow h.264 non-IDR
// I-frames to be treated as keyframes.
uint64_t frames = decoder->GetFramesRead();
if (!usingIframes &&
(GetEof() != kEofStateNone || (frames > 1000 && frames < 1100)) &&
!decoder->HasPositionMap())
{
cout << "No I-frames found, rewinding..." << endl;
decoder->DoRewind(0);
decoder->Reset(true, true, true);
pmap_first = pmap_last = myFramesPlayed = 0;
decoder->SetIdrOnlyKeyframes(false);
usingIframes = true;
}
As an alternative workaround I believe you can force IDR I frames using
Code: Select all
hapi->set_param(&_Param, "bIasIDR", 1);
There is likely to be a trade off between encoder efficiency and seek performance here so also supporting the default settings is probably best.
Recording profiles
I would recommend users setup some dummy recording profiles e.g. Default / HQ / LQ etc. These can then be used to pass on settings such as bitrate to the app. I got the impression you fixed up support for the settings file in which case this could be used to specify the name / location of the file. I believe the original settings file already had separate HD/SD... settings. If not IMHO that is a useful feature, as is having some command line overrides for some settings so you don't end up with too many settings files.
Anyway it's been a while since I looked at this in any detail but I think some of the above should be useful.