31 #define SERIES1_PES_LENGTH 11 32 #define SERIES2_PES_LENGTH 16 33 #define AC3_PES_LENGTH 14 34 #define VIDEO_PES_LENGTH 16 35 #define DTIVO_PTS_OFFSET 6 36 #define SA_PTS_OFFSET 9 37 #define AC3_PTS_OFFSET 9 38 #define VIDEO_PTS_OFFSET 9 39 #define AC3_PKT_LENGTH 1536 45 #define TIVO_PES_FILEID 0xf5467abd 46 #define CHUNK_SIZE (128 * 1024) 47 #define CHUNK_PEEK_COUNT 3 134 for (i = 0; i < num_recs; i++) {
135 const uint8_t *record_header = buf + (i * 16);
138 rec_hdr->
rec_type = record_header[3];
139 rec_hdr->subrec_type = record_header[2] & 0x0f;
140 if ((record_header[0] & 0x80) == 0x80) {
144 b1 = (((record_header[0] & 0x0f) << 4) |
145 ((record_header[1] & 0xf0) >> 4));
146 b2 = (((record_header[1] & 0x0f) << 4) |
147 ((record_header[2] & 0xf0) >> 4));
151 rec_hdr->rec_size = 0;
154 rec_hdr->rec_size = (record_header[0] << 8 |
155 record_header[1]) << 4 |
156 (record_header[2] >> 4);
157 rec_hdr->ty_pts =
AV_RB64(&record_header[8]);
168 for (count = 0; count < search_len; count++) {
169 if (!memcmp(&buffer[count], header, 4))
180 int num_6e0, num_be0, num_9c0, num_3c0;
195 ff_dlog(s,
"probe: chunk has %d recs\n", num_recs);
207 num_6e0 = num_be0 = num_9c0 = num_3c0 = 0;
208 for (i = 0; i < num_recs; i++) {
224 ff_dlog(s,
"probe: chunk has %d 0x6e0 recs, %d 0xbe0 recs.\n",
229 ff_dlog(s,
"detected Series 1 Tivo\n");
232 }
else if (num_be0 > 0) {
233 ff_dlog(s,
"detected Series 2 Tivo\n");
238 ff_dlog(s,
"detected AC-3 Audio (DTivo)\n");
243 }
else if (num_3c0 > 0) {
245 ff_dlog(s,
"detected MPEG Audio\n");
251 uint32_t data_offset = 16 * num_recs;
253 for (i = 0; i < num_recs; i++) {
260 &chunk[data_offset], 5);
261 if (pes_offset >= 0) {
263 if ((chunk[data_offset + 6 + pes_offset] & 0x80) == 0x80) {
266 ff_dlog(s,
"detected Stand-Alone Tivo\n");
271 ff_dlog(s,
"detected DirecTV Tivo\n");
398 int read_size, num_recs;
421 if (ty->
chunk[3] & 0x80) {
436 ff_dlog(s,
"chunk has %d records\n", num_recs);
460 if (subrec_type != 0x02 && subrec_type != 0x0c &&
461 subrec_type != 0x08 && rec_size > 4) {
466 if (es_offset1 != -1) {
469 if (subrec_type != 0x06) {
484 ff_dlog(s,
"video rec type 0x%02x has short PES" 485 " (%"PRId64
" bytes)\n", subrec_type, rec_size);
494 if (subrec_type == 0x06) {
510 if (subrec_type != 0x02) {
511 if (subrec_type == 0x0c && pkt->
size >= 6)
512 pkt->
data[5] |= 0x08;
513 if (subrec_type == 0x07) {
543 if (offset < 0 || offset + ty->pes_length > rec_len) {
545 ff_dlog(s,
"PES header at %"PRId32
" not complete in record. storing.\n", offset);
552 ff_dlog(s,
"PES header not found in record of %"PRId32
" bytes!\n", rec_len);
583 if (subrec_type == 2) {
593 ff_dlog(s,
"continuing PES header\n");
595 if (need >= rec_size) {
614 if (es_offset1 < 0) {
615 ff_dlog(s,
"Can't find audio PES header in packet.\n");
645 }
else if (subrec_type == 0x03) {
657 if ((es_offset1 == 0) && (rec_size == 16)) {
674 }
else if (subrec_type == 0x04) {
683 }
else if (subrec_type == 0x09) {
787 .extensions =
"ty,ty+",
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
#define SERIES1_PES_LENGTH
static int check_sync_pes(AVFormatContext *s, AVPacket *pkt, int32_t offset, int32_t rec_len)
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
static int analyze_chunk(AVFormatContext *s, const uint8_t *chunk)
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
static int demux_video(AVFormatContext *s, TyRecHdr *rec_hdr, AVPacket *pkt)
static int ty_read_header(AVFormatContext *s)
enum AVStreamParseType need_parsing
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
#define AVERROR_EOF
End of file.
static av_cold int read_close(AVFormatContext *ctx)
static const uint8_t header[24]
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
static const uint8_t ty_MPEGAudioPacket[]
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static const uint8_t ty_AC3AudioPacket[]
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
enum AVMediaType codec_type
General type of the encoded data.
static const uint8_t offset[127][2]
static int64_t ff_parse_pes_pts(const uint8_t *buf)
Parse MPEG-PES five-byte timestamp.
int buf_size
Size of buf except extra allocated bytes.
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
#define SERIES2_PES_LENGTH
uint8_t chunk[CHUNK_SIZE]
preferred ID for MPEG-1/2 video decoding
static int read_header(FFV1Context *f)
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
AVIOContext * pb
I/O context.
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
AVInputFormat ff_ty_demuxer
static int get_chunk(AVFormatContext *s)
static int ty_read_packet(AVFormatContext *s, AVPacket *pkt)
static const uint8_t ty_VideoPacket[]
This structure contains the data a format has to probe a file.
static int demux_audio(AVFormatContext *s, TyRecHdr *rec_hdr, AVPacket *pkt)
static int find_es_header(const uint8_t *header, const uint8_t *buffer, int search_len)
static TyRecHdr * parse_chunk_headers(const uint8_t *buf, int num_recs)
static int ty_read_close(AVFormatContext *s)
void * priv_data
Format private data.
AVCodecParameters * codecpar
Codec parameters associated with this stream.
int avio_feof(AVIOContext *s)
feof() equivalent for AVIOContext.
This structure stores compressed data.
static void parse_master(AVFormatContext *s)
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
#define AV_NOPTS_VALUE
Undefined timestamp value.
static int ty_probe(AVProbeData *p)