I have written a TAP that saves the EPG data when recordings are made. Normally, I save this data to a separate file, but I want to add a feature so that the data can be archived (to external media) with the MPG(REC)/INF/NAV without having to worry about archiving my other file.
Adding the extra data to the INF would seem like a logical choice because then any TAP or the standard firmware could copy the files without knowing about my extra file.
For the purposes of my TAP, I could just add my data and be finished. But I thought it might be nice to cooperate with other TAPs that may need to store information in the INF file as well, so I would like to ask for opinions on the following proposal:
First, some background: Research on my Australian TMS PVR suggests that there are 3 types of INF file.
0 snapshots = 3,320 bytes (3k)
1 snapshot = 132,636 bytes (132k)
4 snapshots = 499,572 (499k)
I have found that if I write extra data after 499k, the firmware ignores this extra data, the PVR does not change or destroy the extra data.
In addition to this, I have found that if I have a short (3k or 132k) INF, if I fill the space up to 499k with NULL characters, the PVR still works fine and will even add 4 snapshots without damaging the extra data beyond 499k.
Step 1: As a pre-requisite to writing extra data, the INF needs to be padded to 499k.
When it comes to writing the extra data, I would like to do it in a way that other TAPs could also use if they had data to store.
Step 2: I propose that each extra piece of data should be preceded by a fixed-length header. This header would have enough information for a TAP to either recognise the following data as its own or some other TAP's and provide the ability to skip over it.
The INF file would then contain: <INF DATA> + <HEADER><TAP 1 DATA> + <HEADER><TAP 2 DATA>, etc.
Actually, the <DATA> is optional if there is a small amount of data and it can be saved in the header fields.
Here is the struct that I am considering for the header.
Code: Alles auswählen
typedef struct TYPE_EXTINF {
char magic[4]; //TFr+
dword payloadSize; //Size of the data payload to follow.
dword tapID; //ID of the TAP that created the header, and following data.
dword type; //Flag for the TAP to note the record type.
dword tag; //Option for the TAP to save an additional tag for the data.
dword timeStamp; //Time stamp of when the record was written.
byte secondsStamp; //Seconds from the previous time stamp.
word version; //Version number of the data block.
byte deleted; //Flags if this record is logically deleted and should be ignored.
char lang[3]; //Language of the extensible data.
char description[32]; //Human-readable description of the data type.
} TYPE_EXTINF;
The magic field is very important for detecting corruption. If an INF is larger than 499k, but the first 4 extra bytes after 499k are not magic, the INF is corrupted in some way. This repeats for every header, if a header is read and the magic field is wrong, then there is a corruption.
Extending an INF becomes simple.
1) If < 499k, pad to 499k with NULLs, if already >= 499k then seek EOF.
2) Write a header.
3) Write some data.
4) Close the file.
Reading is simple too:
1) seek 499k+1.
2) Read header.
3) Check magic.
4) Check TAP ID.
5) Read data or seek next header with payloadSize.
Feedback would be appreciated, especially if anyone has written a TAP that could benefit from adding information to the INF.
Best Regards,
DeltaMikeCharlie.