FFmpeg
Loading...
Searching...
No Matches
ipmovie.c
Go to the documentation of this file.
1/*
2 * Interplay MVE File Demuxer
3 * Copyright (c) 2003 The FFmpeg project
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 * Interplay MVE file demuxer
25 * by Mike Melanson (melanson@pcisys.net)
26 * For more information regarding the Interplay MVE file format, visit:
27 * http://www.pcisys.net/~melanson/codecs/
28 * The aforementioned site also contains a command line utility for parsing
29 * IP MVE files so that you can get a good idea of the typical structure of
30 * such files. This demuxer is not the best example to use if you are trying
31 * to write your own as it uses a rather roundabout approach for splitting
32 * up and sending out the chunks.
33 */
34
37#include "avformat.h"
38#include "avio_internal.h"
39#include "demux.h"
40#include "internal.h"
41
42#define CHUNK_PREAMBLE_SIZE 4
43#define OPCODE_PREAMBLE_SIZE 4
44
45#define CHUNK_INIT_AUDIO 0x0000
46#define CHUNK_AUDIO_ONLY 0x0001
47#define CHUNK_INIT_VIDEO 0x0002
48#define CHUNK_VIDEO 0x0003
49#define CHUNK_SHUTDOWN 0x0004
50#define CHUNK_END 0x0005
51/* these last types are used internally */
52#define CHUNK_HAVE_PACKET 0xFFFB
53#define CHUNK_DONE 0xFFFC
54#define CHUNK_NOMEM 0xFFFD
55#define CHUNK_EOF 0xFFFE
56#define CHUNK_BAD 0xFFFF
57
58#define OPCODE_END_OF_STREAM 0x00
59#define OPCODE_END_OF_CHUNK 0x01
60#define OPCODE_CREATE_TIMER 0x02
61#define OPCODE_INIT_AUDIO_BUFFERS 0x03
62#define OPCODE_START_STOP_AUDIO 0x04
63#define OPCODE_INIT_VIDEO_BUFFERS 0x05
64#define OPCODE_VIDEO_DATA_06 0x06
65#define OPCODE_SEND_BUFFER 0x07
66#define OPCODE_AUDIO_FRAME 0x08
67#define OPCODE_SILENCE_FRAME 0x09
68#define OPCODE_INIT_VIDEO_MODE 0x0A
69#define OPCODE_CREATE_GRADIENT 0x0B
70#define OPCODE_SET_PALETTE 0x0C
71#define OPCODE_SET_PALETTE_COMPRESSED 0x0D
72#define OPCODE_SET_SKIP_MAP 0x0E
73#define OPCODE_SET_DECODING_MAP 0x0F
74#define OPCODE_VIDEO_DATA_10 0x10
75#define OPCODE_VIDEO_DATA_11 0x11
76#define OPCODE_UNKNOWN_12 0x12
77#define OPCODE_UNKNOWN_13 0x13
78#define OPCODE_UNKNOWN_14 0x14
79#define OPCODE_UNKNOWN_15 0x15
80
81#define PALETTE_COUNT 256
82
121
123 AVPacket *pkt) {
124
125 int chunk_type;
126
127 if (s->audio_chunk_offset && s->audio_channels && s->audio_bits) {
128 if (s->audio_type == AV_CODEC_ID_NONE) {
129 av_log(s->avf, AV_LOG_ERROR, "Can not read audio packet before"
130 "audio codec is known\n");
131 return CHUNK_BAD;
132 }
133
134 /* adjust for PCM audio by skipping chunk header */
135 if (s->audio_type != AV_CODEC_ID_INTERPLAY_DPCM) {
136 s->audio_chunk_offset += 6;
137 s->audio_chunk_size -= 6;
138 }
139
140 avio_seek(pb, s->audio_chunk_offset, SEEK_SET);
141 s->audio_chunk_offset = 0;
142
143 if (s->audio_chunk_size != av_get_packet(pb, pkt, s->audio_chunk_size))
144 return CHUNK_EOF;
145
146 pkt->stream_index = s->audio_stream_index;
147 pkt->pts = s->audio_frame_count;
148
149 /* audio frame maintenance */
150 if (s->audio_type != AV_CODEC_ID_INTERPLAY_DPCM)
151 s->audio_frame_count +=
152 (s->audio_chunk_size / s->audio_channels / (s->audio_bits / 8));
153 else
154 s->audio_frame_count +=
155 (s->audio_chunk_size - 6 - s->audio_channels) / s->audio_channels;
156
157 av_log(s->avf, AV_LOG_TRACE, "sending audio frame with pts %"PRId64" (%d audio frames)\n",
158 pkt->pts, s->audio_frame_count);
159
160 chunk_type = CHUNK_HAVE_PACKET;
161
162 } else if (s->frame_format) {
163
164 /* send the frame format, decode map, the video data, skip map, and the send_buffer flag together */
165
166 if (av_new_packet(pkt, 8 + s->decode_map_chunk_size + s->video_chunk_size + s->skip_map_chunk_size))
167 return CHUNK_NOMEM;
168
169 if (s->has_palette) {
170 uint8_t *pal;
171
174 if (pal) {
175 memcpy(pal, s->palette, AVPALETTE_SIZE);
176 s->has_palette = 0;
177 }
178 }
179
180 if (s->changed) {
181 ff_add_param_change(pkt, 0, 0, 0, s->video_width, s->video_height);
182 s->changed = 0;
183 }
184
185 AV_WL8(pkt->data, s->frame_format);
186 AV_WL8(pkt->data + 1, s->send_buffer);
187 AV_WL16(pkt->data + 2, s->video_chunk_size);
188 AV_WL16(pkt->data + 4, s->decode_map_chunk_size);
189 AV_WL16(pkt->data + 6, s->skip_map_chunk_size);
190
191 s->frame_format = 0;
192 s->send_buffer = 0;
193
194 pkt->pos = s->video_chunk_offset;
195 avio_seek(pb, s->video_chunk_offset, SEEK_SET);
196 s->video_chunk_offset = 0;
197
198 if (avio_read(pb, pkt->data + 8, s->video_chunk_size) !=
199 s->video_chunk_size) {
200 return CHUNK_EOF;
201 }
202
203 if (s->decode_map_chunk_size) {
204 pkt->pos = s->decode_map_chunk_offset;
205 avio_seek(pb, s->decode_map_chunk_offset, SEEK_SET);
206 s->decode_map_chunk_offset = 0;
207
208 if (avio_read(pb, pkt->data + 8 + s->video_chunk_size,
209 s->decode_map_chunk_size) != s->decode_map_chunk_size) {
210 return CHUNK_EOF;
211 }
212 }
213
214 if (s->skip_map_chunk_size) {
215 pkt->pos = s->skip_map_chunk_offset;
216 avio_seek(pb, s->skip_map_chunk_offset, SEEK_SET);
217 s->skip_map_chunk_offset = 0;
218
219 if (avio_read(pb, pkt->data + 8 + s->video_chunk_size + s->decode_map_chunk_size,
220 s->skip_map_chunk_size) != s->skip_map_chunk_size) {
221 return CHUNK_EOF;
222 }
223 }
224
225 s->video_chunk_size = 0;
226 s->decode_map_chunk_size = 0;
227 s->skip_map_chunk_size = 0;
228
229 pkt->stream_index = s->video_stream_index;
230 pkt->pts = s->video_pts;
231
232 av_log(s->avf, AV_LOG_TRACE, "sending video frame with pts %"PRId64"\n", pkt->pts);
233
234 s->video_pts += s->frame_pts_inc;
235
236 chunk_type = CHUNK_HAVE_PACKET;
237
238 } else {
239
240 avio_seek(pb, s->next_chunk_offset, SEEK_SET);
241 chunk_type = CHUNK_DONE;
242
243 }
244
245 return chunk_type;
246}
247
249{
250 IPMVEContext *ipmovie = s->priv_data;
252 if (!st)
253 return AVERROR(ENOMEM);
254 avpriv_set_pts_info(st, 32, 1, ipmovie->audio_sample_rate);
255 ipmovie->audio_stream_index = st->index;
257 st->codecpar->codec_id = ipmovie->audio_type;
258 st->codecpar->codec_tag = 0; /* no tag */
260 st->codecpar->sample_rate = ipmovie->audio_sample_rate;
262 st->codecpar->bit_rate = ipmovie->audio_channels * st->codecpar->sample_rate *
265 st->codecpar->bit_rate /= 2;
267
268 return 0;
269}
270
271/* This function loads and processes a single chunk in an IP movie file.
272 * It returns the type of chunk that was processed. */
274 AVPacket *pkt)
275{
276 unsigned char chunk_preamble[CHUNK_PREAMBLE_SIZE];
277 int chunk_type;
278 int chunk_size;
279 unsigned char opcode_preamble[OPCODE_PREAMBLE_SIZE];
280 unsigned char opcode_type;
281 unsigned char opcode_version;
282 int opcode_size;
283 unsigned char scratch[1024];
284 int i, j;
285 int first_color, last_color;
286 int audio_flags;
287 unsigned char r, g, b;
288 unsigned int width, height;
289
290 /* see if there are any pending packets */
291 chunk_type = load_ipmovie_packet(s, pb, pkt);
292 if (chunk_type != CHUNK_DONE)
293 return chunk_type;
294
295 /* read the next chunk, wherever the file happens to be pointing */
296 if (avio_feof(pb))
297 return CHUNK_EOF;
298 if (avio_read(pb, chunk_preamble, CHUNK_PREAMBLE_SIZE) !=
300 return CHUNK_BAD;
301 chunk_size = AV_RL16(&chunk_preamble[0]);
302 chunk_type = AV_RL16(&chunk_preamble[2]);
303
304 av_log(s->avf, AV_LOG_TRACE, "chunk type 0x%04X, 0x%04X bytes: ", chunk_type, chunk_size);
305
306 switch (chunk_type) {
307
308 case CHUNK_INIT_AUDIO:
309 av_log(s->avf, AV_LOG_TRACE, "initialize audio\n");
310 break;
311
312 case CHUNK_AUDIO_ONLY:
313 av_log(s->avf, AV_LOG_TRACE, "audio only\n");
314 break;
315
316 case CHUNK_INIT_VIDEO:
317 av_log(s->avf, AV_LOG_TRACE, "initialize video\n");
318 break;
319
320 case CHUNK_VIDEO:
321 av_log(s->avf, AV_LOG_TRACE, "video (and audio)\n");
322 break;
323
324 case CHUNK_SHUTDOWN:
325 av_log(s->avf, AV_LOG_TRACE, "shutdown\n");
326 break;
327
328 case CHUNK_END:
329 av_log(s->avf, AV_LOG_TRACE, "end\n");
330 break;
331
332 default:
333 av_log(s->avf, AV_LOG_TRACE, "invalid chunk\n");
334 chunk_type = CHUNK_BAD;
335 break;
336
337 }
338
339 while ((chunk_size > 0) && (chunk_type != CHUNK_BAD)) {
340
341 /* read the next chunk, wherever the file happens to be pointing */
342 if (avio_feof(pb)) {
343 chunk_type = CHUNK_EOF;
344 break;
345 }
346 if (avio_read(pb, opcode_preamble, CHUNK_PREAMBLE_SIZE) !=
348 chunk_type = CHUNK_BAD;
349 break;
350 }
351
352 opcode_size = AV_RL16(&opcode_preamble[0]);
353 opcode_type = opcode_preamble[2];
354 opcode_version = opcode_preamble[3];
355
356 chunk_size -= OPCODE_PREAMBLE_SIZE;
357 chunk_size -= opcode_size;
358 if (chunk_size < 0) {
359 av_log(s->avf, AV_LOG_TRACE, "chunk_size countdown just went negative\n");
360 chunk_type = CHUNK_BAD;
361 break;
362 }
363
364 av_log(s->avf, AV_LOG_TRACE, " opcode type %02X, version %d, 0x%04X bytes: ",
365 opcode_type, opcode_version, opcode_size);
366 switch (opcode_type) {
367
369 av_log(s->avf, AV_LOG_TRACE, "end of stream\n");
370 avio_skip(pb, opcode_size);
371 break;
372
374 av_log(s->avf, AV_LOG_TRACE, "end of chunk\n");
375 avio_skip(pb, opcode_size);
376 break;
377
379 av_log(s->avf, AV_LOG_TRACE, "create timer\n");
380 if ((opcode_version > 0) || (opcode_size != 6)) {
381 av_log(s->avf, AV_LOG_TRACE, "bad create_timer opcode\n");
382 chunk_type = CHUNK_BAD;
383 break;
384 }
385 if (avio_read(pb, scratch, opcode_size) !=
386 opcode_size) {
387 chunk_type = CHUNK_BAD;
388 break;
389 }
390 s->frame_pts_inc = ((uint64_t)AV_RL32(&scratch[0])) * AV_RL16(&scratch[4]);
391 break;
392
394 av_log(s->avf, AV_LOG_TRACE, "initialize audio buffers\n");
395 if (opcode_version > 1 || opcode_size > 10 || opcode_size < 6) {
396 av_log(s->avf, AV_LOG_TRACE, "bad init_audio_buffers opcode\n");
397 chunk_type = CHUNK_BAD;
398 break;
399 }
400 if (avio_read(pb, scratch, opcode_size) !=
401 opcode_size) {
402 chunk_type = CHUNK_BAD;
403 break;
404 }
405 s->audio_sample_rate = AV_RL16(&scratch[4]);
406 audio_flags = AV_RL16(&scratch[2]);
407 /* bit 0 of the flags: 0 = mono, 1 = stereo */
408 s->audio_channels = (audio_flags & 1) + 1;
409 /* bit 1 of the flags: 0 = 8 bit, 1 = 16 bit */
410 s->audio_bits = (((audio_flags >> 1) & 1) + 1) * 8;
411 /* bit 2 indicates compressed audio in version 1 opcode */
412 if ((opcode_version == 1) && (audio_flags & 0x4))
413 s->audio_type = AV_CODEC_ID_INTERPLAY_DPCM;
414 else if (s->audio_bits == 16)
415 s->audio_type = AV_CODEC_ID_PCM_S16LE;
416 else
417 s->audio_type = AV_CODEC_ID_PCM_U8;
418 av_log(s->avf, AV_LOG_TRACE, "audio: %d bits, %d Hz, %s, %s format\n",
419 s->audio_bits, s->audio_sample_rate,
420 (s->audio_channels == 2) ? "stereo" : "mono",
421 (s->audio_type == AV_CODEC_ID_INTERPLAY_DPCM) ?
422 "Interplay audio" : "PCM");
423 break;
424
426 av_log(s->avf, AV_LOG_TRACE, "start/stop audio\n");
427 avio_skip(pb, opcode_size);
428 break;
429
431 av_log(s->avf, AV_LOG_TRACE, "initialize video buffers\n");
432 if ((opcode_version > 2) || (opcode_size > 8) || opcode_size < 4
433 || opcode_version == 2 && opcode_size < 8
434 ) {
435 av_log(s->avf, AV_LOG_TRACE, "bad init_video_buffers opcode\n");
436 chunk_type = CHUNK_BAD;
437 break;
438 }
439 if (avio_read(pb, scratch, opcode_size) !=
440 opcode_size) {
441 chunk_type = CHUNK_BAD;
442 break;
443 }
444 width = AV_RL16(&scratch[0]) * 8;
445 height = AV_RL16(&scratch[2]) * 8;
446 if (width != s->video_width) {
447 s->video_width = width;
448 s->changed++;
449 }
450 if (height != s->video_height) {
451 s->video_height = height;
452 s->changed++;
453 }
454 if (opcode_version < 2 || !AV_RL16(&scratch[6])) {
455 s->video_bpp = 8;
456 } else {
457 s->video_bpp = 16;
458 }
459 av_log(s->avf, AV_LOG_TRACE, "video resolution: %d x %d\n",
460 s->video_width, s->video_height);
461 break;
462
467 av_log(s->avf, AV_LOG_TRACE, "unknown (but documented) opcode %02X\n", opcode_type);
468 avio_skip(pb, opcode_size);
469 break;
470
472 av_log(s->avf, AV_LOG_TRACE, "send buffer\n");
473 avio_skip(pb, opcode_size);
474 s->send_buffer = 1;
475 break;
476
478 av_log(s->avf, AV_LOG_TRACE, "audio frame\n");
479
480 /* log position and move on for now */
481 s->audio_chunk_offset = avio_tell(pb);
482 s->audio_chunk_size = opcode_size;
483 avio_skip(pb, opcode_size);
484 break;
485
487 av_log(s->avf, AV_LOG_TRACE, "silence frame\n");
488 avio_skip(pb, opcode_size);
489 break;
490
492 av_log(s->avf, AV_LOG_TRACE, "initialize video mode\n");
493 avio_skip(pb, opcode_size);
494 break;
495
497 av_log(s->avf, AV_LOG_TRACE, "create gradient\n");
498 avio_skip(pb, opcode_size);
499 break;
500
502 av_log(s->avf, AV_LOG_TRACE, "set palette\n");
503 /* check for the logical maximum palette size
504 * (3 * 256 + 4 bytes) */
505 if (opcode_size > 0x304 || opcode_size < 4) {
506 av_log(s->avf, AV_LOG_TRACE, "demux_ipmovie: set_palette opcode with invalid size\n");
507 chunk_type = CHUNK_BAD;
508 break;
509 }
510 if (avio_read(pb, scratch, opcode_size) != opcode_size) {
511 chunk_type = CHUNK_BAD;
512 break;
513 }
514
515 /* load the palette into internal data structure */
516 first_color = AV_RL16(&scratch[0]);
517 last_color = first_color + AV_RL16(&scratch[2]) - 1;
518 /* sanity check (since they are 16 bit values) */
519 if ( (first_color > 0xFF) || (last_color > 0xFF)
520 || (last_color - first_color + 1)*3 + 4 > opcode_size) {
521 av_log(s->avf, AV_LOG_TRACE, "demux_ipmovie: set_palette indexes out of range (%d -> %d)\n",
522 first_color, last_color);
523 chunk_type = CHUNK_BAD;
524 break;
525 }
526 j = 4; /* offset of first palette data */
527 for (i = first_color; i <= last_color; i++) {
528 /* the palette is stored as a 6-bit VGA palette, thus each
529 * component is shifted up to a 8-bit range */
530 r = scratch[j++] * 4;
531 g = scratch[j++] * 4;
532 b = scratch[j++] * 4;
533 s->palette[i] = (0xFFU << 24) | (r << 16) | (g << 8) | (b);
534 s->palette[i] |= s->palette[i] >> 6 & 0x30303;
535 }
536 s->has_palette = 1;
537 break;
538
540 av_log(s->avf, AV_LOG_TRACE, "set palette compressed\n");
541 avio_skip(pb, opcode_size);
542 break;
543
545 av_log(s->avf, AV_LOG_TRACE, "set skip map\n");
546
547 /* log position and move on for now */
548 s->skip_map_chunk_offset = avio_tell(pb);
549 s->skip_map_chunk_size = opcode_size;
550 avio_skip(pb, opcode_size);
551 break;
552
554 av_log(s->avf, AV_LOG_TRACE, "set decoding map\n");
555
556 /* log position and move on for now */
557 s->decode_map_chunk_offset = avio_tell(pb);
558 s->decode_map_chunk_size = opcode_size;
559 avio_skip(pb, opcode_size);
560 break;
561
565 s->frame_format = opcode_type;
566 av_log(s->avf, AV_LOG_TRACE, "set video data format 0x%02X\n",
567 opcode_type);
568
569 /* log position and move on for now */
570 s->video_chunk_offset = avio_tell(pb);
571 s->video_chunk_size = opcode_size;
572 avio_skip(pb, opcode_size);
573 break;
574
575 default:
576 av_log(s->avf, AV_LOG_TRACE, "*** unknown opcode type\n");
577 chunk_type = CHUNK_BAD;
578 break;
579
580 }
581 }
582
583 if (s->avf->nb_streams == 1 && s->audio_type)
584 init_audio(s->avf);
585
586 /* make a note of where the stream is sitting */
587 s->next_chunk_offset = avio_tell(pb);
588
589 return chunk_type;
590}
591
592static const char signature[] = "Interplay MVE File\x1A\0\x1A";
593
594static int ipmovie_probe(const AVProbeData *p)
595{
596 const uint8_t *b = p->buf;
597 const uint8_t *b_end = p->buf + p->buf_size - sizeof(signature);
598 do {
599 if (b[0] == signature[0] && memcmp(b, signature, sizeof(signature)) == 0)
600 return AVPROBE_SCORE_MAX;
601 b++;
602 } while (b < b_end);
603
604 return 0;
605}
606
608{
609 IPMVEContext *ipmovie = s->priv_data;
610 AVIOContext *pb = s->pb;
611 AVStream *st;
612 unsigned char chunk_preamble[CHUNK_PREAMBLE_SIZE];
613 int chunk_type, i;
614 uint8_t signature_buffer[sizeof(signature)];
615 int ret;
616
617 ipmovie->avf = s;
618
619 ret = ffio_read_size(pb, signature_buffer, sizeof(signature_buffer));
620 if (ret < 0)
621 return ret;
622 while (memcmp(signature_buffer, signature, sizeof(signature))) {
623 memmove(signature_buffer, signature_buffer + 1, sizeof(signature_buffer) - 1);
624 signature_buffer[sizeof(signature_buffer) - 1] = avio_r8(pb);
625 if (avio_feof(pb))
626 return AVERROR_EOF;
627 }
628
629 /* on the first read, this will position the stream at the first chunk */
630 ipmovie->next_chunk_offset = avio_tell(pb) + 4;
631
632 for (i = 0; i < 256; i++)
633 ipmovie->palette[i] = 0xFFU << 24;
634
635 /* process the first chunk which should be CHUNK_INIT_VIDEO */
636 if (process_ipmovie_chunk(ipmovie, pb, NULL) != CHUNK_INIT_VIDEO) {
637 return AVERROR_INVALIDDATA;
638 }
639
640 /* peek ahead to the next chunk-- if it is an init audio chunk, process
641 * it; if it is the first video chunk, this is a silent file */
642 if ((ret = ffio_read_size(pb, chunk_preamble, CHUNK_PREAMBLE_SIZE)) < 0)
643 return ret;
644 chunk_type = AV_RL16(&chunk_preamble[2]);
645 avio_seek(pb, -CHUNK_PREAMBLE_SIZE, SEEK_CUR);
646
647 if (chunk_type == CHUNK_VIDEO)
648 ipmovie->audio_type = AV_CODEC_ID_NONE; /* no audio */
649 else if (process_ipmovie_chunk(ipmovie, pb, ffformatcontext(s)->parse_pkt) != CHUNK_INIT_AUDIO) {
650 return AVERROR_INVALIDDATA;
651 }
652
653 /* initialize the stream decoders */
655 if (!st)
656 return AVERROR(ENOMEM);
657 avpriv_set_pts_info(st, 63, 1, 1000000);
658 ipmovie->video_stream_index = st->index;
661 st->codecpar->codec_tag = 0; /* no fourcc */
662 st->codecpar->width = ipmovie->video_width;
663 st->codecpar->height = ipmovie->video_height;
665
666 if (ipmovie->audio_type) {
667 return init_audio(s);
668 } else
669 s->ctx_flags |= AVFMTCTX_NOHEADER;
670
671 return 0;
672}
673
675 AVPacket *pkt)
676{
677 IPMVEContext *ipmovie = s->priv_data;
678 AVIOContext *pb = s->pb;
679 int ret;
680
681 for (;;) {
682 ret = process_ipmovie_chunk(ipmovie, pb, pkt);
683 /* dispatch the first of any pending packets */
684 if ((ret == CHUNK_VIDEO) || (ret == CHUNK_AUDIO_ONLY))
685 ret = load_ipmovie_packet(ipmovie, pb, pkt);
686
687 if (ret == CHUNK_BAD)
689 else if (ret == CHUNK_EOF)
691 else if (ret == CHUNK_NOMEM)
692 ret = AVERROR(ENOMEM);
693 else if (ret == CHUNK_END || ret == CHUNK_SHUTDOWN)
694 ret = AVERROR_EOF;
695 else if (ret == CHUNK_HAVE_PACKET)
696 ret = 0;
697 else if (ret == CHUNK_INIT_VIDEO || ret == CHUNK_INIT_AUDIO)
698 continue;
699 else
700 continue;
701
702 return ret;
703 }
704}
705
707 .p.name = "ipmovie",
708 .p.long_name = NULL_IF_CONFIG_SMALL("Interplay MVE"),
709 .priv_data_size = sizeof(IPMVEContext),
713};
const FFInputFormat ff_ipmovie_demuxer
Definition ipmovie.c:706
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition avformat.c:834
Main libavformat public API header.
#define AVPROBE_SCORE_MAX
maximum score
Definition avformat.h:483
#define AVFMTCTX_NOHEADER
signal that no header is present (streams are added dynamically)
Definition avformat.h:1284
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.
Definition utils.c:98
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition aviobuf.c:236
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition aviobuf.c:349
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition avio.h:494
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition aviobuf.c:321
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition aviobuf.c:615
int avio_r8(AVIOContext *s)
Definition aviobuf.c:606
int ffio_read_size(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition aviobuf.c:665
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
static int read_probe(const AVProbeData *p)
Definition cdg.c:30
Public libavutil channel layout APIs header.
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
int ff_add_param_change(AVPacket *pkt, int32_t channels, uint64_t channel_layout, int32_t sample_rate, int32_t width, int32_t height)
Add side data to a packet for changing parameters to the given values.
static AVPacket * pkt
static int read_header(FFV1Context *f, RangeCoder *c)
Definition ffv1dec.c:578
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition codec_id.h:47
@ AV_CODEC_ID_PCM_U8
Definition codec_id.h:335
@ AV_CODEC_ID_PCM_S16LE
Definition codec_id.h:330
@ AV_CODEC_ID_NONE
Definition codec_id.h:48
@ AV_CODEC_ID_INTERPLAY_DPCM
Definition codec_id.h:443
@ AV_CODEC_ID_INTERPLAY_VIDEO
Definition codec_id.h:89
@ AV_PKT_DATA_PALETTE
An AV_PKT_DATA_PALETTE side data packet contains exactly AVPALETTE_SIZE bytes worth of palette.
Definition packet.h:47
uint8_t * av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type, size_t size)
Allocate new information of a packet.
Definition packet.c:231
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition packet.c:98
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
void av_channel_layout_default(AVChannelLayout *ch_layout, int nb_channels)
Get the default channel layout for a given number of channels.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR_EOF
End of file.
Definition error.h:57
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition log.h:236
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define r
Definition input.c:42
#define b
Definition input.c:43
#define AV_WL8(p, d)
#define AV_RL32(p)
#define AV_RL16(p)
#define AV_WL16(p, v)
#define CHUNK_DONE
Definition ipmovie.c:53
#define CHUNK_BAD
Definition ipmovie.c:56
#define OPCODE_INIT_VIDEO_BUFFERS
Definition ipmovie.c:63
#define OPCODE_UNKNOWN_12
Definition ipmovie.c:76
#define CHUNK_SHUTDOWN
Definition ipmovie.c:49
#define OPCODE_SILENCE_FRAME
Definition ipmovie.c:67
#define OPCODE_SET_SKIP_MAP
Definition ipmovie.c:72
#define OPCODE_INIT_VIDEO_MODE
Definition ipmovie.c:68
#define OPCODE_INIT_AUDIO_BUFFERS
Definition ipmovie.c:61
#define OPCODE_VIDEO_DATA_11
Definition ipmovie.c:75
#define OPCODE_VIDEO_DATA_06
Definition ipmovie.c:64
#define CHUNK_INIT_AUDIO
Definition ipmovie.c:45
#define CHUNK_INIT_VIDEO
Definition ipmovie.c:47
#define OPCODE_SEND_BUFFER
Definition ipmovie.c:65
#define OPCODE_SET_PALETTE
Definition ipmovie.c:70
#define CHUNK_NOMEM
Definition ipmovie.c:54
static int init_audio(AVFormatContext *s)
Definition ipmovie.c:248
#define OPCODE_PREAMBLE_SIZE
Definition ipmovie.c:43
static const char signature[]
Definition ipmovie.c:592
#define OPCODE_CREATE_GRADIENT
Definition ipmovie.c:69
#define OPCODE_END_OF_STREAM
Definition ipmovie.c:58
#define OPCODE_SET_DECODING_MAP
Definition ipmovie.c:73
#define OPCODE_SET_PALETTE_COMPRESSED
Definition ipmovie.c:71
#define CHUNK_PREAMBLE_SIZE
Definition ipmovie.c:42
#define OPCODE_START_STOP_AUDIO
Definition ipmovie.c:62
#define OPCODE_UNKNOWN_14
Definition ipmovie.c:78
#define OPCODE_AUDIO_FRAME
Definition ipmovie.c:66
static int ipmovie_read_header(AVFormatContext *s)
Definition ipmovie.c:607
#define OPCODE_UNKNOWN_15
Definition ipmovie.c:79
static int ipmovie_probe(const AVProbeData *p)
Definition ipmovie.c:594
#define OPCODE_UNKNOWN_13
Definition ipmovie.c:77
#define CHUNK_HAVE_PACKET
Definition ipmovie.c:52
#define OPCODE_END_OF_CHUNK
Definition ipmovie.c:59
#define CHUNK_VIDEO
Definition ipmovie.c:48
#define CHUNK_END
Definition ipmovie.c:50
#define CHUNK_AUDIO_ONLY
Definition ipmovie.c:46
static int ipmovie_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition ipmovie.c:674
#define CHUNK_EOF
Definition ipmovie.c:55
#define OPCODE_CREATE_TIMER
Definition ipmovie.c:60
static int load_ipmovie_packet(IPMVEContext *s, AVIOContext *pb, AVPacket *pkt)
Definition ipmovie.c:122
#define OPCODE_VIDEO_DATA_10
Definition ipmovie.c:74
static int process_ipmovie_chunk(IPMVEContext *s, AVIOContext *pb, AVPacket *pkt)
Definition ipmovie.c:273
static av_always_inline FFFormatContext * ffformatcontext(AVFormatContext *s)
Definition internal.h:130
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
#define AVPALETTE_SIZE
Definition pixfmt.h:32
int height
The height of the video frame in pixels.
Definition codec_par.h:150
int bits_per_coded_sample
The number of bits per sample in the codedwords.
Definition codec_par.h:113
AVChannelLayout ch_layout
The channel layout and number of channels.
Definition codec_par.h:207
int width
The width of the video frame in pixels.
Definition codec_par.h:143
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition codec_par.h:99
enum AVMediaType codec_type
General type of the encoded data.
Definition codec_par.h:53
int block_align
The number of bytes per coded audio frame, required by some formats.
Definition codec_par.h:221
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition codec_par.h:61
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition codec_par.h:57
int sample_rate
The number of audio samples per second.
Definition codec_par.h:213
Format I/O context.
Definition avformat.h:1333
Bytestream IO Context.
Definition avio.h:160
This structure stores compressed data.
Definition packet.h:580
This structure contains the data a format has to probe a file.
Definition avformat.h:471
Stream structure.
Definition avformat.h:766
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:789
int index
stream index in AVFormatContext
Definition avformat.h:772
unsigned char * buf
Definition ipmovie.c:85
int64_t audio_chunk_offset
Definition ipmovie.c:109
unsigned int audio_bits
Definition ipmovie.c:100
int audio_chunk_size
Definition ipmovie.c:110
unsigned int audio_sample_rate
Definition ipmovie.c:102
unsigned int audio_channels
Definition ipmovie.c:101
int64_t video_pts
Definition ipmovie.c:93
uint64_t frame_pts_inc
Definition ipmovie.c:88
uint8_t send_buffer
Definition ipmovie.c:97
int64_t video_chunk_offset
Definition ipmovie.c:111
unsigned int video_height
Definition ipmovie.c:92
int video_chunk_size
Definition ipmovie.c:112
int decode_map_chunk_size
Definition ipmovie.c:116
int skip_map_chunk_size
Definition ipmovie.c:114
unsigned int video_width
Definition ipmovie.c:91
int audio_stream_index
Definition ipmovie.c:107
uint8_t frame_format
Definition ipmovie.c:98
AVFormatContext * avf
Definition ipmovie.c:84
int64_t decode_map_chunk_offset
Definition ipmovie.c:115
int buf_size
Definition ipmovie.c:86
int64_t skip_map_chunk_offset
Definition ipmovie.c:113
int64_t next_chunk_offset
Definition ipmovie.c:118
int changed
Definition ipmovie.c:96
int has_palette
Definition ipmovie.c:95
uint32_t palette[256]
Definition ipmovie.c:94
unsigned int video_bpp
Definition ipmovie.c:90
enum AVCodecID audio_type
Definition ipmovie.c:103
unsigned int audio_frame_count
Definition ipmovie.c:104
int video_stream_index
Definition ipmovie.c:106
#define av_log(a,...)
#define height
Definition dsp.h:89
#define width
Definition dsp.h:89
const char * g
Definition vf_curves.c:128