annotate ffmpeg/libavformat/bfi.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 * Brute Force & Ignorance (BFI) demuxer
yading@11 3 * Copyright (c) 2008 Sisir Koppaka
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 /**
yading@11 23 * @file
yading@11 24 * @brief Brute Force & Ignorance (.bfi) file demuxer
yading@11 25 * @author Sisir Koppaka ( sisir.koppaka at gmail dot com )
yading@11 26 * @see http://wiki.multimedia.cx/index.php?title=BFI
yading@11 27 */
yading@11 28
yading@11 29 #include "libavutil/channel_layout.h"
yading@11 30 #include "libavutil/intreadwrite.h"
yading@11 31 #include "avformat.h"
yading@11 32 #include "internal.h"
yading@11 33
yading@11 34 typedef struct BFIContext {
yading@11 35 int nframes;
yading@11 36 int audio_frame;
yading@11 37 int video_frame;
yading@11 38 int video_size;
yading@11 39 int avflag;
yading@11 40 } BFIContext;
yading@11 41
yading@11 42 static int bfi_probe(AVProbeData * p)
yading@11 43 {
yading@11 44 /* Check file header */
yading@11 45 if (AV_RL32(p->buf) == MKTAG('B', 'F', '&', 'I'))
yading@11 46 return AVPROBE_SCORE_MAX;
yading@11 47 else
yading@11 48 return 0;
yading@11 49 }
yading@11 50
yading@11 51 static int bfi_read_header(AVFormatContext * s)
yading@11 52 {
yading@11 53 BFIContext *bfi = s->priv_data;
yading@11 54 AVIOContext *pb = s->pb;
yading@11 55 AVStream *vstream;
yading@11 56 AVStream *astream;
yading@11 57 int fps, chunk_header;
yading@11 58
yading@11 59 /* Initialize the video codec... */
yading@11 60 vstream = avformat_new_stream(s, NULL);
yading@11 61 if (!vstream)
yading@11 62 return AVERROR(ENOMEM);
yading@11 63
yading@11 64 /* Initialize the audio codec... */
yading@11 65 astream = avformat_new_stream(s, NULL);
yading@11 66 if (!astream)
yading@11 67 return AVERROR(ENOMEM);
yading@11 68
yading@11 69 /* Set the total number of frames. */
yading@11 70 avio_skip(pb, 8);
yading@11 71 chunk_header = avio_rl32(pb);
yading@11 72 bfi->nframes = avio_rl32(pb);
yading@11 73 avio_rl32(pb);
yading@11 74 avio_rl32(pb);
yading@11 75 avio_rl32(pb);
yading@11 76 fps = avio_rl32(pb);
yading@11 77 avio_skip(pb, 12);
yading@11 78 vstream->codec->width = avio_rl32(pb);
yading@11 79 vstream->codec->height = avio_rl32(pb);
yading@11 80
yading@11 81 /*Load the palette to extradata */
yading@11 82 avio_skip(pb, 8);
yading@11 83 vstream->codec->extradata = av_malloc(768);
yading@11 84 vstream->codec->extradata_size = 768;
yading@11 85 avio_read(pb, vstream->codec->extradata,
yading@11 86 vstream->codec->extradata_size);
yading@11 87
yading@11 88 astream->codec->sample_rate = avio_rl32(pb);
yading@11 89
yading@11 90 /* Set up the video codec... */
yading@11 91 avpriv_set_pts_info(vstream, 32, 1, fps);
yading@11 92 vstream->codec->codec_type = AVMEDIA_TYPE_VIDEO;
yading@11 93 vstream->codec->codec_id = AV_CODEC_ID_BFI;
yading@11 94 vstream->codec->pix_fmt = AV_PIX_FMT_PAL8;
yading@11 95 vstream->nb_frames =
yading@11 96 vstream->duration = bfi->nframes;
yading@11 97
yading@11 98 /* Set up the audio codec now... */
yading@11 99 astream->codec->codec_type = AVMEDIA_TYPE_AUDIO;
yading@11 100 astream->codec->codec_id = AV_CODEC_ID_PCM_U8;
yading@11 101 astream->codec->channels = 1;
yading@11 102 astream->codec->channel_layout = AV_CH_LAYOUT_MONO;
yading@11 103 astream->codec->bits_per_coded_sample = 8;
yading@11 104 astream->codec->bit_rate =
yading@11 105 astream->codec->sample_rate * astream->codec->bits_per_coded_sample;
yading@11 106 avio_seek(pb, chunk_header - 3, SEEK_SET);
yading@11 107 avpriv_set_pts_info(astream, 64, 1, astream->codec->sample_rate);
yading@11 108 return 0;
yading@11 109 }
yading@11 110
yading@11 111
yading@11 112 static int bfi_read_packet(AVFormatContext * s, AVPacket * pkt)
yading@11 113 {
yading@11 114 BFIContext *bfi = s->priv_data;
yading@11 115 AVIOContext *pb = s->pb;
yading@11 116 int ret, audio_offset, video_offset, chunk_size, audio_size = 0;
yading@11 117 if (bfi->nframes == 0 || url_feof(pb)) {
yading@11 118 return AVERROR_EOF;
yading@11 119 }
yading@11 120
yading@11 121 /* If all previous chunks were completely read, then find a new one... */
yading@11 122 if (!bfi->avflag) {
yading@11 123 uint32_t state = 0;
yading@11 124 while(state != MKTAG('S','A','V','I')){
yading@11 125 if (url_feof(pb))
yading@11 126 return AVERROR(EIO);
yading@11 127 state = 256*state + avio_r8(pb);
yading@11 128 }
yading@11 129 /* Now that the chunk's location is confirmed, we proceed... */
yading@11 130 chunk_size = avio_rl32(pb);
yading@11 131 avio_rl32(pb);
yading@11 132 audio_offset = avio_rl32(pb);
yading@11 133 avio_rl32(pb);
yading@11 134 video_offset = avio_rl32(pb);
yading@11 135 audio_size = video_offset - audio_offset;
yading@11 136 bfi->video_size = chunk_size - video_offset;
yading@11 137
yading@11 138 //Tossing an audio packet at the audio decoder.
yading@11 139 ret = av_get_packet(pb, pkt, audio_size);
yading@11 140 if (ret < 0)
yading@11 141 return ret;
yading@11 142
yading@11 143 pkt->pts = bfi->audio_frame;
yading@11 144 bfi->audio_frame += ret;
yading@11 145 }
yading@11 146
yading@11 147 else {
yading@11 148
yading@11 149 //Tossing a video packet at the video decoder.
yading@11 150 ret = av_get_packet(pb, pkt, bfi->video_size);
yading@11 151 if (ret < 0)
yading@11 152 return ret;
yading@11 153
yading@11 154 pkt->pts = bfi->video_frame;
yading@11 155 bfi->video_frame += bfi->video_size ? ret / bfi->video_size : 1;
yading@11 156
yading@11 157 /* One less frame to read. A cursory decrement. */
yading@11 158 bfi->nframes--;
yading@11 159 }
yading@11 160
yading@11 161 bfi->avflag = !bfi->avflag;
yading@11 162 pkt->stream_index = bfi->avflag;
yading@11 163 return ret;
yading@11 164 }
yading@11 165
yading@11 166 AVInputFormat ff_bfi_demuxer = {
yading@11 167 .name = "bfi",
yading@11 168 .long_name = NULL_IF_CONFIG_SMALL("Brute Force & Ignorance"),
yading@11 169 .priv_data_size = sizeof(BFIContext),
yading@11 170 .read_probe = bfi_probe,
yading@11 171 .read_header = bfi_read_header,
yading@11 172 .read_packet = bfi_read_packet,
yading@11 173 };