annotate ffmpeg/libavformat/dfa.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents f445c3017523
children
rev   line source
yading@11 1 /*
yading@11 2 * Chronomaster DFA Format Demuxer
yading@11 3 * Copyright (c) 2011 Konstantin Shishkov
yading@11 4 *
yading@11 5 * This file is part of FFmpeg.
yading@11 6 *
yading@11 7 * FFmpeg is free software; you can redistribute it and/or
yading@11 8 * modify it under the terms of the GNU Lesser General Public
yading@11 9 * License as published by the Free Software Foundation; either
yading@11 10 * version 2.1 of the License, or (at your option) any later version.
yading@11 11 *
yading@11 12 * FFmpeg is distributed in the hope that it will be useful,
yading@11 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@11 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@11 15 * Lesser General Public License for more details.
yading@11 16 *
yading@11 17 * You should have received a copy of the GNU Lesser General Public
yading@11 18 * License along with FFmpeg; if not, write to the Free Software
yading@11 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@11 20 */
yading@11 21
yading@11 22 #include "libavutil/intreadwrite.h"
yading@11 23 #include "avformat.h"
yading@11 24 #include "internal.h"
yading@11 25
yading@11 26 static int dfa_probe(AVProbeData *p)
yading@11 27 {
yading@11 28 if (p->buf_size < 4 || AV_RL32(p->buf) != MKTAG('D', 'F', 'I', 'A'))
yading@11 29 return 0;
yading@11 30
yading@11 31 return AVPROBE_SCORE_MAX;
yading@11 32 }
yading@11 33
yading@11 34 static int dfa_read_header(AVFormatContext *s)
yading@11 35 {
yading@11 36 AVIOContext *pb = s->pb;
yading@11 37 AVStream *st;
yading@11 38 int frames;
yading@11 39 int version;
yading@11 40 uint32_t mspf;
yading@11 41
yading@11 42 if (avio_rl32(pb) != MKTAG('D', 'F', 'I', 'A')) {
yading@11 43 av_log(s, AV_LOG_ERROR, "Invalid magic for DFA\n");
yading@11 44 return AVERROR_INVALIDDATA;
yading@11 45 }
yading@11 46
yading@11 47 version = avio_rl16(pb);
yading@11 48 frames = avio_rl16(pb);
yading@11 49
yading@11 50 st = avformat_new_stream(s, NULL);
yading@11 51 if (!st)
yading@11 52 return AVERROR(ENOMEM);
yading@11 53
yading@11 54 st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
yading@11 55 st->codec->codec_id = AV_CODEC_ID_DFA;
yading@11 56 st->codec->width = avio_rl16(pb);
yading@11 57 st->codec->height = avio_rl16(pb);
yading@11 58 mspf = avio_rl32(pb);
yading@11 59 if (!mspf) {
yading@11 60 av_log(s, AV_LOG_WARNING, "Zero FPS reported, defaulting to 10\n");
yading@11 61 mspf = 100;
yading@11 62 }
yading@11 63 avpriv_set_pts_info(st, 24, mspf, 1000);
yading@11 64 avio_skip(pb, 128 - 16); // padding
yading@11 65 st->duration = frames;
yading@11 66
yading@11 67 st->codec->extradata = av_malloc(2);
yading@11 68 st->codec->extradata_size = 2;
yading@11 69 AV_WL16(st->codec->extradata, version);
yading@11 70 if (version == 0x100)
yading@11 71 st->sample_aspect_ratio = (AVRational){2, 1};
yading@11 72
yading@11 73 return 0;
yading@11 74 }
yading@11 75
yading@11 76 static int dfa_read_packet(AVFormatContext *s, AVPacket *pkt)
yading@11 77 {
yading@11 78 AVIOContext *pb = s->pb;
yading@11 79 uint32_t frame_size;
yading@11 80 int ret, first = 1;
yading@11 81
yading@11 82 if (pb->eof_reached)
yading@11 83 return AVERROR_EOF;
yading@11 84
yading@11 85 if (av_get_packet(pb, pkt, 12) != 12)
yading@11 86 return AVERROR(EIO);
yading@11 87 while (!pb->eof_reached) {
yading@11 88 if (!first) {
yading@11 89 ret = av_append_packet(pb, pkt, 12);
yading@11 90 if (ret < 0) {
yading@11 91 av_free_packet(pkt);
yading@11 92 return ret;
yading@11 93 }
yading@11 94 } else
yading@11 95 first = 0;
yading@11 96 frame_size = AV_RL32(pkt->data + pkt->size - 8);
yading@11 97 if (frame_size > INT_MAX - 4) {
yading@11 98 av_log(s, AV_LOG_ERROR, "Too large chunk size: %d\n", frame_size);
yading@11 99 return AVERROR(EIO);
yading@11 100 }
yading@11 101 if (AV_RL32(pkt->data + pkt->size - 12) == MKTAG('E', 'O', 'F', 'R')) {
yading@11 102 if (frame_size) {
yading@11 103 av_log(s, AV_LOG_WARNING, "skipping %d bytes of end-of-frame marker chunk\n",
yading@11 104 frame_size);
yading@11 105 avio_skip(pb, frame_size);
yading@11 106 }
yading@11 107 return 0;
yading@11 108 }
yading@11 109 ret = av_append_packet(pb, pkt, frame_size);
yading@11 110 if (ret < 0) {
yading@11 111 av_free_packet(pkt);
yading@11 112 return ret;
yading@11 113 }
yading@11 114 }
yading@11 115
yading@11 116 return 0;
yading@11 117 }
yading@11 118
yading@11 119 AVInputFormat ff_dfa_demuxer = {
yading@11 120 .name = "dfa",
yading@11 121 .long_name = NULL_IF_CONFIG_SMALL("Chronomaster DFA"),
yading@11 122 .read_probe = dfa_probe,
yading@11 123 .read_header = dfa_read_header,
yading@11 124 .read_packet = dfa_read_packet,
yading@11 125 .flags = AVFMT_GENERIC_INDEX,
yading@11 126 };