Libav 0.7.1
|
00001 /* 00002 * VC1 Test Bitstreams Format Demuxer 00003 * Copyright (c) 2006, 2008 Konstantin Shishkov 00004 * 00005 * This file is part of Libav. 00006 * 00007 * Libav is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * Libav is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with Libav; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00029 #include "libavutil/intreadwrite.h" 00030 #include "avformat.h" 00031 00032 #define VC1_EXTRADATA_SIZE 4 00033 00034 static int vc1t_probe(AVProbeData *p) 00035 { 00036 if (p->buf_size < 24) 00037 return 0; 00038 if (p->buf[3] != 0xC5 || AV_RL32(&p->buf[4]) != 4 || AV_RL32(&p->buf[20]) != 0xC) 00039 return 0; 00040 00041 return AVPROBE_SCORE_MAX/2; 00042 } 00043 00044 static int vc1t_read_header(AVFormatContext *s, 00045 AVFormatParameters *ap) 00046 { 00047 AVIOContext *pb = s->pb; 00048 AVStream *st; 00049 int frames; 00050 uint32_t fps; 00051 00052 frames = avio_rl24(pb); 00053 if(avio_r8(pb) != 0xC5 || avio_rl32(pb) != 4) 00054 return -1; 00055 00056 /* init video codec */ 00057 st = av_new_stream(s, 0); 00058 if (!st) 00059 return -1; 00060 00061 st->codec->codec_type = AVMEDIA_TYPE_VIDEO; 00062 st->codec->codec_id = CODEC_ID_WMV3; 00063 00064 st->codec->extradata = av_malloc(VC1_EXTRADATA_SIZE); 00065 st->codec->extradata_size = VC1_EXTRADATA_SIZE; 00066 avio_read(pb, st->codec->extradata, VC1_EXTRADATA_SIZE); 00067 st->codec->height = avio_rl32(pb); 00068 st->codec->width = avio_rl32(pb); 00069 if(avio_rl32(pb) != 0xC) 00070 return -1; 00071 avio_skip(pb, 8); 00072 fps = avio_rl32(pb); 00073 if(fps == 0xFFFFFFFF) 00074 av_set_pts_info(st, 32, 1, 1000); 00075 else{ 00076 if (!fps) { 00077 av_log(s, AV_LOG_ERROR, "Zero FPS specified, defaulting to 1 FPS\n"); 00078 fps = 1; 00079 } 00080 av_set_pts_info(st, 24, 1, fps); 00081 st->duration = frames; 00082 } 00083 00084 return 0; 00085 } 00086 00087 static int vc1t_read_packet(AVFormatContext *s, 00088 AVPacket *pkt) 00089 { 00090 AVIOContext *pb = s->pb; 00091 int frame_size; 00092 int keyframe = 0; 00093 uint32_t pts; 00094 00095 if(pb->eof_reached) 00096 return AVERROR(EIO); 00097 00098 frame_size = avio_rl24(pb); 00099 if(avio_r8(pb) & 0x80) 00100 keyframe = 1; 00101 pts = avio_rl32(pb); 00102 if(av_get_packet(pb, pkt, frame_size) < 0) 00103 return AVERROR(EIO); 00104 if(s->streams[0]->time_base.den == 1000) 00105 pkt->pts = pts; 00106 pkt->flags |= keyframe ? AV_PKT_FLAG_KEY : 0; 00107 pkt->pos -= 8; 00108 00109 return pkt->size; 00110 } 00111 00112 AVInputFormat ff_vc1t_demuxer = { 00113 "vc1test", 00114 NULL_IF_CONFIG_SMALL("VC-1 test bitstream format"), 00115 0, 00116 vc1t_probe, 00117 vc1t_read_header, 00118 vc1t_read_packet, 00119 .flags = AVFMT_GENERIC_INDEX, 00120 };