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
(!
avio_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
(
avio_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 Mar 8 2015 02:35:12 for FFmpeg by
1.8.2