Recorded Files
From OpenWiz
Contents |
File Naming Convention
TV recordings are created in a directory named in the following format:
- Title_MMM.DD.YYYY_HH.NN.tvwiz
Radio recordings are created in a directory named in the following format:
- Title_MMM.DD.YYYY_HH.NN.radwiz
MMM = 3 letter month
DD = 2 digit date (day)
YYYY = 4 digit year
HH = 2 digit hour (in 24 hour format)
NN = 2 digit minute
TV and Radio recordings are stored in the beyonwiz's recording directory.
- TV recordings are only visible to the user when Movie mode is selected.
- Radio recordings are only visible to the user when Music mode is selected.
In 24 hour mode the user sees recordings as:
- DD/MM/YY HH:NN (## min) Title
In 12 hour mode the user sees recordings as:
- DD/MM/YY HH:NNam (## min) Title
- DD/MM/YY HH:NNpm (## min) Title
Note: The channel name will be used as the title if the program's title is unavailable:
- DD/MM/YY HH:NN (## min) ChannelName
--Dave® 03:09, 21 March 2008 (UTC)
Recording Directory Contents
Each recording's directory contains 3 binary files - a header file, a trunc file and a stat file - and as many 32MB mpeg-ts files as needed. The mpeg-ts files have no file extension and normally start at 0000 with each consecutive file's name incremented by 1. i.e. 0001, 0002, 0003 and so on. The last file can be 32MB or smaller.
Note: If you have edited a recording, or saved part of the timeshift buffer, the numbered 32MB files may not start at 0000. File sets need not be complete - i.e. the numered sets can have gaps as long as the trunc file has been updated accordingly.
header.tvwiz & header.radwiz files
Contains all the LCN and channel information.
It is always 256 KB (262,144 bytes).
Acknowledgment: Much of the information in this section is derived from the Beyonwiz WizFX source code and the Beyonwiz WizPnP Protocol description. The source code license says "Any adaptation and/or re-distribution of this program is/are allowed."
header.tvwiz file layout
+---------------------+ < offset 0 (0x00000)
| |
| TVWizFileHeader |
| |
+---------------------+ < offset 18 (0x00012)
| |
| ... |
| |
+---------------------+ < offset 1024 (0x00400)
| |
| TVWizTSPoint |
| |
+---------------------+ < offset 1548 (0x0060c)
| |
| TVWizTSPoint.offset |
| |
+---------------------+ < offset 69128 (0x10e08)
| |
| ... |
| |
+---------------------+ < offset 79316 (0x135d4)
| |
| TVWizTSbookmarks |
| |
+---------------------+ < offset 79856 (0x137f0)
| |
| TVWizTSextInfo |
| |
+---------------------+ < offset 81140 (0x13cf4)
| |
| ... |
| |
+---------------------+ < offset 262144 (0x40000)
Prl 05:32, 1 April 2008 (UTC)
offset 0 - 4 bytes (hex): 62 10 02 00
offset 1024 - varies (text): Channel-Name
offset 1280 - varies (text): FAV-Group - LCN - Title
offset 1536 (hex): ?unknown?
offset 79316 - 1 byte (hex): Number of Bookmarks
offset 79336 - 3 bytes (hex): First Bookmark.
offset 79344 - 3 bytes (hex): Second Bookmark.
offset 79352 - 3 bytes (hex): Third Bookmark.
Each successive bookmark starts 6 bytes after the end of the preceding bookmark. Maximum quantity of bookmarks?
TVWizFileHeader
struct TVWizFileHeader { /* File offset 0 */
ushort magic; /* File offset 0
* Always 0x1062
*/
ushort header_version; /* File offset 2 */
ushort vidPID; /* File offset 4
* Program video PID
*/
ushort audPID; /* File offset 6 */
* Program audio PID (see text)
*/
ushort PCRPID; /* File offset 8 */
* Program PCR PID
* PCR = Program Clock Reference
*/
ushort PMTPID; /* File offset 10 (0xa) */
* Program video PID
* PMT = Program Map Tables
*/
uchar lock; /* File offset 12 (0x0c)
* File Lock
*/
uchar mediaType; /* File offset 13 (0x0d)
* media type
* 0 = video, 1 = audio, 2 = photo (?)
*/
uchar inRec; /* File offset 14 (0x0e)
* currently recording
* if non-zero.
*/
uchar unused; /* File offset 15 (0x0f) */
uchar autoDelete[2]; /* File offset 16 (0x10)
* Autodelete setting and flags. See text for details.
*/
};
The data types in the example follow C conventions: char: 8-bit signed or unsigned - architecture dependent; uchar: 8-bit unsigned; ushort: 16-bit unsigned; ulong: 32-bit unsigned; uint64: 64-bit unsigned. The structures are assumed to be packed as tightly as possible, all padding is explicit or for the start of structures, implied by the file offset. Multi-byte values are in the Beyonwiz's ARM CPU's native littlendian format; that is the lowest file offset is the least significant byte. This is the same byte order as Intel x86 processors.
Only the 13 least significant bits of the PID fields (vidPID & 0x01ff, audPID & 0x01ff, pcrPID & 0x01ff, pmtPID & 0x01ff) contain the PID. If the most significant bit audPID (audPID & 0x8000) is set, it indicates that the audio on the PID is AC3, otherwise it's MP2 audio. It's not known if the three high-order bits in audPID or in any of the other PIDs are significant. PCRPID is the PID containing the PCR (Program Clock Reference) packets. At the time of writing, all broadcasters except the ABC place the PCR packets in the video stream, so this is the same as vidPID for them. The ABC uses a dedicated PID for the PCR packets, so on ABC recordings PCRPID is not equal to vidPID. Media type in WizFX is determined by whether the recording contains a header.tvwiz (for TV) or a header.radwiz (for radio) file.
If inRec is non-zero, the recording is currently being recorded. Copying it from the Beyonwiz may result in a corrupted copy on the destination.
autoDelete encodes up to 4 flag bits and a 12-bit number of days for the autodelete. The fields are decoded as follows:
#define AUTODELETE_FLAGS 0x0f #define AUTODELETE_ENABLE 0x02 #define autoDeleteTime(hdr) ( ( ((hdr)->autoDelete[0] & 0xf0) << 4) | (hdr)->autoDelete[1] ) #define autoDeleteFlags(hdr) ( (hdr)->autoDelete[0] & AUTODELETE_FLAGS ) #define autoDeleteEnable(hdr) ( (hdr)->autoDelete[0] & AUTODELETE_ENABLE )
Only the AUTODELETE_ENABLE flag has been observed in firmware version 01.05.301. The purpose of other bit positions in AUTODELETE_FLAGS is unknown. autoDeleteTime(hdr) corresponds to the number of "days after" set for Autodelete in FilePlayer>POPUP>Autodelete in the Beyonwiz GUI. The Never setting of the Autodelete timer is represented by (hdr)->autoDelete[0] == 0 && (hdr)->autoDelete[0], but it may be the setting of autoDeleteTime(hdr) == 0 that is definitive.
The 12-bit field of autoDeleteTime(hdr) allows "days after" to be up to 4095, but the GUI restricts the value to 365.
Prl 05:32, 1 April 2008 (UTC)
TVWizTSPoint
struct TVWizTSPoint { /* File offset 1024, 0x400 */
char svcName[256]; /* File offset 1024, 0x400
* service (LCN) name. NUL padded.
*/
char evtName[256]; /* File offset 1280, 0x500
* program title (event name). NUL padded.
*/
ushort mjd; /* File offset 1536, 0x600
* Recording start time, as a Modified
* Julian Date, but not really
* MJD, strictly speaking.
* See text.
*/
ushort pad; /* File offset 1538, 0x602 - Alignment */
ulong start; /* File offset 1540, 0x604
* Recording start time, seconds
* past midnight on the MJD.
*/
ushort last; /* File offset 1544, 0x608
* Index of the last valid
* navigation offset in
* offset.fileoff[].
* Navigation offsets are at 10
* second intervals, so
* the recording duration is
* duration = last*10 + sec
* The offset at last+1 is also
* set to zero. Non-zero offsets
* may follow, but are not relevant.
*/
ushort sec; /* File offset 1546, 0x608
* Recording duration (sec)
* beyond the last navigation
* offset.
*/
struct TOffset offset; /* File offset 1548, 0x60c
* Recording navigation index.
* Offset of end of recording
* and recording offsets every
* 10 sec.
*/
};
svcName and evtName are the broadcast service (strictly the name of the LCN or logical channel number) that made the recorded broadcast and the program title (or event name if set from the EPG).
mjd and start make up the start time for the recording. Although its name suggests that the start time is a Modified Julian Date, which is "the number of days ... that have elapsed since midnight at the beginning of Wednesday November 17, 1858 [Universal Time]". The timestamp is in fact the MJD plus the time zone offset current at the time the recording started.
To make sense of this time scheme, you can translate the recording start time into local time in C or (or similarly in Perl) on Unix-like systems using:time_t startt; struct tm *locatime; startt = (wizTSPoint.mjd - 40587) * 24 * 60 * 60 + wizTSPoint.starttime; localtime = gmtime(&startt); /* now the fields of localtime are correct for local time at the start of the recording */
In particular, note that although startt is similar to the Unix time, it should not be converted into the local time date/time information in struct tm by using localtime(3) as it normally would be. To convert the time into a true UTC-based Unix time, set TZ to the timezone that was in effect at the time of the recording, and call mktime(3) on startt.
offset provides a navigation index into the recording, allowing a point in elapsed time in the recording to be mapped into an approximate position in the recording file by interpolation.
offset.fileOff contains offsets into the logical recording file described by the trunc file. The offsets represent the starts of 10-second intervals of the recording, possibly aligned to the start of an MPEG I-frame.
last is the index of the last valid navigation offset in offset.fileoff[]. Because the navigation offsets are at 10 second intervals, the recording duration is duration = last*10 + sec. The offset at last+1 is also set to zero. Non-zero offsets may follow, but are not relevant.
sec is the time between offset.fileFF[last] and offset.lastOff.
Prl 05:32, 1 April 2008 (UTC)
TOffset
TOffset provides a navigation index into the recording, allowing a point in elapsed time in the recording to be mapped into an approximate position in the recording file by interpolation.
Its operation is described above in TVWizTSPoint.
There are up to 8640 entries each representing a 10-second interval, allowing a recording up to 86400 seconds (or one day) long to be indexed. The fileOff part of the index describes 86390 seconds of recording, and the the interval from fileOff[8639] to lastOff may be an additional 10 seconds.
fileOff[0] is always 262144, the length of header.tvwiz, suggesting that the header is considered part of the logical recording.
struct TOffset { /* File offset 1548, 0x60c */
uint64 lastOff; /* File offset 1548, 0x60c
* Offset of end of recording
*/
uint64 fileOff[8640]; /* File offset 1556, 0x614 */
* Table of offsets in the recording
* at 10-sec intervals. Terminated
* by an offset of 0.
*/
};
TVWizTSbookmarks
The TVWizTSbookmarks section of the header describes bookmarks in the recording. The structure of this part of the file is not documented in WizFX source code nor in the Beyonwiz WizPnP Protocol description.
struct TVWizTSbookmarks {
ushort numBookmarks; /* File offset 79316 (0x135d4)
* Count of the number of bookmarks.
* May be more space than 16 bits,
* but there's "only" room for
* 22776 bookmarks, so 16 bits
* is easily enough.
*/
uchar pad[18]; /* File offset 79318 (0x135d6) */
uint64 bookmarks[64]; /* File offset 79336 (0x135e8)
* Table of bookmark offsets,
* sorted in time order.
* Count in numBookmarks;
* actual maximum size uncertain,
* probably 64, but certainly
* no more than 65.
*/
};
The structure is very straightforward. The actual length of numBookmarks is not known, but an unsigned 16-bit integer is easily large enough to contain the number of bookmarks that can follow given the (apparently fixed) size of the header. It's possible that it is in fact stored as a ulong, which would make the padding 16, rather than 18 bytes. It's possible that the "padding" space is actually reserved for the implementation of a resume play offset.
Each bookmark is an offset into the logical recording file, as described in trunc file and in TOffset. The offset of the start of actual recorded material is 262144.
It is also not known whether the whole remaining header is reserved for bookmarks, or whether there is other reserved space past the end of the bookmark table.
The bookmarks are ordered to be at least non-descending by their offset. They are probably in fact in strict ascending order (i.e. no bookmarks with the same offset).
Bookmarks are currently copied when the header.tvwiz file is copied either by WizFX (or similar programs) or by the Beyonwiz copy function. However, at the moment, the Beyonwiz can't delete or add bookmarks to a recording on a network share. Once the bookmark has been copied to a share, all bookmarks can be deleted by zeroing out the bookmark area of the file; simply setting numBookmarks to zero will probably suffice. Adding bookmarks to the header is also simple, but the alignment requirements of the offsets are unknown. For a clean visual transition, the bookmarks should probably be aligned to the start of an I-frame. Using existing offsets from the TOffset table may provide bookmark offsets that are suitably aligned, though they are only available at 10-second intervals.
TVWizTSextInfo
The TVWizTSextInfo section of the header contains the recording episode name and extended event information (program synopsis). The structure of this part of the file is not documented in WizFX source code nor in the Beyonwiz WizPnP Protocol description.
struct TVWizTSextInfo {
uchar episodeLen; /* File offset 79856 (0x137f0)
* Episode name length, 0..255
*/
char episodeName[255]; /* File offset 79857 (0x137f1)
* Episode name text
*/
ushort extInfoLen; /* File offset 80114 (0x138f2)
* Extended event information
* length, 0..1024.
*/
char extInfo[1024]; /* File offset 80116 (0x138f4)
* Extended event information text
*/
};
stat file
I'm not sure what this file is used for yet.
It is always 96 bytes
offset 46 - 2 bits (hex): ?unknown?
--Dave® 03:09, 21 March 2008 (UTC)
trunc file
Contains all the information needed to construct a single logical recording file from the 32MB (and smaller) MPEG-TS files that make up the recording.
Once they have been created by a recording, the MPEG-TS files don't seem to be changed in size by editing operations (except perhaps the new files created when a Copy A->B operation is done). The information about how to assemble the (pieces of the) MPEG-TS files into a single logical recording is held in the trunc file.
Contains all the information about the quantity and names of all of the 32MB (and smaller) mpeg-ts files.
struct TwizOffsetFileSection {
uint64 wizOffset; /* Offset 0 (0x00)
* Logical offset of the start
* of the file chunk in the
* recording. The wizOffset of
* the first trunc entry is always
* 262144.
*/
ushort fileNum; /* Offset 8 (0x08)
* File number containing
* the recording chunk.
*/
ushort flags; /* Offset 10 (0x0a)
* Unknown purpose. Never
* referred to by WizFX.
*/
uint64 offset; /* Offset 12 (0x0c)
* Offset of the recording
* chunk in file fileNum.
* Size overkill, because recording
* files are never larger than
* 32 MB (33554432 bytes).
*/
ulong size; /* Offset 20 (0x14)
* Size of the recording chunk.
*/
};
The trunc file consists of a sequence of 24-byte TwizOffsetFileSection records, one for each chunk of the MPEG-TS files that makes up the logical recording file. More than one TwizOffsetFileSection record may refer to a single MPEG-TS file, but the limited nature of the editing operations on the Beyonwiz ensures that trunc files created and edited on the Beyonwiz will always have any multiple references to the same MPEG-TS file adjacent and in order of increasing offset, and the values of the fileNum fields will be non-decreasing. It is possible, though, that the Beyonwiz playback code does not depend on this ordering, and the trunc file could be used for general cut/splice operations. The cut/splice positions probably need to be on I-frame boundaries.
wizOffset is the offset of the start of the chunk in the logical recording file. As with the offsets in TOffset, the start of the recording material is at offset 262144. The records in the trunc file must be ordered so that the wizOffset fields are in ascending order, and increase by exactly the size field.
Prl 06:14, 1 April 2008 (UTC)
Download html version of image for editing
Each 'line' referred to below refers to 24 bytes.
- Last byte: Each 24 byte line always ends in either 00, 01 or 02.
The first and last line always ends in either 00, 01 or 02.
All other lines always end in 02.
- 2nd last byte: The 2nd last byte on each first and last 24 byte line varies.
I've seen 00, 06, 60, 80 and E4.
All lines between the first and last have 00 as the 2nd last byte.
- 1st 3 bytes: Each 24 byte line almost always starts with 00 00 04.
Except sometimes the first line starts with 00 00 A4 instead of 00 00 04.
- 4th byte: On each 24 byte line the 4th byte increments by 2 hex from the last line's 4th byte.
Usually the first line's 4th byte is 00 but sometimes it starts at a larger number.
- 9th byte: The 9th byte on each 24 byte line increments by 2 hex from the last line's 9th byte.
Usually the first line's 9th byte is 00 but sometimes it starts at a larger number.
- 10th byte: The 10th byte on each 24 byte line increments by 2 hex for every 255 lines in the file.
When record 255 + 1 has been reached, the 9th byte resets to 00 and we start counting again.
- 15th byte: In one file the 15th byte on the first line was A0 (in all other files it was 00).
This particular recording was saved from the timeshift buffer.
All other bytes are 00
Notes:
The 4th byte is always double the value of the 9th byte.
The 9th byte is the hex value of the part file's number.
If the part files start with 0000 the 9th byte on the first line will be 00.
And the 4th byte on the first line will be 00.
On a 85 file set starting at 0000 and ending at 0084:
The last line's 9th byte would be 55.
And the last line's 4th byte would be AA.
File sets can start at any number:
i.e. Starting at 0083 and ending at 0089 etc (if recorded from the timeshift buffer)
--Dave® 03:09, 21 March 2008 (UTC)
Contents directory media files
Media files that are small enough to be stored in a single file on the Beyonwiz's FAT32 file system are stored as a single file, under their original name. FAT32 files can be up to about 4GB. According to Wikipedia, up to 232-1 bytes, but it's not certain where the breakpoint is for Beyonwiz media files.
Larger media files are stored in a folder with the extension .wiz appended, and the media file is broken up into 1GB (exactly 230 bytes) files, named 0000, 0001, etc, stored in the folder. A single header file, wmmeta contains the information that allows the Beyonwiz to reconstruct the media file for playback.
wmmeta file
The wmmeta header file is similar in structure to the trunc file, but for some reason, has a different format, even though the trunc file format could have been used for this purpose.
wmmeta has a 4096-byte header, of which only 12 bytes appear to be used, and a fixed-size array of 512 16-byte entries describing the files that the original media file has been split into. The file is constant length -- 12288 bytes. The first four bytes of wmmeta are the characters WzMF. The next 4 bytes contain an integer -- its purpose is not known.
As before, numbers in the file are in littlendian order.
struct Wmmeta {
uchar magic[4]; /* Offset 0 (0x00)
* "Magic number". The text "WzMF"
*/
ulong unknown; /* Offset 4 (0x04)
* Unknown purpose. Normally the value 1.
*/
ulong nentries; /* Offset 8 (0x08)
* The number of valid entries in entries.
*/
uchar pad[4084]; /* Offset 12 (0x0c) */
struct WmmetaFileEntry entries[512];
/* Offset 8 (0x08)
* Describes the files that the original
* has been split into.
*/
};
struct WmmetaFileEntry {
uint64 wizOffset; /* Offset 0 (0x00)
* Logical offset of the start
* of the file chunk in the
* media file. The wizOffset of
* the first wmmeta entry is always 0.
*/
ulong fileNum; /* Offset 8 (0x08)
* File number containing
* the media file chunk.
* 0 is file name 0000, etc.
*/
ulong size; /* Offset 12 (0x0c)
* Size of the recording chunk.
*/
};
Prl 06:04, 7 February 2009 (UTC)




