libavformat/jvdec.c
Go to the documentation of this file.
1 /*
2  * Bitmap Brothers JV demuxer
3  * Copyright (c) 2005, 2011 Peter Ross <pross@xvid.org>
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
24  * Bitmap Brothers JV demuxer
25  * @author Peter Ross <pross@xvid.org>
26  */
27 
29 #include "libavutil/intreadwrite.h"
30 #include "avformat.h"
31 #include "internal.h"
32 
33 #define JV_PREAMBLE_SIZE 5
34 
35 typedef struct {
36  int audio_size; /** audio packet size (bytes) */
37  int video_size; /** video packet size (bytes) */
38  int palette_size; /** palette size (bytes) */
39  int video_type; /** per-frame video compression type */
40 } JVFrame;
41 
42 typedef struct {
44  enum {
45  JV_AUDIO = 0,
47  JV_PADDING
48  } state;
49  int64_t pts;
51 
52 #define MAGIC " Compression by John M Phillips Copyright (C) 1995 The Bitmap Brothers Ltd."
53 
54 static int read_probe(AVProbeData *pd)
55 {
56  if (pd->buf[0] == 'J' && pd->buf[1] == 'V' && strlen(MAGIC) <= pd->buf_size - 4 &&
57  !memcmp(pd->buf + 4, MAGIC, strlen(MAGIC)))
58  return AVPROBE_SCORE_MAX;
59  return 0;
60 }
61 
63 {
64  JVDemuxContext *jv = s->priv_data;
65  AVIOContext *pb = s->pb;
66  AVStream *vst, *ast;
67  int64_t audio_pts = 0;
68  int64_t offset;
69  int i;
70 
71  avio_skip(pb, 80);
72 
73  ast = avformat_new_stream(s, NULL);
74  vst = avformat_new_stream(s, NULL);
75  if (!ast || !vst)
76  return AVERROR(ENOMEM);
77 
80  vst->codec->codec_tag = 0; /* no fourcc */
81  vst->codec->width = avio_rl16(pb);
82  vst->codec->height = avio_rl16(pb);
83  vst->duration =
84  vst->nb_frames =
85  ast->nb_index_entries = avio_rl16(pb);
86  avpriv_set_pts_info(vst, 64, avio_rl16(pb), 1000);
87 
88  avio_skip(pb, 4);
89 
92  ast->codec->codec_tag = 0; /* no fourcc */
93  ast->codec->sample_rate = avio_rl16(pb);
94  ast->codec->channels = 1;
96  avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
97 
98  avio_skip(pb, 10);
99 
100  ast->index_entries = av_malloc(ast->nb_index_entries * sizeof(*ast->index_entries));
101  if (!ast->index_entries)
102  return AVERROR(ENOMEM);
103 
104  jv->frames = av_malloc(ast->nb_index_entries * sizeof(JVFrame));
105  if (!jv->frames)
106  return AVERROR(ENOMEM);
107 
108  offset = 0x68 + ast->nb_index_entries * 16;
109  for(i = 0; i < ast->nb_index_entries; i++) {
110  AVIndexEntry *e = ast->index_entries + i;
111  JVFrame *jvf = jv->frames + i;
112 
113  /* total frame size including audio, video, palette data and padding */
114  e->size = avio_rl32(pb);
115  e->timestamp = i;
116  e->pos = offset;
117  offset += e->size;
118 
119  jvf->audio_size = avio_rl32(pb);
120  jvf->video_size = avio_rl32(pb);
121  jvf->palette_size = avio_r8(pb) ? 768 : 0;
122  jvf->video_size = FFMIN(FFMAX(jvf->video_size, 0),
123  INT_MAX - JV_PREAMBLE_SIZE - jvf->palette_size);
124  if (avio_r8(pb))
125  av_log(s, AV_LOG_WARNING, "unsupported audio codec\n");
126  jvf->video_type = avio_r8(pb);
127  avio_skip(pb, 1);
128 
129  e->timestamp = jvf->audio_size ? audio_pts : AV_NOPTS_VALUE;
130  audio_pts += jvf->audio_size;
131 
132  e->flags = jvf->video_type != 1 ? AVINDEX_KEYFRAME : 0;
133  }
134 
135  jv->state = JV_AUDIO;
136  return 0;
137 }
138 
140 {
141  JVDemuxContext *jv = s->priv_data;
142  AVIOContext *pb = s->pb;
143  AVStream *ast = s->streams[0];
144 
145  while (!url_feof(s->pb) && jv->pts < ast->nb_index_entries) {
146  const AVIndexEntry *e = ast->index_entries + jv->pts;
147  const JVFrame *jvf = jv->frames + jv->pts;
148 
149  switch(jv->state) {
150  case JV_AUDIO:
151  jv->state++;
152  if (jvf->audio_size ) {
153  if (av_get_packet(s->pb, pkt, jvf->audio_size) < 0)
154  return AVERROR(ENOMEM);
155  pkt->stream_index = 0;
156  pkt->pts = e->timestamp;
157  pkt->flags |= AV_PKT_FLAG_KEY;
158  return 0;
159  }
160  case JV_VIDEO:
161  jv->state++;
162  if (jvf->video_size || jvf->palette_size) {
163  int size = jvf->video_size + jvf->palette_size;
164  if (av_new_packet(pkt, size + JV_PREAMBLE_SIZE))
165  return AVERROR(ENOMEM);
166 
167  AV_WL32(pkt->data, jvf->video_size);
168  pkt->data[4] = jvf->video_type;
169  if ((size = avio_read(pb, pkt->data + JV_PREAMBLE_SIZE, size)) < 0)
170  return AVERROR(EIO);
171 
172  pkt->size = size + JV_PREAMBLE_SIZE;
173  pkt->stream_index = 1;
174  pkt->pts = jv->pts;
175  if (jvf->video_type != 1)
176  pkt->flags |= AV_PKT_FLAG_KEY;
177  return 0;
178  }
179  case JV_PADDING:
180  avio_skip(pb, FFMAX(e->size - jvf->audio_size - jvf->video_size
181  - jvf->palette_size, 0));
182  jv->state = JV_AUDIO;
183  jv->pts++;
184  }
185  }
186 
187  return AVERROR(EIO);
188 }
189 
190 static int read_seek(AVFormatContext *s, int stream_index,
191  int64_t ts, int flags)
192 {
193  JVDemuxContext *jv = s->priv_data;
194  AVStream *ast = s->streams[0];
195  int i;
196 
197  if (flags & (AVSEEK_FLAG_BYTE|AVSEEK_FLAG_FRAME))
198  return AVERROR(ENOSYS);
199 
200  switch(stream_index) {
201  case 0:
202  i = av_index_search_timestamp(ast, ts, flags);
203  break;
204  case 1:
205  i = ts;
206  break;
207  default:
208  return 0;
209  }
210 
211  if (i < 0 || i >= ast->nb_index_entries)
212  return 0;
213  if (avio_seek(s->pb, ast->index_entries[i].pos, SEEK_SET) < 0)
214  return -1;
215 
216  jv->state = JV_AUDIO;
217  jv->pts = i;
218  return 0;
219 }
220 
222 {
223  JVDemuxContext *jv = s->priv_data;
224 
225  av_freep(&jv->frames);
226 
227  return 0;
228 }
229 
231  .name = "jv",
232  .long_name = NULL_IF_CONFIG_SMALL("Bitmap Brothers JV"),
233  .priv_data_size = sizeof(JVDemuxContext),
237  .read_seek = read_seek,
239 };
int video_type
palette size (bytes)
const char * s
Definition: avisynth_c.h:668
Bytestream IO Context.
Definition: avio.h:68
void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
int64_t pos
Definition: avformat.h:592
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:154
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:199
AVIndexEntry * index_entries
Only used if the format does not support seeking natively.
Definition: avformat.h:822
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:256
static int read_packet(AVFormatContext *s, AVPacket *pkt)
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
Format I/O context.
Definition: avformat.h:944
#define MAGIC
#define AV_WL32(p, darg)
Definition: intreadwrite.h:282
static AVPacket pkt
Definition: demuxing.c:56
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
AVStream ** streams
Definition: avformat.h:992
#define JV_PREAMBLE_SIZE
uint8_t * data
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
static int read_seek(AVFormatContext *s, int stream_index, int64_t ts, int flags)
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:478
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: avpacket.c:73
#define AVINDEX_KEYFRAME
Definition: avformat.h:599
int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags)
Get the index for a specific timestamp.
unsigned int avio_rl32(AVIOContext *s)
Definition: aviobuf.c:579
int64_t timestamp
Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are...
Definition: avformat.h:593
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
enum JVDemuxContext::@143 state
static const uint8_t offset[127][2]
Definition: vf_spp.c:70
#define FFMAX(a, b)
Definition: common.h:56
int size
int flags
A combination of AV_PKT_FLAG values.
uint64_t channel_layout
Audio channel layout.
int avio_r8(AVIOContext *s)
Definition: aviobuf.c:469
AVCodecContext * codec
Codec context associated with this stream.
Definition: avformat.h:662
int buf_size
Size of buf except extra allocated bytes.
Definition: avformat.h:337
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:336
audio channel layout utility functions
#define FFMIN(a, b)
Definition: common.h:58
static int read_probe(AVProbeData *pd)
int width
picture width / height.
int palette_size
video packet size (bytes)
int url_feof(AVIOContext *s)
feof() equivalent for AVIOContext.
Definition: aviobuf.c:280
static int read_close(AVFormatContext *s)
Stream structure.
Definition: avformat.h:643
NULL
Definition: eval.c:55
enum AVMediaType codec_type
enum AVCodecID codec_id
int sample_rate
samples per second
AVIOContext * pb
I/O context.
Definition: avformat.h:977
unsigned int codec_tag
fourcc (LSB first, so "ABCD" -> (&#39;D&#39;<<24) + (&#39;C&#39;<<16) + (&#39;B&#39;<<8) + &#39;A&#39;).
int nb_index_entries
Definition: avformat.h:824
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:73
synthesis window for stochastic i
#define AVSEEK_FLAG_BYTE
seeking based on position in bytes
Definition: avformat.h:1744
This structure contains the data a format has to probe a file.
Definition: avformat.h:334
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
static uint32_t state
Definition: trasher.c:27
static int flags
Definition: cpu.c:23
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:696
#define AVPROBE_SCORE_MAX
maximum score, half of that is used for file-extension-based detection
Definition: avformat.h:340
unsigned int avio_rl16(AVIOContext *s)
Definition: aviobuf.c:563
Main libavformat public API header.
int video_size
audio packet size (bytes)
int64_t nb_frames
number of frames in this stream if known or 0
Definition: avformat.h:698
int channels
number of audio channels
void * priv_data
Format private data.
Definition: avformat.h:964
#define AVSEEK_FLAG_FRAME
seeking based on frame number
Definition: avformat.h:1746
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:461
#define AV_CH_LAYOUT_MONO
This structure stores compressed data.
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:190
AVInputFormat ff_jv_demuxer
static int read_header(AVFormatContext *s)