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