Browse Source

Merge commit 'eeadcdfd1a6f3089b6bf6e194d6ece8d3f113123'

* commit 'eeadcdfd1a6f3089b6bf6e194d6ece8d3f113123':
  LucasArts SMUSH demuxer

Conflicts:
	Changelog
	doc/general.texi
	libavformat/smush.c
	libavformat/version.h

See: bef8fd7099
Merged-by: Michael Niedermayer <michaelni@gmx.at>
tags/n2.3
Michael Niedermayer 11 years ago
parent
commit
5297003aa7
4 changed files with 35 additions and 20 deletions
  1. +1
    -0
      Changelog
  2. +32
    -18
      libavformat/smush.c
  3. +1
    -1
      libavformat/version.h
  4. +1
    -1
      tests/ref/fate/sanm

+ 1
- 0
Changelog View File

@@ -279,6 +279,7 @@ version 1.0:
- showwaves and showspectrum filter - showwaves and showspectrum filter
- LucasArts SMUSH SANM playback support - LucasArts SMUSH SANM playback support
- LucasArts SMUSH VIMA audio decoder (ADPCM) - LucasArts SMUSH VIMA audio decoder (ADPCM)
- LucasArts SMUSH demuxer
- SAMI, RealText and SubViewer demuxers and decoders - SAMI, RealText and SubViewer demuxers and decoders
- Heart Of Darkness PAF playback support - Heart Of Darkness PAF playback support
- iec61883 device - iec61883 device


+ 32
- 18
libavformat/smush.c View File

@@ -20,11 +20,12 @@
*/ */


#include "libavutil/intreadwrite.h" #include "libavutil/intreadwrite.h"

#include "avformat.h" #include "avformat.h"
#include "internal.h"
#include "avio.h" #include "avio.h"
#include "internal.h"


typedef struct {
typedef struct SMUSHContext {
int version; int version;
int audio_stream_index; int audio_stream_index;
int video_stream_index; int video_stream_index;
@@ -32,9 +33,9 @@ typedef struct {


static int smush_read_probe(AVProbeData *p) static int smush_read_probe(AVProbeData *p)
{ {
if (((AV_RL32(p->buf) == MKTAG('S', 'A', 'N', 'M') &&
if (((AV_RL32(p->buf) == MKTAG('S', 'A', 'N', 'M') &&
AV_RL32(p->buf + 8) == MKTAG('S', 'H', 'D', 'R')) || AV_RL32(p->buf + 8) == MKTAG('S', 'H', 'D', 'R')) ||
(AV_RL32(p->buf) == MKTAG('A', 'N', 'I', 'M') &&
(AV_RL32(p->buf) == MKTAG('A', 'N', 'I', 'M') &&
AV_RL32(p->buf + 8) == MKTAG('A', 'H', 'D', 'R')))) { AV_RL32(p->buf + 8) == MKTAG('A', 'H', 'D', 'R')))) {
return AVPROBE_SCORE_MAX; return AVPROBE_SCORE_MAX;
} }
@@ -65,6 +66,8 @@ static int smush_read_header(AVFormatContext *ctx)
smush->version = 0; smush->version = 0;
subversion = avio_rl16(pb); subversion = avio_rl16(pb);
nframes = avio_rl16(pb); nframes = avio_rl16(pb);
if (!nframes)
return AVERROR_INVALIDDATA;


avio_skip(pb, 2); // skip pad avio_skip(pb, 2); // skip pad


@@ -72,7 +75,7 @@ static int smush_read_header(AVFormatContext *ctx)
palette[i] = avio_rb24(pb); palette[i] = avio_rb24(pb);


avio_skip(pb, size - (3 * 256 + 6)); avio_skip(pb, size - (3 * 256 + 6));
} else if (magic == MKBETAG('S', 'A', 'N', 'M') ) {
} else if (magic == MKBETAG('S', 'A', 'N', 'M')) {
if (avio_rb32(pb) != MKBETAG('S', 'H', 'D', 'R')) if (avio_rb32(pb) != MKBETAG('S', 'H', 'D', 'R'))
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;


@@ -81,8 +84,11 @@ static int smush_read_header(AVFormatContext *ctx)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;


smush->version = 1; smush->version = 1;
subversion = avio_rl16(pb);
subversion = avio_rl16(pb);
nframes = avio_rl32(pb); nframes = avio_rl32(pb);
if (!nframes)
return AVERROR_INVALIDDATA;

avio_skip(pb, 2); // skip pad avio_skip(pb, 2); // skip pad
width = avio_rl16(pb); width = avio_rl16(pb);
height = avio_rl16(pb); height = avio_rl16(pb);
@@ -101,12 +107,18 @@ static int smush_read_header(AVFormatContext *ctx)


sig = avio_rb32(pb); sig = avio_rb32(pb);
chunk_size = avio_rb32(pb); chunk_size = avio_rb32(pb);
read += 8;
read += 8;
switch (sig) { switch (sig) {
case MKBETAG('W', 'a', 'v', 'e'): case MKBETAG('W', 'a', 'v', 'e'):
got_audio = 1; got_audio = 1;
sample_rate = avio_rl32(pb); sample_rate = avio_rl32(pb);
channels = avio_rl32(pb);
if (!sample_rate)
return AVERROR_INVALIDDATA;

channels = avio_rl32(pb);
if (!channels)
return AVERROR_INVALIDDATA;

avio_skip(pb, chunk_size - 8); avio_skip(pb, chunk_size - 8);
read += chunk_size; read += chunk_size;
break; break;
@@ -133,17 +145,18 @@ static int smush_read_header(AVFormatContext *ctx)


smush->video_stream_index = vst->index; smush->video_stream_index = vst->index;


avpriv_set_pts_info(vst, 64, 1, 15);

vst->start_time = 0; vst->start_time = 0;
vst->duration = vst->duration =
vst->nb_frames = nframes; vst->nb_frames = nframes;
vst->avg_frame_rate = av_inv_q(vst->time_base);
vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
vst->codec->codec_id = AV_CODEC_ID_SANM; vst->codec->codec_id = AV_CODEC_ID_SANM;
vst->codec->codec_tag = 0; vst->codec->codec_tag = 0;
vst->codec->width = width; vst->codec->width = width;
vst->codec->height = height; vst->codec->height = height;


avpriv_set_pts_info(vst, 64, 66667, 1000000);

if (!smush->version) { if (!smush->version) {
if (ff_alloc_extradata(vst->codec, 1024 + 2)) if (ff_alloc_extradata(vst->codec, 1024 + 2))
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
@@ -162,7 +175,7 @@ static int smush_read_header(AVFormatContext *ctx)


ast->start_time = 0; ast->start_time = 0;
ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
ast->codec->codec_id = AV_CODEC_ID_VIMA;
ast->codec->codec_id = AV_CODEC_ID_ADPCM_VIMA;
ast->codec->codec_tag = 0; ast->codec->codec_tag = 0;
ast->codec->sample_rate = sample_rate; ast->codec->sample_rate = sample_rate;
ast->codec->channels = channels; ast->codec->channels = channels;
@@ -178,6 +191,7 @@ static int smush_read_packet(AVFormatContext *ctx, AVPacket *pkt)
SMUSHContext *smush = ctx->priv_data; SMUSHContext *smush = ctx->priv_data;
AVIOContext *pb = ctx->pb; AVIOContext *pb = ctx->pb;
int done = 0; int done = 0;
int ret;


while (!done) { while (!done) {
uint32_t sig, size; uint32_t sig, size;
@@ -185,22 +199,22 @@ static int smush_read_packet(AVFormatContext *ctx, AVPacket *pkt)
if (url_feof(pb)) if (url_feof(pb))
return AVERROR_EOF; return AVERROR_EOF;


sig = avio_rb32(pb);
size = avio_rb32(pb);
sig = avio_rb32(pb);
size = avio_rb32(pb);


switch (sig) { switch (sig) {
case MKBETAG('F', 'R', 'M', 'E'): case MKBETAG('F', 'R', 'M', 'E'):
if (smush->version) if (smush->version)
break; break;
if (av_get_packet(pb, pkt, size) < 0)
return AVERROR(EIO);
if ((ret = av_get_packet(pb, pkt, size)) < 0)
return ret;


pkt->stream_index = smush->video_stream_index; pkt->stream_index = smush->video_stream_index;
done = 1; done = 1;
break; break;
case MKBETAG('B', 'l', '1', '6'): case MKBETAG('B', 'l', '1', '6'):
if (av_get_packet(pb, pkt, size) < 0)
return AVERROR(EIO);
if ((ret = av_get_packet(pb, pkt, size)) < 0)
return ret;


pkt->stream_index = smush->video_stream_index; pkt->stream_index = smush->video_stream_index;
pkt->duration = 1; pkt->duration = 1;
@@ -214,7 +228,7 @@ static int smush_read_packet(AVFormatContext *ctx, AVPacket *pkt)


pkt->stream_index = smush->audio_stream_index; pkt->stream_index = smush->audio_stream_index;
pkt->flags |= AV_PKT_FLAG_KEY; pkt->flags |= AV_PKT_FLAG_KEY;
pkt->duration = AV_RB32(pkt->data);
pkt->duration = AV_RB32(pkt->data);
if (pkt->duration == 0xFFFFFFFFu) if (pkt->duration == 0xFFFFFFFFu)
pkt->duration = AV_RB32(pkt->data + 8); pkt->duration = AV_RB32(pkt->data + 8);
done = 1; done = 1;


+ 1
- 1
libavformat/version.h View File

@@ -31,7 +31,7 @@


#define LIBAVFORMAT_VERSION_MAJOR 55 #define LIBAVFORMAT_VERSION_MAJOR 55
#define LIBAVFORMAT_VERSION_MINOR 36 #define LIBAVFORMAT_VERSION_MINOR 36
#define LIBAVFORMAT_VERSION_MICRO 101
#define LIBAVFORMAT_VERSION_MICRO 102


#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
LIBAVFORMAT_VERSION_MINOR, \ LIBAVFORMAT_VERSION_MINOR, \


+ 1
- 1
tests/ref/fate/sanm View File

@@ -1,4 +1,4 @@
#tb 0: 66667/1000000
#tb 0: 1/15
0, 0, 0, 1, 921600, 0x00000000 0, 0, 0, 1, 921600, 0x00000000
0, 1, 1, 1, 921600, 0x00000000 0, 1, 1, 1, 921600, 0x00000000
0, 2, 2, 1, 921600, 0x00000000 0, 2, 2, 1, 921600, 0x00000000


Loading…
Cancel
Save