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