~medibuntu-maintainers/mplayer/medibuntu.precise

« back to all changes in this revision

Viewing changes to ffmpeg/libavformat/smjpeg.c

  • Committer: Package Import Robot
  • Author(s): Reinhard Tartler
  • Date: 2012-01-12 22:23:28 UTC
  • mfrom: (0.4.7 sid)
  • mto: This revision was merged to the branch mainline in revision 76.
  • Revision ID: package-import@ubuntu.com-20120112222328-8jqdyodym3p84ygu
Tags: 2:1.0~rc4.dfsg1+svn34540-1
* New upstream snapshot
* upload to unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * SMJPEG demuxer
 
3
 * Copyright (c) 2011 Paul B Mahol
 
4
 *
 
5
 * This file is part of Libav.
 
6
 *
 
7
 * Libav 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
 * Libav 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 Libav; 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
 * This is a demuxer for Loki SDL Motion JPEG files
 
25
 */
 
26
 
 
27
#include "avformat.h"
 
28
#include "internal.h"
 
29
#include "riff.h"
 
30
 
 
31
static const AVCodecTag codec_smjpeg_video_tags[] = {
 
32
    { CODEC_ID_MJPEG,             MKTAG('J', 'F', 'I', 'F') },
 
33
    { CODEC_ID_NONE, 0 },
 
34
};
 
35
 
 
36
static const AVCodecTag codec_smjpeg_audio_tags[] = {
 
37
    { CODEC_ID_ADPCM_IMA_SMJPEG,  MKTAG('A', 'P', 'C', 'M') },
 
38
    { CODEC_ID_PCM_S16LE,         MKTAG('N', 'O', 'N', 'E') },
 
39
    { CODEC_ID_NONE, 0 },
 
40
};
 
41
 
 
42
typedef struct SMJPEGContext {
 
43
    int audio_stream_index;
 
44
    int video_stream_index;
 
45
} SMJPEGContext;
 
46
 
 
47
static int smjpeg_probe(AVProbeData *p)
 
48
{
 
49
    if (!memcmp(p->buf, "\x0\xaSMJPEG", 8))
 
50
        return AVPROBE_SCORE_MAX;
 
51
    return 0;
 
52
}
 
53
 
 
54
static int smjpeg_read_header(AVFormatContext *s, AVFormatParameters *ap)
 
55
{
 
56
    SMJPEGContext *sc = s->priv_data;
 
57
    AVStream *ast = NULL, *vst = NULL;
 
58
    AVIOContext *pb = s->pb;
 
59
    uint32_t version, htype, hlength, duration;
 
60
    char *comment;
 
61
 
 
62
    avio_skip(pb, 8); // magic
 
63
    version = avio_rb32(pb);
 
64
    if (version)
 
65
        av_log_ask_for_sample(s, "unknown version %d\n", version);
 
66
 
 
67
    duration = avio_rb32(pb); // in msec
 
68
 
 
69
    while (!pb->eof_reached) {
 
70
        htype = avio_rl32(pb);
 
71
        switch (htype) {
 
72
        case MKTAG('_', 'T', 'X', 'T'):
 
73
            hlength = avio_rb32(pb);
 
74
            if (!hlength || hlength > 512)
 
75
                return AVERROR_INVALIDDATA;
 
76
            comment = av_malloc(hlength + 1);
 
77
            if (!comment)
 
78
                return AVERROR(ENOMEM);
 
79
            if (avio_read(pb, comment, hlength) != hlength) {
 
80
                av_freep(&comment);
 
81
                av_log(s, AV_LOG_ERROR, "error when reading comment\n");
 
82
                return AVERROR_INVALIDDATA;
 
83
            }
 
84
            comment[hlength] = 0;
 
85
            av_dict_set(&s->metadata, "comment", comment,
 
86
                        AV_DICT_DONT_STRDUP_VAL);
 
87
            break;
 
88
        case MKTAG('_', 'S', 'N', 'D'):
 
89
            if (ast) {
 
90
                av_log_ask_for_sample(s, "multiple audio streams not supported\n");
 
91
                return AVERROR_INVALIDDATA;
 
92
            }
 
93
            hlength = avio_rb32(pb);
 
94
            if (hlength < 8)
 
95
                return AVERROR_INVALIDDATA;
 
96
            ast = avformat_new_stream(s, 0);
 
97
            if (!ast)
 
98
                return AVERROR(ENOMEM);
 
99
            ast->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
 
100
            ast->codec->sample_rate = avio_rb16(pb);
 
101
            ast->codec->bits_per_coded_sample = avio_r8(pb);
 
102
            ast->codec->channels    = avio_r8(pb);
 
103
            ast->codec->codec_tag   = avio_rl32(pb);
 
104
            ast->codec->codec_id    = ff_codec_get_id(codec_smjpeg_audio_tags,
 
105
                                                      ast->codec->codec_tag);
 
106
            ast->duration           = duration;
 
107
            sc->audio_stream_index  = ast->index;
 
108
            avpriv_set_pts_info(ast, 32, 1, 1000);
 
109
            avio_skip(pb, hlength - 8);
 
110
            break;
 
111
        case MKTAG('_', 'V', 'I', 'D'):
 
112
            if (vst) {
 
113
                av_log_ask_for_sample(s, "multiple video streams not supported\n");
 
114
                return AVERROR_INVALIDDATA;
 
115
            }
 
116
            hlength = avio_rb32(pb);
 
117
            if (hlength < 12)
 
118
                return AVERROR_INVALIDDATA;
 
119
            avio_skip(pb, 4); // number of frames
 
120
            vst = avformat_new_stream(s, 0);
 
121
            if (!vst)
 
122
                return AVERROR(ENOMEM);
 
123
            vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
 
124
            vst->codec->width      = avio_rb16(pb);
 
125
            vst->codec->height     = avio_rb16(pb);
 
126
            vst->codec->codec_tag  = avio_rl32(pb);
 
127
            vst->codec->codec_id   = ff_codec_get_id(codec_smjpeg_video_tags,
 
128
                                                     vst->codec->codec_tag);
 
129
            vst->duration          = duration;
 
130
            sc->video_stream_index = vst->index;
 
131
            avpriv_set_pts_info(vst, 32, 1, 1000);
 
132
            avio_skip(pb, hlength - 12);
 
133
            break;
 
134
        case MKTAG('H', 'E', 'N', 'D'):
 
135
            return 0;
 
136
        default:
 
137
            av_log(s, AV_LOG_ERROR, "unknown header %x\n", htype);
 
138
            return AVERROR_INVALIDDATA;
 
139
        }
 
140
    }
 
141
 
 
142
    return AVERROR_EOF;
 
143
}
 
144
 
 
145
static int smjpeg_read_packet(AVFormatContext *s, AVPacket *pkt)
 
146
{
 
147
    SMJPEGContext *sc = s->priv_data;
 
148
    uint32_t dtype, ret, size, timestamp;
 
149
 
 
150
    if (s->pb->eof_reached)
 
151
        return AVERROR_EOF;
 
152
    dtype = avio_rl32(s->pb);
 
153
    switch (dtype) {
 
154
    case MKTAG('s', 'n', 'd', 'D'):
 
155
        timestamp = avio_rb32(s->pb);
 
156
        size = avio_rb32(s->pb);
 
157
        ret = av_get_packet(s->pb, pkt, size);
 
158
        pkt->stream_index = sc->audio_stream_index;
 
159
        pkt->pts = timestamp;
 
160
        break;
 
161
    case MKTAG('v', 'i', 'd', 'D'):
 
162
        timestamp = avio_rb32(s->pb);
 
163
        size = avio_rb32(s->pb);
 
164
        ret = av_get_packet(s->pb, pkt, size);
 
165
        pkt->stream_index = sc->video_stream_index;
 
166
        pkt->pts = timestamp;
 
167
        break;
 
168
    case MKTAG('D', 'O', 'N', 'E'):
 
169
        ret = AVERROR_EOF;
 
170
        break;
 
171
    default:
 
172
        av_log(s, AV_LOG_ERROR, "unknown chunk %x\n", dtype);
 
173
        ret = AVERROR_INVALIDDATA;
 
174
        break;
 
175
    }
 
176
    return ret;
 
177
}
 
178
 
 
179
AVInputFormat ff_smjpeg_demuxer = {
 
180
    .name           = "smjpeg",
 
181
    .long_name      = NULL_IF_CONFIG_SMALL("Loki SDL MJPEG"),
 
182
    .priv_data_size = sizeof(SMJPEGContext),
 
183
    .read_probe     = smjpeg_probe,
 
184
    .read_header    = smjpeg_read_header,
 
185
    .read_packet    = smjpeg_read_packet,
 
186
    .extensions     = "mjpg",
 
187
};