1/* 2 * VC1 Test Bitstreams Format Demuxer 3 * Copyright (c) 2006, 2008 Konstantin Shishkov 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg 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 * FFmpeg 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 FFmpeg; 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 32#define VC1_EXTRADATA_SIZE 4 33 34static int vc1t_probe(AVProbeData *p) 35{ 36 if (p->buf_size < 24) 37 return 0; 38 if (p->buf[3] != 0xC5 || AV_RL32(&p->buf[4]) != 4 || AV_RL32(&p->buf[20]) != 0xC) 39 return 0; 40 41 return AVPROBE_SCORE_MAX/2; 42} 43 44static int vc1t_read_header(AVFormatContext *s, 45 AVFormatParameters *ap) 46{ 47 ByteIOContext *pb = s->pb; 48 AVStream *st; 49 int frames; 50 uint32_t fps; 51 52 frames = get_le24(pb); 53 if(get_byte(pb) != 0xC5 || get_le32(pb) != 4) 54 return -1; 55 56 /* init video codec */ 57 st = av_new_stream(s, 0); 58 if (!st) 59 return -1; 60 61 st->codec->codec_type = AVMEDIA_TYPE_VIDEO; 62 st->codec->codec_id = CODEC_ID_WMV3; 63 64 st->codec->extradata = av_malloc(VC1_EXTRADATA_SIZE); 65 st->codec->extradata_size = VC1_EXTRADATA_SIZE; 66 get_buffer(pb, st->codec->extradata, VC1_EXTRADATA_SIZE); 67 st->codec->height = get_le32(pb); 68 st->codec->width = get_le32(pb); 69 if(get_le32(pb) != 0xC) 70 return -1; 71 url_fskip(pb, 8); 72 fps = get_le32(pb); 73 if(fps == 0xFFFFFFFF) 74 av_set_pts_info(st, 32, 1, 1000); 75 else{ 76 if (!fps) { 77 av_log(s, AV_LOG_ERROR, "Zero FPS specified, defaulting to 1 FPS\n"); 78 fps = 1; 79 } 80 av_set_pts_info(st, 24, 1, fps); 81 st->duration = frames; 82 } 83 84 return 0; 85} 86 87static int vc1t_read_packet(AVFormatContext *s, 88 AVPacket *pkt) 89{ 90 ByteIOContext *pb = s->pb; 91 int frame_size; 92 int keyframe = 0; 93 uint32_t pts; 94 95 if(url_feof(pb)) 96 return AVERROR(EIO); 97 98 frame_size = get_le24(pb); 99 if(get_byte(pb) & 0x80) 100 keyframe = 1; 101 pts = get_le32(pb); 102 if(av_get_packet(pb, pkt, frame_size) < 0) 103 return AVERROR(EIO); 104 if(s->streams[0]->time_base.den == 1000) 105 pkt->pts = pts; 106 pkt->flags |= keyframe ? AV_PKT_FLAG_KEY : 0; 107 pkt->pos -= 8; 108 109 return pkt->size; 110} 111 112AVInputFormat vc1t_demuxer = { 113 "vc1test", 114 NULL_IF_CONFIG_SMALL("VC-1 test bitstream format"), 115 0, 116 vc1t_probe, 117 vc1t_read_header, 118 vc1t_read_packet, 119 .flags = AVFMT_GENERIC_INDEX, 120}; 121