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