annotate bfi.c @ 3754:8d267b43eaba libavformat

Move malloc() down until after all initializations, so that the resource is only allocated if initialization worked. This means that on failure, we don't have to deallocate it.
author rbultje
date Sat, 23 Aug 2008 18:46:30 +0000
parents 7a0230981402
children 1d3d17de20ba
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3213
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
1 /*
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
2 * Brute Force & Ignorance (BFI) demuxer
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
3 * Copyright (c) 2008 Sisir Koppaka
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
4 *
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
5 * This file is part of FFmpeg.
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
6 *
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
11 *
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
15 * Lesser General Public License for more details.
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
16 *
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
20 */
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
21
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
22 /**
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
23 * @file bfi.c
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
24 * @brief Brute Force & Ignorance (.bfi) file demuxer
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
25 * @author Sisir Koppaka ( sisir.koppaka at gmail dot com )
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
26 * @sa http://wiki.multimedia.cx/index.php?title=BFI
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
27 */
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
28
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
29 #include "avformat.h"
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
30
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
31 typedef struct BFIContext {
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
32 int nframes;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
33 int audio_frame;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
34 int video_frame;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
35 int video_size;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
36 int avflag;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
37 } BFIContext;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
38
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
39 static int bfi_probe(AVProbeData * p)
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
40 {
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
41 /* Check file header */
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
42 if (AV_RL32(p->buf) == MKTAG('B', 'F', '&', 'I'))
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
43 return AVPROBE_SCORE_MAX;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
44 else
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
45 return 0;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
46 }
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
47
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
48 static int bfi_read_header(AVFormatContext * s, AVFormatParameters * ap)
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
49 {
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
50 BFIContext *bfi = s->priv_data;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
51 ByteIOContext *pb = s->pb;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
52 AVStream *vstream;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
53 AVStream *astream;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
54 int fps, chunk_header;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
55
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
56 /* Initialize the video codec... */
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
57 vstream = av_new_stream(s, 0);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
58 if (!vstream)
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
59 return AVERROR(ENOMEM);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
60
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
61 /* Initialize the audio codec... */
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
62 astream = av_new_stream(s, 0);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
63 if (!astream)
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
64 return AVERROR(ENOMEM);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
65
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
66 /* Set the total number of frames. */
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
67 url_fskip(pb, 8);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
68 chunk_header = get_le32(pb);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
69 bfi->nframes = get_le32(pb);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
70 get_le32(pb);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
71 get_le32(pb);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
72 get_le32(pb);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
73 fps = get_le32(pb);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
74 url_fskip(pb, 12);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
75 vstream->codec->width = get_le32(pb);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
76 vstream->codec->height = get_le32(pb);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
77
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
78 /*Load the palette to extradata */
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
79 url_fskip(pb, 8);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
80 vstream->codec->extradata = av_malloc(768);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
81 vstream->codec->extradata_size = 768;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
82 get_buffer(pb, vstream->codec->extradata,
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
83 vstream->codec->extradata_size);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
84
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
85 astream->codec->sample_rate = get_le32(pb);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
86
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
87 /* Set up the video codec... */
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
88 av_set_pts_info(vstream, 32, 1, fps);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
89 vstream->codec->codec_type = CODEC_TYPE_VIDEO;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
90 vstream->codec->codec_id = CODEC_ID_BFI;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
91 vstream->codec->pix_fmt = PIX_FMT_PAL8;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
92
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
93 /* Set up the audio codec now... */
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
94 astream->codec->codec_type = CODEC_TYPE_AUDIO;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
95 astream->codec->codec_id = CODEC_ID_PCM_U8;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
96 astream->codec->channels = 1;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
97 astream->codec->bits_per_sample = 8;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
98 astream->codec->bit_rate =
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
99 astream->codec->sample_rate * astream->codec->bits_per_sample;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
100 url_fseek(pb, chunk_header - 3, SEEK_SET);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
101 av_set_pts_info(astream, 64, 1, astream->codec->sample_rate);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
102 return 0;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
103 }
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
104
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
105
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
106 static int bfi_read_packet(AVFormatContext * s, AVPacket * pkt)
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
107 {
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
108 BFIContext *bfi = s->priv_data;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
109 ByteIOContext *pb = s->pb;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
110 int ret, audio_offset, video_offset, chunk_size, audio_size = 0;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
111 if (bfi->nframes == 0 || url_feof(pb)) {
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
112 return AVERROR(EIO);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
113 }
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
114
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
115 /* If all previous chunks were completely read, then find a new one... */
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
116 if (!bfi->avflag) {
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
117 uint32_t state = 0;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
118 while(state != MKTAG('S','A','V','I')){
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
119 if (url_feof(pb))
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
120 return AVERROR(EIO);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
121 state = 256*state + get_byte(pb);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
122 }
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
123 /* Now that the chunk's location is confirmed, we proceed... */
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
124 chunk_size = get_le32(pb);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
125 get_le32(pb);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
126 audio_offset = get_le32(pb);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
127 get_le32(pb);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
128 video_offset = get_le32(pb);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
129 audio_size = video_offset - audio_offset;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
130 bfi->video_size = chunk_size - video_offset;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
131
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
132 //Tossing an audio packet at the audio decoder.
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
133 ret = av_get_packet(pb, pkt, audio_size);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
134 if (ret < 0)
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
135 return ret;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
136
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
137 pkt->pts = bfi->audio_frame;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
138 bfi->audio_frame += ret;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
139 }
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
140
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
141 else {
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
142
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
143 //Tossing a video packet at the video decoder.
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
144 ret = av_get_packet(pb, pkt, bfi->video_size);
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
145 if (ret < 0)
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
146 return ret;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
147
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
148 pkt->pts = bfi->video_frame;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
149 bfi->video_frame += ret / bfi->video_size;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
150
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
151 /* One less frame to read. A cursory decrement. */
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
152 bfi->nframes--;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
153 }
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
154
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
155 bfi->avflag = !bfi->avflag;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
156 pkt->stream_index = bfi->avflag;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
157 return ret;
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
158 }
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
159
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
160 AVInputFormat bfi_demuxer = {
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
161 "bfi",
3424
7a0230981402 Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents: 3213
diff changeset
162 NULL_IF_CONFIG_SMALL("Brute Force & Ignorance"),
3213
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
163 sizeof(BFIContext),
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
164 bfi_probe,
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
165 bfi_read_header,
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
166 bfi_read_packet,
d5ad219a794f BFI demuxer
vitor
parents:
diff changeset
167 };