FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavformat
smjpegdec.c
Go to the documentation of this file.
1
/*
2
* SMJPEG demuxer
3
* Copyright (c) 2011 Paul B Mahol
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
* 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
#include "
smjpeg.h
"
31
32
typedef
struct
SMJPEGContext
{
33
int
audio_stream_index
;
34
int
video_stream_index
;
35
}
SMJPEGContext
;
36
37
static
int
smjpeg_probe
(
AVProbeData
*p)
38
{
39
if
(!memcmp(p->
buf
,
SMJPEG_MAGIC
, 8))
40
return
AVPROBE_SCORE_MAX
;
41
return
0;
42
}
43
44
static
int
smjpeg_read_header
(
AVFormatContext
*
s
)
45
{
46
SMJPEGContext
*sc = s->
priv_data
;
47
AVStream
*ast = NULL, *vst = NULL;
48
AVIOContext
*pb = s->
pb
;
49
uint32_t
version
, htype, hlength,
duration
;
50
char
*comment;
51
52
avio_skip
(pb, 8);
// magic
53
version =
avio_rb32
(pb);
54
if
(version)
55
avpriv_request_sample
(s,
"Unknown version %d"
, version);
56
57
duration =
avio_rb32
(pb);
// in msec
58
59
while
(!
url_feof
(pb)) {
60
htype =
avio_rl32
(pb);
61
switch
(htype) {
62
case
SMJPEG_TXT
:
63
hlength =
avio_rb32
(pb);
64
if
(!hlength || hlength > 512)
65
return
AVERROR_INVALIDDATA
;
66
comment =
av_malloc
(hlength + 1);
67
if
(!comment)
68
return
AVERROR
(ENOMEM);
69
if
(
avio_read
(pb, comment, hlength) != hlength) {
70
av_freep
(&comment);
71
av_log
(s,
AV_LOG_ERROR
,
"error when reading comment\n"
);
72
return
AVERROR_INVALIDDATA
;
73
}
74
comment[hlength] = 0;
75
av_dict_set
(&s->
metadata
,
"comment"
, comment,
76
AV_DICT_DONT_STRDUP_VAL
);
77
break
;
78
case
SMJPEG_SND
:
79
if
(ast) {
80
avpriv_request_sample
(s,
"Multiple audio streams"
);
81
return
AVERROR_PATCHWELCOME
;
82
}
83
hlength =
avio_rb32
(pb);
84
if
(hlength < 8)
85
return
AVERROR_INVALIDDATA
;
86
ast =
avformat_new_stream
(s, 0);
87
if
(!ast)
88
return
AVERROR
(ENOMEM);
89
ast->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
90
ast->
codec
->
sample_rate
=
avio_rb16
(pb);
91
ast->
codec
->
bits_per_coded_sample
=
avio_r8
(pb);
92
ast->
codec
->
channels
=
avio_r8
(pb);
93
ast->
codec
->
codec_tag
=
avio_rl32
(pb);
94
ast->
codec
->
codec_id
=
ff_codec_get_id
(
ff_codec_smjpeg_audio_tags
,
95
ast->
codec
->
codec_tag
);
96
ast->
duration
=
duration
;
97
sc->
audio_stream_index
= ast->
index
;
98
avpriv_set_pts_info
(ast, 32, 1, 1000);
99
avio_skip
(pb, hlength - 8);
100
break
;
101
case
SMJPEG_VID
:
102
if
(vst) {
103
avpriv_request_sample
(s,
"Multiple video streams"
);
104
return
AVERROR_INVALIDDATA
;
105
}
106
hlength =
avio_rb32
(pb);
107
if
(hlength < 12)
108
return
AVERROR_INVALIDDATA
;
109
vst =
avformat_new_stream
(s, 0);
110
if
(!vst)
111
return
AVERROR
(ENOMEM);
112
vst->nb_frames =
avio_rb32
(pb);
113
vst->codec->codec_type =
AVMEDIA_TYPE_VIDEO
;
114
vst->codec->width =
avio_rb16
(pb);
115
vst->codec->height =
avio_rb16
(pb);
116
vst->codec->codec_tag =
avio_rl32
(pb);
117
vst->codec->codec_id =
ff_codec_get_id
(
ff_codec_smjpeg_video_tags
,
118
vst->codec->codec_tag);
119
vst->duration =
duration
;
120
sc->
video_stream_index
= vst->index;
121
avpriv_set_pts_info
(vst, 32, 1, 1000);
122
avio_skip
(pb, hlength - 12);
123
break
;
124
case
SMJPEG_HEND
:
125
return
0;
126
default
:
127
av_log
(s,
AV_LOG_ERROR
,
"unknown header %x\n"
, htype);
128
return
AVERROR_INVALIDDATA
;
129
}
130
}
131
132
return
AVERROR_EOF
;
133
}
134
135
static
int
smjpeg_read_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
136
{
137
SMJPEGContext
*sc = s->
priv_data
;
138
uint32_t dtype,
size
, timestamp;
139
int64_t pos;
140
int
ret
;
141
142
if
(
url_feof
(s->
pb
))
143
return
AVERROR_EOF
;
144
pos =
avio_tell
(s->
pb
);
145
dtype =
avio_rl32
(s->
pb
);
146
switch
(dtype) {
147
case
SMJPEG_SNDD
:
148
timestamp =
avio_rb32
(s->
pb
);
149
size =
avio_rb32
(s->
pb
);
150
ret =
av_get_packet
(s->
pb
, pkt, size);
151
pkt->
stream_index
= sc->
audio_stream_index
;
152
pkt->
pts
= timestamp;
153
pkt->
pos
= pos;
154
break
;
155
case
SMJPEG_VIDD
:
156
timestamp =
avio_rb32
(s->
pb
);
157
size =
avio_rb32
(s->
pb
);
158
ret =
av_get_packet
(s->
pb
, pkt, size);
159
pkt->
stream_index
= sc->
video_stream_index
;
160
pkt->
pts
= timestamp;
161
pkt->
pos
= pos;
162
break
;
163
case
SMJPEG_DONE
:
164
ret =
AVERROR_EOF
;
165
break
;
166
default
:
167
av_log
(s,
AV_LOG_ERROR
,
"unknown chunk %x\n"
, dtype);
168
ret =
AVERROR_INVALIDDATA
;
169
break
;
170
}
171
return
ret
;
172
}
173
174
AVInputFormat
ff_smjpeg_demuxer
= {
175
.
name
=
"smjpeg"
,
176
.long_name =
NULL_IF_CONFIG_SMALL
(
"Loki SDL MJPEG"
),
177
.priv_data_size =
sizeof
(
SMJPEGContext
),
178
.
read_probe
=
smjpeg_probe
,
179
.
read_header
=
smjpeg_read_header
,
180
.
read_packet
=
smjpeg_read_packet
,
181
.extensions =
"mjpg"
,
182
.
flags
=
AVFMT_GENERIC_INDEX
,
183
};
Generated on Sun Mar 23 2014 23:50:13 for FFmpeg by
1.8.2