1/* 2 * Copyright (c) 2009 Michael Niedermayer 3 * 4 * This file is part of FFmpeg. 5 * 6 * FFmpeg is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * FFmpeg is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with FFmpeg; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21#include "avformat.h" 22#include "internal.h" 23 24 25static int probe(AVProbeData *p) 26{ 27 // the single file I have starts with that, I do not know if others do, too 28 if( p->buf[0] == 1 29 && p->buf[1] == 1 30 && p->buf[2] == 3 31 && p->buf[3] == 0xB8 32 && p->buf[4] == 0x80 33 && p->buf[5] == 0x60 34 ) 35 return AVPROBE_SCORE_MAX-2; 36 37 return 0; 38} 39 40static int read_header(AVFormatContext *s) 41{ 42 AVStream *st; 43 44 st = avformat_new_stream(s, NULL); 45 if (!st) 46 return AVERROR(ENOMEM); 47 48 st->codec->codec_type = AVMEDIA_TYPE_VIDEO; 49 st->codec->codec_id = AV_CODEC_ID_MPEG4; 50 st->need_parsing = AVSTREAM_PARSE_FULL; 51 avpriv_set_pts_info(st, 64, 1, 90000); 52 53 return 0; 54 55} 56 57static int read_packet(AVFormatContext *s, AVPacket *pkt) 58{ 59 int ret, size, pts, type, flags; 60 int first_pkt = 0; 61 int frame_complete = 0; 62 63 while (!frame_complete) { 64 65 type = avio_rb16(s->pb); // 257 or 258 66 size = avio_rb16(s->pb); 67 flags = avio_rb16(s->pb); //some flags, 0x80 indicates end of frame 68 avio_rb16(s->pb); //packet number 69 pts = avio_rb32(s->pb); 70 avio_rb32(s->pb); //6A 13 E3 88 71 72 frame_complete = flags & 0x80; 73 74 size -= 12; 75 if (size < 1) 76 return -1; 77 78 if (type == 258) { 79 avio_skip(s->pb, size); 80 frame_complete = 0; 81 continue; 82 } 83 84 if (!first_pkt) { 85 ret = av_get_packet(s->pb, pkt, size); 86 if (ret < 0) 87 return ret; 88 first_pkt = 1; 89 pkt->pts = pts; 90 pkt->pos -= 16; 91 } else { 92 ret = av_append_packet(s->pb, pkt, size); 93 if (ret < 0) { 94 av_log(s, AV_LOG_ERROR, "failed to grow packet\n"); 95 av_free_packet(pkt); 96 return ret; 97 } 98 } 99 if (ret < size) { 100 av_log(s, AV_LOG_ERROR, "Truncated packet! Read %d of %d bytes\n", 101 ret, size); 102 pkt->flags |= AV_PKT_FLAG_CORRUPT; 103 break; 104 } 105 } 106 pkt->stream_index = 0; 107 108 return 0; 109} 110 111AVInputFormat ff_iv8_demuxer = { 112 .name = "iv8", 113 .long_name = NULL_IF_CONFIG_SMALL("IndigoVision 8000 video"), 114 .read_probe = probe, 115 .read_header = read_header, 116 .read_packet = read_packet, 117 .flags = AVFMT_GENERIC_INDEX, 118}; 119