2 * Bitmap Brothers JV demuxer
3 * Copyright (c) 2005, 2011 Peter Ross <pross@xvid.org>
5 * This file is part of FFmpeg.
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.
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.
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
24 * Bitmap Brothers JV demuxer
25 * @author Peter Ross <pross@xvid.org>
28 #include "libavutil/channel_layout.h"
29 #include "libavutil/intreadwrite.h"
34 #define JV_PREAMBLE_SIZE 5
37 int audio_size
; /**< audio packet size (bytes) */
38 int video_size
; /**< video packet size (bytes) */
39 int palette_size
; /**< palette size (bytes) */
40 int video_type
; /**< per-frame video compression type */
53 #define MAGIC " Compression by John M Phillips Copyright (C) 1995 The Bitmap Brothers Ltd."
55 static int read_probe(AVProbeData
*pd
)
57 if (pd
->buf
[0] == 'J' && pd
->buf
[1] == 'V' && strlen(MAGIC
) <= pd
->buf_size
- 4 &&
58 !memcmp(pd
->buf
+ 4, MAGIC
, strlen(MAGIC
)))
59 return AVPROBE_SCORE_MAX
;
63 static int read_close(AVFormatContext
*s
)
65 JVDemuxContext
*jv
= s
->priv_data
;
67 av_freep(&jv
->frames
);
72 static int read_header(AVFormatContext
*s
)
74 JVDemuxContext
*jv
= s
->priv_data
;
75 AVIOContext
*pb
= s
->pb
;
77 int64_t audio_pts
= 0;
83 ast
= avformat_new_stream(s
, NULL
);
84 vst
= avformat_new_stream(s
, NULL
);
86 return AVERROR(ENOMEM
);
88 vst
->codec
->codec_type
= AVMEDIA_TYPE_VIDEO
;
89 vst
->codec
->codec_id
= AV_CODEC_ID_JV
;
90 vst
->codec
->codec_tag
= 0; /* no fourcc */
91 vst
->codec
->width
= avio_rl16(pb
);
92 vst
->codec
->height
= avio_rl16(pb
);
95 ast
->nb_index_entries
= avio_rl16(pb
);
96 avpriv_set_pts_info(vst
, 64, avio_rl16(pb
), 1000);
100 ast
->codec
->codec_type
= AVMEDIA_TYPE_AUDIO
;
101 ast
->codec
->codec_id
= AV_CODEC_ID_PCM_U8
;
102 ast
->codec
->codec_tag
= 0; /* no fourcc */
103 ast
->codec
->sample_rate
= avio_rl16(pb
);
104 ast
->codec
->channels
= 1;
105 ast
->codec
->channel_layout
= AV_CH_LAYOUT_MONO
;
106 avpriv_set_pts_info(ast
, 64, 1, ast
->codec
->sample_rate
);
110 ast
->index_entries
= av_malloc(ast
->nb_index_entries
*
111 sizeof(*ast
->index_entries
));
112 if (!ast
->index_entries
)
113 return AVERROR(ENOMEM
);
115 jv
->frames
= av_malloc(ast
->nb_index_entries
* sizeof(JVFrame
));
117 return AVERROR(ENOMEM
);
119 offset
= 0x68 + ast
->nb_index_entries
* 16;
120 for (i
= 0; i
< ast
->nb_index_entries
; i
++) {
121 AVIndexEntry
*e
= ast
->index_entries
+ i
;
122 JVFrame
*jvf
= jv
->frames
+ i
;
124 /* total frame size including audio, video, palette data and padding */
125 e
->size
= avio_rl32(pb
);
130 jvf
->audio_size
= avio_rl32(pb
);
131 jvf
->video_size
= avio_rl32(pb
);
132 jvf
->palette_size
= avio_r8(pb
) ? 768 : 0;
134 if ((jvf
->video_size
| jvf
->audio_size
) & ~0xFFFFFF ||
135 e
->size
- jvf
->audio_size
137 - jvf
->palette_size
< 0) {
138 if (s
->error_recognition
& AV_EF_EXPLODE
) {
140 return AVERROR_INVALIDDATA
;
144 jvf
->palette_size
= 0;
148 av_log(s
, AV_LOG_WARNING
, "unsupported audio codec\n");
150 jvf
->video_type
= avio_r8(pb
);
153 e
->timestamp
= jvf
->audio_size
? audio_pts
: AV_NOPTS_VALUE
;
154 audio_pts
+= jvf
->audio_size
;
156 e
->flags
= jvf
->video_type
!= 1 ? AVINDEX_KEYFRAME
: 0;
159 jv
->state
= JV_AUDIO
;
163 static int read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
165 JVDemuxContext
*jv
= s
->priv_data
;
166 AVIOContext
*pb
= s
->pb
;
167 AVStream
*ast
= s
->streams
[0];
169 while (!avio_feof(s
->pb
) && jv
->pts
< ast
->nb_index_entries
) {
170 const AVIndexEntry
*e
= ast
->index_entries
+ jv
->pts
;
171 const JVFrame
*jvf
= jv
->frames
+ jv
->pts
;
176 if (jvf
->audio_size
) {
177 if (av_get_packet(s
->pb
, pkt
, jvf
->audio_size
) < 0)
178 return AVERROR(ENOMEM
);
179 pkt
->stream_index
= 0;
180 pkt
->pts
= e
->timestamp
;
181 pkt
->flags
|= AV_PKT_FLAG_KEY
;
186 if (jvf
->video_size
|| jvf
->palette_size
) {
188 int size
= jvf
->video_size
+ jvf
->palette_size
;
189 if (av_new_packet(pkt
, size
+ JV_PREAMBLE_SIZE
))
190 return AVERROR(ENOMEM
);
192 AV_WL32(pkt
->data
, jvf
->video_size
);
193 pkt
->data
[4] = jvf
->video_type
;
194 ret
= avio_read(pb
, pkt
->data
+ JV_PREAMBLE_SIZE
, size
);
198 memset(pkt
->data
+ JV_PREAMBLE_SIZE
+ ret
, 0,
199 FF_INPUT_BUFFER_PADDING_SIZE
);
200 pkt
->flags
|= AV_PKT_FLAG_CORRUPT
;
202 pkt
->size
= ret
+ JV_PREAMBLE_SIZE
;
203 pkt
->stream_index
= 1;
205 if (jvf
->video_type
!= 1)
206 pkt
->flags
|= AV_PKT_FLAG_KEY
;
210 avio_skip(pb
, FFMAX(e
->size
- jvf
->audio_size
- jvf
->video_size
211 - jvf
->palette_size
, 0));
212 jv
->state
= JV_AUDIO
;
217 if (s
->pb
->eof_reached
)
223 static int read_seek(AVFormatContext
*s
, int stream_index
,
224 int64_t ts
, int flags
)
226 JVDemuxContext
*jv
= s
->priv_data
;
227 AVStream
*ast
= s
->streams
[0];
230 if (flags
& (AVSEEK_FLAG_BYTE
| AVSEEK_FLAG_FRAME
))
231 return AVERROR(ENOSYS
);
233 switch (stream_index
) {
235 i
= av_index_search_timestamp(ast
, ts
, flags
);
244 if (i
< 0 || i
>= ast
->nb_index_entries
)
246 if (avio_seek(s
->pb
, ast
->index_entries
[i
].pos
, SEEK_SET
) < 0)
249 jv
->state
= JV_AUDIO
;
254 AVInputFormat ff_jv_demuxer
= {
256 .long_name
= NULL_IF_CONFIG_SMALL("Bitmap Brothers JV"),
257 .priv_data_size
= sizeof(JVDemuxContext
),
258 .read_probe
= read_probe
,
259 .read_header
= read_header
,
260 .read_packet
= read_packet
,
261 .read_seek
= read_seek
,
262 .read_close
= read_close
,