1/* 2 * VC1 Test Bitstreams Format Demuxer 3 * Copyright (c) 2006, 2008 Konstantin Shishkov 4 * 5 * This file is part of Libav. 6 * 7 * Libav is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * Libav is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with Libav; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22/** 23 * @file 24 * VC1 test bitstream file demuxer 25 * by Konstantin Shishkov 26 * Format specified in SMPTE standard 421 Annex L 27 */ 28 29#include "libavutil/intreadwrite.h" 30#include "avformat.h" 31#include "internal.h" 32 33#define VC1_EXTRADATA_SIZE 4 34 35static int vc1t_probe(AVProbeData *p) 36{ 37 if (p->buf_size < 24) 38 return 0; 39 if (p->buf[3] != 0xC5 || AV_RL32(&p->buf[4]) != 4 || AV_RL32(&p->buf[20]) != 0xC) 40 return 0; 41 42 return AVPROBE_SCORE_MAX/2; 43} 44 45static int vc1t_read_header(AVFormatContext *s, 46 AVFormatParameters *ap) 47{ 48 AVIOContext *pb = s->pb; 49 AVStream *st; 50 int frames; 51 uint32_t fps; 52 53 frames = avio_rl24(pb); 54 if(avio_r8(pb) != 0xC5 || avio_rl32(pb) != 4) 55 return -1; 56 57 /* init video codec */ 58 st = avformat_new_stream(s, NULL); 59 if (!st) 60 return -1; 61 62 st->codec->codec_type = AVMEDIA_TYPE_VIDEO; 63 st->codec->codec_id = CODEC_ID_WMV3; 64 65 st->codec->extradata = av_malloc(VC1_EXTRADATA_SIZE); 66 st->codec->extradata_size = VC1_EXTRADATA_SIZE; 67 avio_read(pb, st->codec->extradata, VC1_EXTRADATA_SIZE); 68 st->codec->height = avio_rl32(pb); 69 st->codec->width = avio_rl32(pb); 70 if(avio_rl32(pb) != 0xC) 71 return -1; 72 avio_skip(pb, 8); 73 fps = avio_rl32(pb); 74 if(fps == 0xFFFFFFFF) 75 avpriv_set_pts_info(st, 32, 1, 1000); 76 else{ 77 if (!fps) { 78 av_log(s, AV_LOG_ERROR, "Zero FPS specified, defaulting to 1 FPS\n"); 79 fps = 1; 80 } 81 avpriv_set_pts_info(st, 24, 1, fps); 82 st->duration = frames; 83 } 84 85 return 0; 86} 87 88static int vc1t_read_packet(AVFormatContext *s, 89 AVPacket *pkt) 90{ 91 AVIOContext *pb = s->pb; 92 int frame_size; 93 int keyframe = 0; 94 uint32_t pts; 95 96 if(pb->eof_reached) 97 return AVERROR(EIO); 98 99 frame_size = avio_rl24(pb); 100 if(avio_r8(pb) & 0x80) 101 keyframe = 1; 102 pts = avio_rl32(pb); 103 if(av_get_packet(pb, pkt, frame_size) < 0) 104 return AVERROR(EIO); 105 if(s->streams[0]->time_base.den == 1000) 106 pkt->pts = pts; 107 pkt->flags |= keyframe ? AV_PKT_FLAG_KEY : 0; 108 pkt->pos -= 8; 109 110 return pkt->size; 111} 112 113AVInputFormat ff_vc1t_demuxer = { 114 .name = "vc1test", 115 .long_name = NULL_IF_CONFIG_SMALL("VC-1 test bitstream format"), 116 .read_probe = vc1t_probe, 117 .read_header = vc1t_read_header, 118 .read_packet = vc1t_read_packet, 119 .flags = AVFMT_GENERIC_INDEX, 120}; 121