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/intreadwrite.h"
32 int audio_size
; /** audio packet size (bytes) */
33 int video_size
; /** video packet size (bytes) */
34 int palette
; /** frame contains palette change */
35 int video_type
; /** per-frame video compression type */
48 #define MAGIC " Compression by John M Phillips Copyright (C) 1995 The Bitmap Brothers Ltd."
50 static int read_probe(AVProbeData
*pd
)
52 if (pd
->buf
[0] == 'J' && pd
->buf
[1] == 'V' &&
53 !memcmp(pd
->buf
+ 4, MAGIC
, FFMIN(strlen(MAGIC
), pd
->buf_size
- 4)))
54 return AVPROBE_SCORE_MAX
;
58 static int read_header(AVFormatContext
*s
,
59 AVFormatParameters
*ap
)
61 JVDemuxContext
*jv
= s
->priv_data
;
62 AVIOContext
*pb
= s
->pb
;
64 int64_t audio_pts
= 0;
70 ast
= av_new_stream(s
, 0);
71 vst
= av_new_stream(s
, 1);
73 return AVERROR(ENOMEM
);
75 vst
->codec
->codec_type
= CODEC_TYPE_VIDEO
;
76 vst
->codec
->codec_id
= CODEC_ID_JV
;
77 vst
->codec
->codec_tag
= 0; /* no fourcc */
78 vst
->codec
->width
= avio_rl16(pb
);
79 vst
->codec
->height
= avio_rl16(pb
);
81 ast
->nb_index_entries
= avio_rl16(pb
);
82 av_set_pts_info(vst
, 64, avio_rl16(pb
), 1000);
86 ast
->codec
->codec_type
= CODEC_TYPE_AUDIO
;
87 ast
->codec
->codec_id
= CODEC_ID_PCM_U8
;
88 ast
->codec
->codec_tag
= 0; /* no fourcc */
89 ast
->codec
->sample_rate
= avio_rl16(pb
);
90 ast
->codec
->channels
= 1;
91 av_set_pts_info(ast
, 64, 1, ast
->codec
->sample_rate
);
95 ast
->index_entries
= av_malloc(ast
->nb_index_entries
* sizeof(*ast
->index_entries
));
96 if (!ast
->index_entries
)
97 return AVERROR(ENOMEM
);
99 jv
->frames
= av_malloc(ast
->nb_index_entries
* sizeof(JVFrame
));
101 return AVERROR(ENOMEM
);
103 offset
= 0x68 + ast
->nb_index_entries
* 16;
104 for(i
= 0; i
< ast
->nb_index_entries
; i
++) {
105 AVIndexEntry
*e
= ast
->index_entries
+ i
;
106 JVFrame
*jvf
= jv
->frames
+ i
;
108 /* total frame size including audio, video, palette data and padding */
109 e
->size
= avio_rl32(pb
);
114 jvf
->audio_size
= avio_rl32(pb
);
115 jvf
->video_size
= avio_rl32(pb
);
116 jvf
->palette
= avio_r8(pb
);
118 av_log(s
, AV_LOG_WARNING
, "unsupported audio codec\n");
119 jvf
->video_type
= avio_r8(pb
);
122 e
->timestamp
= jvf
->audio_size ? audio_pts
: AV_NOPTS_VALUE
;
123 audio_pts
+= jvf
->audio_size
;
125 e
->flags
= jvf
->video_type
!= 1 ? AVINDEX_KEYFRAME
: 0;
128 jv
->state
= JV_AUDIO
;
132 static int read_packet(AVFormatContext
*s
, AVPacket
*pkt
)
134 JVDemuxContext
*jv
= s
->priv_data
;
135 AVIOContext
*pb
= s
->pb
;
136 AVStream
*ast
= s
->streams
[0];
138 while (!url_feof(s
->pb
) && jv
->pts
< ast
->nb_index_entries
) {
139 const AVIndexEntry
*e
= ast
->index_entries
+ jv
->pts
;
140 const JVFrame
*jvf
= jv
->frames
+ jv
->pts
;
145 if (jvf
->audio_size
) {
146 if (av_get_packet(s
->pb
, pkt
, jvf
->audio_size
) < 0)
147 return AVERROR(ENOMEM
);
148 pkt
->stream_index
= 0;
149 pkt
->pts
= e
->timestamp
;
150 pkt
->flags
|= PKT_FLAG_KEY
;
155 if (jvf
->video_size
|| jvf
->palette
) {
156 int size
= jvf
->video_size
+ (jvf
->palette ?
768 : 0);
157 if (av_new_packet(pkt
, size
+ 5))
158 return AVERROR(ENOMEM
);
160 AV_WL32(pkt
->data
, jvf
->video_size
);
161 pkt
->data
[4] = jvf
->video_type
;
162 if (avio_read(pb
, pkt
->data
+ 5, size
) < 0)
165 pkt
->size
= size
+ 5;
166 pkt
->stream_index
= 1;
168 if (jvf
->video_type
!= 1)
169 pkt
->flags
|= PKT_FLAG_KEY
;
173 avio_skip(pb
, FFMAX(e
->size
- jvf
->audio_size
- jvf
->video_size
174 - (jvf
->palette ?
768 : 0), 0));
175 jv
->state
= JV_AUDIO
;
183 static int read_seek(AVFormatContext
*s
, int stream_index
,
184 int64_t ts
, int flags
)
186 JVDemuxContext
*jv
= s
->priv_data
;
187 AVStream
*ast
= s
->streams
[0];
190 if (flags
& (AVSEEK_FLAG_BYTE
|AVSEEK_FLAG_FRAME
))
191 return AVERROR_NOTSUPP
;
193 switch(stream_index
) {
195 i
= av_index_search_timestamp(ast
, ts
, flags
);
204 if (i
< 0 || i
>= ast
->nb_index_entries
)
207 jv
->state
= JV_AUDIO
;
209 avio_seek(s
->pb
, ast
->index_entries
[i
].pos
, SEEK_SET
);
213 AVInputFormat ff_jv_demuxer
= {
215 .long_name
= NULL_IF_CONFIG_SMALL("Bitmap Brothers JV"),
216 .priv_data_size
= sizeof(JVDemuxContext
),
217 .read_probe
= read_probe
,
218 .read_header
= read_header
,
219 .read_packet
= read_packet
,
220 .read_seek
= read_seek
,