| 1 | /*************************************************************************** |
|---|
| 2 | * Copyright (c) 2005-2007, Broadcom Corporation |
|---|
| 3 | * All Rights Reserved |
|---|
| 4 | * Confidential Property of Broadcom Corporation |
|---|
| 5 | * |
|---|
| 6 | * THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE |
|---|
| 7 | * AGREEMENT BETWEEN THE USER AND BROADCOM. YOU HAVE NO RIGHT TO USE OR |
|---|
| 8 | * EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT. |
|---|
| 9 | * |
|---|
| 10 | * $brcm_Workfile: bsettop_fileio_fifo.h $ |
|---|
| 11 | * $brcm_Revision: 6 $ |
|---|
| 12 | * $brcm_Date: 12/7/07 4:24p $ |
|---|
| 13 | * |
|---|
| 14 | * Module Description: |
|---|
| 15 | * |
|---|
| 16 | * Revision History: |
|---|
| 17 | * |
|---|
| 18 | * $brcm_Log: /BSEAV/api/include/bsettop_fileio_fifo.h $ |
|---|
| 19 | * |
|---|
| 20 | * 6 12/7/07 4:24p vsilyaev |
|---|
| 21 | * PR 37037: Improved documentation for fifo file |
|---|
| 22 | * |
|---|
| 23 | * 5 4/12/06 2:16p vsilyaev |
|---|
| 24 | * PR 20680: Promoted bsettop_fileio_fifo API |
|---|
| 25 | * |
|---|
| 26 | * 4 12/23/05 4:10p vsilyaev |
|---|
| 27 | * PR 18183: Renamed API functions |
|---|
| 28 | * |
|---|
| 29 | * 2 11/21/05 3:42p vsilyaev |
|---|
| 30 | * PR 18183: Renamed size function to bounds, so it would remain useful |
|---|
| 31 | * with trimmed files |
|---|
| 32 | * |
|---|
| 33 | * 1 11/17/05 4:22p vsilyaev |
|---|
| 34 | * PR 18183: Added circular(FIFO) file |
|---|
| 35 | * |
|---|
| 36 | ***************************************************************************/ |
|---|
| 37 | #ifndef BSETTOP_FILEIO_FIFO_H__ |
|---|
| 38 | #define BSETTOP_FILEIO_FIFO_H__ |
|---|
| 39 | |
|---|
| 40 | #ifdef __cplusplus |
|---|
| 41 | extern "C" { |
|---|
| 42 | #endif |
|---|
| 43 | |
|---|
| 44 | #include "bsettop_types.h" |
|---|
| 45 | #include "bfile_io.h" |
|---|
| 46 | |
|---|
| 47 | /* |
|---|
| 48 | Overview |
|---|
| 49 | bfile_out_fifo is a type of record file used for PVR timeshifting. |
|---|
| 50 | |
|---|
| 51 | bfile_out_fifo works by trimming the beginning of a file so that the overall file size remains bounded. |
|---|
| 52 | For efficiency reasons, trimming is done in chunks, not in bytes. |
|---|
| 53 | Because of variable bit rate complexities, bounding is not done using a simple size number but with set of time and data limits. |
|---|
| 54 | |
|---|
| 55 | The main API is: |
|---|
| 56 | |
|---|
| 57 | bfile_fifo_out_create - create a new timeshifting buffer for record |
|---|
| 58 | |
|---|
| 59 | bfile_fifo_out_file - create a brecord_file_t mapped to the timeshifting buffer for use in Settop API record |
|---|
| 60 | |
|---|
| 61 | bfile_fifo_in_open - create a bplayback_file_t mapped to the timeshifting buffer for use in Settop API playback |
|---|
| 62 | based on either a live recording or a static file (i.e. terminated recording). |
|---|
| 63 | |
|---|
| 64 | The actual size of the file on disk is not actually fixed. Most applications require a timeshifting buffer which is bounded by a specified time. |
|---|
| 65 | Because video bit rates vary, the actual amount of data needed to achieve this time will vary. |
|---|
| 66 | bfile_out_fifo employs three parameters to determine limits: |
|---|
| 67 | |
|---|
| 68 | interval - desired accessible size of buffer, measured in units of seconds |
|---|
| 69 | see bfile_out_settings for details |
|---|
| 70 | |
|---|
| 71 | soft limit - minimum size of sustained buffer (either data or index), measured in units of bytes |
|---|
| 72 | see bfile_out_limit for details |
|---|
| 73 | |
|---|
| 74 | hard limit - maximum size of buffer (either data or index), measured in units of bytes |
|---|
| 75 | see bfile_out_limit for details |
|---|
| 76 | |
|---|
| 77 | After the bfile_out_fifo is closed (i.e. the recording is terminated), the file can be reopened as |
|---|
| 78 | a static playback file. See bfile_fifo_in_open for details. |
|---|
| 79 | |
|---|
| 80 | If your application wants to convert a time-limited timeshifting buffer into a disk-limited permanent recording, |
|---|
| 81 | it can simply update the bfile_out_settings to enormous values. The recording can then continue until it |
|---|
| 82 | fails because of a full disk. Here's an example: |
|---|
| 83 | |
|---|
| 84 | bfile_out_settings settings; |
|---|
| 85 | bfile_out_get(file, &settings); |
|---|
| 86 | settings.interval = 356 * 24 * 60 * 60; // 1 year |
|---|
| 87 | settings.data.soft = 1024*1024*1024*1024; // 1000 GB |
|---|
| 88 | settings.data.hard = settings.data.soft; |
|---|
| 89 | settings.index.soft = settings.data.soft; |
|---|
| 90 | settings.index.hard = settings.data.soft; |
|---|
| 91 | bfile_out_set(file, &settings); |
|---|
| 92 | */ |
|---|
| 93 | |
|---|
| 94 | /* |
|---|
| 95 | Summary: |
|---|
| 96 | Handle used for timeshifting buffer |
|---|
| 97 | */ |
|---|
| 98 | typedef struct bfile_out_fifo *bfile_out_fifo_t; |
|---|
| 99 | |
|---|
| 100 | /* |
|---|
| 101 | Summary: |
|---|
| 102 | Configuration parameters for the timeshifting buffer |
|---|
| 103 | |
|---|
| 104 | Description: |
|---|
| 105 | These numbers are used to limit the size of the timeshifting buffer on the disk. |
|---|
| 106 | |
|---|
| 107 | The soft limit is the targetted file size. |
|---|
| 108 | A sustained continuous record will not be less than "soft". |
|---|
| 109 | You can terminate a record before it reaches the soft limit, but if allow it to continue (i.e. sustained), it will eventually reach the soft limit. |
|---|
| 110 | |
|---|
| 111 | In certain cases (e.g. if the bitrate of the recorded stream suddenly increases) bfile_out_fifo may |
|---|
| 112 | exceed the soft limit. However, it will never exceed the hard limit. |
|---|
| 113 | Once the hard limit is reached, an overflow error occurs. |
|---|
| 114 | |
|---|
| 115 | Choosing an appropriate hard and soft limit should be as follows: |
|---|
| 116 | |
|---|
| 117 | 1. Choose the desired interval based on your application (e.g. 1 hour, 2 hours). |
|---|
| 118 | |
|---|
| 119 | // 1 hour = 3600 seconds |
|---|
| 120 | bfile_out_settings.interval = 60 * 60; |
|---|
| 121 | |
|---|
| 122 | 2. For the data soft limit, multiply the interval by the expected max bitrate for your system: |
|---|
| 123 | |
|---|
| 124 | // for 20 Mbps |
|---|
| 125 | bfile_out_settings.data.soft = bfile_out_settings.interval * (20*1024*1024/8); |
|---|
| 126 | |
|---|
| 127 | 3. For the data hard limit, increase from the soft limit by a margin no less than 50% of the soft limit. |
|---|
| 128 | |
|---|
| 129 | // 100% margin |
|---|
| 130 | bfile_out_settings.data.hard = bfile_out_settings.data.soft * 2; |
|---|
| 131 | |
|---|
| 132 | 4. For the index soft limit, multiply the interval by the max size of a NAV entry (for BNAV_AVC_Entry, it's 64 bytes) |
|---|
| 133 | and the max frame rate of the stream (e.g. 60 fps). |
|---|
| 134 | |
|---|
| 135 | // 64 byte NAV, 60fps, and some margin |
|---|
| 136 | bfile_out_settings.index.soft = bfile_out_settings.interval * 64 * 60 * 2; |
|---|
| 137 | |
|---|
| 138 | 5. For the index hard limit, increase from the soft limit by a margin no less than 200% of the soft limit. |
|---|
| 139 | The index buffer is small, so there's a very small cost to guarantee no index overflow. |
|---|
| 140 | |
|---|
| 141 | bfile_out_settings.index.hard = bfile_out_settings.index.soft * 2; |
|---|
| 142 | |
|---|
| 143 | See bfile_out_settings for how bfile_out_limit is used for the data and index files. |
|---|
| 144 | */ |
|---|
| 145 | typedef struct bfile_out_limit { |
|---|
| 146 | off_t soft; /* Targetted file size in bytes. */ |
|---|
| 147 | off_t hard; /* Maximum file size in bytes. */ |
|---|
| 148 | } bfile_out_limit; |
|---|
| 149 | |
|---|
| 150 | /** |
|---|
| 151 | Summary: |
|---|
| 152 | This value is used to indicate if timestamp or index position is invalid |
|---|
| 153 | **/ |
|---|
| 154 | #define BPVR_INVALID_POSITION ((unsigned long)-1) |
|---|
| 155 | |
|---|
| 156 | /** |
|---|
| 157 | Summary: |
|---|
| 158 | bpvr_position provides several types of information about a position in the timeshifting buffer |
|---|
| 159 | |
|---|
| 160 | See also: bfile_fifo_out_position |
|---|
| 161 | **/ |
|---|
| 162 | typedef struct bpvr_position { |
|---|
| 163 | off_t mpeg_file_offset; /* Byte offset in the data file. (called "mpeg" for legacy reasons. it applies to any codec.) */ |
|---|
| 164 | unsigned long index_offset; /* Offset of the current index entry in the index. |
|---|
| 165 | This field is set to BPVR_INVALID_POSITION, if the index is invalid */ |
|---|
| 166 | |
|---|
| 167 | unsigned long timestamp; /* Timestamp of the current index entry in the index. |
|---|
| 168 | Timestamp is different from PTS. Timestamp is generated |
|---|
| 169 | by bcmindexer, it begins at 0 for any recorded stream, |
|---|
| 170 | and is guaranteed to be continuous increasing throughout |
|---|
| 171 | the stream. The units of the timestamp depend on the |
|---|
| 172 | implementation of bcmindexer, but they are defaulted |
|---|
| 173 | to milliseconds. |
|---|
| 174 | This field is set to BPVR_INVALID_POSITION, if the index is invalid */ |
|---|
| 175 | } bpvr_position; |
|---|
| 176 | |
|---|
| 177 | /* |
|---|
| 178 | Summary: |
|---|
| 179 | Configuration parameters for the timeshifting buffer |
|---|
| 180 | */ |
|---|
| 181 | typedef struct bfile_out_settings { |
|---|
| 182 | unsigned interval; /* Amount of time accessible to application in the timeshifting buffer, units are seconds. |
|---|
| 183 | Must set data and index soft/hard limits that coordinate with this interval. See bfile_out_limit. */ |
|---|
| 184 | bfile_out_limit data; /* Limits for the timeshifting data file */ |
|---|
| 185 | bfile_out_limit index; /* Limits for the timeshifting index file */ |
|---|
| 186 | } bfile_out_settings; |
|---|
| 187 | |
|---|
| 188 | /* |
|---|
| 189 | Summary: |
|---|
| 190 | This function opens a new timeshifting buffer |
|---|
| 191 | |
|---|
| 192 | Description: |
|---|
| 193 | The bfile_out_fifo_t can be used for only one record at a time. |
|---|
| 194 | The files will be created if they don't already exist and truncated if they do. |
|---|
| 195 | The index file is mandatory for timeshifting. |
|---|
| 196 | */ |
|---|
| 197 | |
|---|
| 198 | bfile_out_fifo_t bfile_fifo_out_create( |
|---|
| 199 | const char *data_file_name, /* name of data file to create */ |
|---|
| 200 | const char *index_file_name /* name of index file to create */ |
|---|
| 201 | ); |
|---|
| 202 | |
|---|
| 203 | /* |
|---|
| 204 | Summary: |
|---|
| 205 | This function returns position information about the first and last |
|---|
| 206 | picture in the timeshifting buffer |
|---|
| 207 | */ |
|---|
| 208 | bresult bfile_fifo_out_position( |
|---|
| 209 | bfile_out_fifo_t file, /* Handle created by bfile_fifo_out_create() */ |
|---|
| 210 | bpvr_position *first, /* [out] first accessible picture in the file */ |
|---|
| 211 | bpvr_position *last /* [out] last accessible picture in the file */ |
|---|
| 212 | ); |
|---|
| 213 | |
|---|
| 214 | /* |
|---|
| 215 | Summary: |
|---|
| 216 | This function returns a handle to be passed to brecord_start(). |
|---|
| 217 | */ |
|---|
| 218 | brecord_file_t bfile_fifo_out_file( |
|---|
| 219 | bfile_out_fifo_t file /* Handle created by bfile_fifo_out_create() */ |
|---|
| 220 | ); |
|---|
| 221 | |
|---|
| 222 | /* |
|---|
| 223 | Summary: |
|---|
| 224 | This function returns a handle to be passed to bplayback_start(). |
|---|
| 225 | |
|---|
| 226 | Description: |
|---|
| 227 | This function shall be used only for files created by bfile_fifo_out_create(). |
|---|
| 228 | The bplayback_file_t can be used for only one playback at a time. |
|---|
| 229 | |
|---|
| 230 | All the metadata needed to manage the timeshifting buffer is persisted to disk. This means you can close the |
|---|
| 231 | buffer bfile_out_fifo (i.e. stop recording) and at a later time reopen a bplayback_file_t for non-timeshifting playback. |
|---|
| 232 | Pass a NULL to file for non-timeshifting playback. |
|---|
| 233 | |
|---|
| 234 | If bfile_out_fifo_t is currently open, you must not open the data and index file with a NULL as file. |
|---|
| 235 | The metadata is being updated during record and an unlinked playback will get corrupted. |
|---|
| 236 | */ |
|---|
| 237 | bplayback_file_t bfile_fifo_in_open( |
|---|
| 238 | const char *data_file_name, |
|---|
| 239 | const char *index_file_name, |
|---|
| 240 | bfile_out_fifo_t file /* Live recording which will be timeshifted. |
|---|
| 241 | Pass NULL only if this is not a live timeshift. */ |
|---|
| 242 | ); |
|---|
| 243 | |
|---|
| 244 | /* |
|---|
| 245 | Summary: |
|---|
| 246 | Get the current configuration of the timeshifting buffer |
|---|
| 247 | */ |
|---|
| 248 | void |
|---|
| 249 | bfile_fifo_out_get( |
|---|
| 250 | bfile_out_fifo_t file, /* Handle created by bfile_fifo_out_create() */ |
|---|
| 251 | bfile_out_settings *settings /* [out] current settings of timeshifting buffer */ |
|---|
| 252 | ); |
|---|
| 253 | |
|---|
| 254 | /* |
|---|
| 255 | Summary: |
|---|
| 256 | Set a new configuration for the timeshifting buffer |
|---|
| 257 | */ |
|---|
| 258 | bresult |
|---|
| 259 | bfile_fifo_out_set( |
|---|
| 260 | bfile_out_fifo_t file, /* Handle created by bfile_fifo_out_create() */ |
|---|
| 261 | const bfile_out_settings *settings /* new settings of timeshifting buffer */ |
|---|
| 262 | ); |
|---|
| 263 | |
|---|
| 264 | |
|---|
| 265 | struct bfile_io_write_fifo; |
|---|
| 266 | struct bfile_io_read_fifo; |
|---|
| 267 | |
|---|
| 268 | |
|---|
| 269 | /* low level functions */ |
|---|
| 270 | struct bfile_io_write_fifo *bpvrfifo_write_open(const char *fname, int flags, off_t start); |
|---|
| 271 | bfile_io_write_t bpvrfifo_write_file(struct bfile_io_write_fifo *file); |
|---|
| 272 | void bpvrfifo_write_close(struct bfile_io_write_fifo *file); |
|---|
| 273 | struct bfile_io_read_fifo *bpvrfifo_read_open(const char *fname, int flags, struct bfile_io_write_fifo *writer); |
|---|
| 274 | bfile_io_read_t bpvrfifo_read_file(struct bfile_io_read_fifo *file); |
|---|
| 275 | void bpvrfifo_read_close(struct bfile_io_read_fifo *file); |
|---|
| 276 | |
|---|
| 277 | #ifdef __cplusplus |
|---|
| 278 | } |
|---|
| 279 | #endif |
|---|
| 280 | |
|---|
| 281 | #endif /* BSETTOP_FILEIO_FIFO_H__ */ |
|---|
| 282 | |
|---|