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
img2enc.c
Go to the documentation of this file.
1
/*
2
* Image format
3
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
4
* Copyright (c) 2004 Michael Niedermayer
5
*
6
* This file is part of FFmpeg.
7
*
8
* FFmpeg is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU Lesser General Public
10
* License as published by the Free Software Foundation; either
11
* version 2.1 of the License, or (at your option) any later version.
12
*
13
* FFmpeg is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
* Lesser General Public License for more details.
17
*
18
* You should have received a copy of the GNU Lesser General Public
19
* License along with FFmpeg; if not, write to the Free Software
20
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
*/
22
23
#include "
libavutil/intreadwrite.h
"
24
#include "
libavutil/avassert.h
"
25
#include "
libavutil/avstring.h
"
26
#include "
libavutil/log.h
"
27
#include "
libavutil/opt.h
"
28
#include "
libavutil/pixdesc.h
"
29
#include "
libavutil/time_internal.h
"
30
#include "
avformat.h
"
31
#include "
avio_internal.h
"
32
#include "
internal.h
"
33
34
typedef
struct
{
35
const
AVClass
*
class
;
/**< Class for private options. */
36
int
img_number
;
37
int
is_pipe
;
38
int
split_planes
;
/**< use independent file for each Y, U, V plane */
39
char
path[1024];
40
int
update
;
41
int
use_strftime
;
42
const
char
*
muxer
;
43
}
VideoMuxData
;
44
45
static
int
write_header
(
AVFormatContext
*
s
)
46
{
47
VideoMuxData
*
img
= s->
priv_data
;
48
AVStream
*st = s->
streams
[0];
49
const
AVPixFmtDescriptor
*desc =
av_pix_fmt_desc_get
(st->
codec
->
pix_fmt
);
50
51
av_strlcpy
(img->
path
, s->
filename
,
sizeof
(img->
path
));
52
53
/* find format */
54
if
(s->
oformat
->
flags
&
AVFMT_NOFILE
)
55
img->
is_pipe
= 0;
56
else
57
img->
is_pipe
= 1;
58
59
if
(st->
codec
->
codec_id
==
AV_CODEC_ID_GIF
) {
60
img->
muxer
=
"gif"
;
61
}
else
if
(st->
codec
->
codec_id
==
AV_CODEC_ID_RAWVIDEO
) {
62
const
char
*str = strrchr(img->
path
,
'.'
);
63
img->
split_planes
= str
64
&& !
av_strcasecmp
(str + 1,
"y"
)
65
&& s->
nb_streams
== 1
66
&& desc
67
&&(desc->
flags
&
AV_PIX_FMT_FLAG_PLANAR
)
68
&& desc->
nb_components
>= 3;
69
}
70
return
0;
71
}
72
73
static
int
write_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
74
{
75
VideoMuxData
*
img
= s->
priv_data
;
76
AVIOContext
*pb[4];
77
char
filename[1024];
78
AVCodecContext
*codec = s->
streams
[pkt->
stream_index
]->
codec
;
79
const
AVPixFmtDescriptor
*desc =
av_pix_fmt_desc_get
(codec->
pix_fmt
);
80
int
i;
81
82
if
(!img->
is_pipe
) {
83
if
(img->
update
) {
84
av_strlcpy
(filename, img->
path
,
sizeof
(filename));
85
}
else
if
(img->
use_strftime
) {
86
time_t now0;
87
struct
tm *tm, tmpbuf;
88
time(&now0);
89
tm =
localtime_r
(&now0, &tmpbuf);
90
if
(!strftime(filename,
sizeof
(filename), img->
path
, tm)) {
91
av_log
(s,
AV_LOG_ERROR
,
"Could not get frame filename with strftime\n"
);
92
return
AVERROR
(EINVAL);
93
}
94
}
else
if
(
av_get_frame_filename
(filename,
sizeof
(filename), img->
path
, img->
img_number
) < 0 &&
95
img->
img_number
> 1) {
96
av_log
(s,
AV_LOG_ERROR
,
97
"Could not get frame filename number %d from pattern '%s' (either set updatefirst or use a pattern like %%03d within the filename pattern)\n"
,
98
img->
img_number
, img->
path
);
99
return
AVERROR
(EINVAL);
100
}
101
for
(i = 0; i < 4; i++) {
102
if
(
avio_open2
(&pb[i], filename,
AVIO_FLAG_WRITE
,
103
&s->
interrupt_callback
, NULL) < 0) {
104
av_log
(s,
AV_LOG_ERROR
,
"Could not open file : %s\n"
, filename);
105
return
AVERROR
(EIO);
106
}
107
108
if
(!img->
split_planes
|| i+1 >= desc->
nb_components
)
109
break
;
110
filename[strlen(filename) - 1] =
"UVAx"
[i];
111
}
112
}
else
{
113
pb[0] = s->
pb
;
114
}
115
116
if
(img->
split_planes
) {
117
int
ysize = codec->
width
* codec->
height
;
118
int
usize =
FF_CEIL_RSHIFT
(codec->
width
, desc->
log2_chroma_w
) *
FF_CEIL_RSHIFT
(codec->
height
, desc->
log2_chroma_h
);
119
if
(desc->
comp
[0].
depth_minus1
>= 8) {
120
ysize *= 2;
121
usize *= 2;
122
}
123
avio_write
(pb[0], pkt->
data
, ysize);
124
avio_write
(pb[1], pkt->
data
+ ysize , usize);
125
avio_write
(pb[2], pkt->
data
+ ysize + usize, usize);
126
avio_close
(pb[1]);
127
avio_close
(pb[2]);
128
if
(desc->
nb_components
> 3) {
129
avio_write
(pb[3], pkt->
data
+ ysize + 2*usize, ysize);
130
avio_close
(pb[3]);
131
}
132
}
else
if
(img->
muxer
) {
133
int
ret
;
134
AVStream
*st;
135
AVPacket
pkt2 = {0};
136
AVFormatContext
*
fmt
= NULL;
137
138
av_assert0
(!img->
split_planes
);
139
140
ret =
avformat_alloc_output_context2
(&fmt, NULL, img->
muxer
, s->
filename
);
141
if
(ret < 0)
142
return
ret
;
143
st =
avformat_new_stream
(fmt, NULL);
144
if
(!st) {
145
avformat_free_context
(fmt);
146
return
AVERROR
(ENOMEM);
147
}
148
st->
id
= pkt->
stream_index
;
149
150
fmt->
pb
= pb[0];
151
if
((ret =
av_copy_packet
(&pkt2, pkt)) < 0 ||
152
(ret =
av_dup_packet
(&pkt2)) < 0 ||
153
(ret =
avcodec_copy_context
(st->
codec
, s->
streams
[0]->
codec
)) < 0 ||
154
(ret =
avformat_write_header
(fmt, NULL)) < 0 ||
155
(ret =
av_interleaved_write_frame
(fmt, &pkt2)) < 0 ||
156
(ret =
av_write_trailer
(fmt)) < 0) {
157
av_free_packet
(&pkt2);
158
avformat_free_context
(fmt);
159
return
ret
;
160
}
161
av_free_packet
(&pkt2);
162
avformat_free_context
(fmt);
163
}
else
{
164
avio_write
(pb[0], pkt->
data
, pkt->
size
);
165
}
166
avio_flush
(pb[0]);
167
if
(!img->
is_pipe
) {
168
avio_close
(pb[0]);
169
}
170
171
img->
img_number
++;
172
return
0;
173
}
174
175
#define OFFSET(x) offsetof(VideoMuxData, x)
176
#define ENC AV_OPT_FLAG_ENCODING_PARAM
177
static
const
AVOption
muxoptions
[] = {
178
{
"updatefirst"
,
"continuously overwrite one file"
,
OFFSET
(
update
),
AV_OPT_TYPE_INT
, { .i64 = 0 }, 0, 1,
ENC
},
179
{
"update"
,
"continuously overwrite one file"
,
OFFSET
(
update
),
AV_OPT_TYPE_INT
, { .i64 = 0 }, 0, 1,
ENC
},
180
{
"start_number"
,
"set first number in the sequence"
,
OFFSET
(img_number),
AV_OPT_TYPE_INT
, { .i64 = 1 }, 0, INT_MAX,
ENC
},
181
{
"strftime"
,
"use strftime for filename"
,
OFFSET
(use_strftime),
AV_OPT_TYPE_INT
, { .i64 = 0 }, 0, 1,
ENC
},
182
{ NULL },
183
};
184
185
#if CONFIG_IMAGE2_MUXER
186
static
const
AVClass
img2mux_class = {
187
.
class_name
=
"image2 muxer"
,
188
.item_name =
av_default_item_name
,
189
.option =
muxoptions
,
190
.version =
LIBAVUTIL_VERSION_INT
,
191
};
192
193
AVOutputFormat
ff_image2_muxer = {
194
.
name
=
"image2"
,
195
.long_name =
NULL_IF_CONFIG_SMALL
(
"image2 sequence"
),
196
.extensions =
"bmp,dpx,jls,jpeg,jpg,ljpg,pam,pbm,pcx,pgm,pgmyuv,png,"
197
"ppm,sgi,tga,tif,tiff,jp2,j2c,j2k,xwd,sun,ras,rs,im1,im8,im24,"
198
"sunras,xbm,xface,pix,y"
,
199
.priv_data_size =
sizeof
(
VideoMuxData
),
200
.video_codec =
AV_CODEC_ID_MJPEG
,
201
.
write_header
=
write_header
,
202
.
write_packet
=
write_packet
,
203
.
flags
=
AVFMT_NOTIMESTAMPS
|
AVFMT_NODIMENSIONS
|
AVFMT_NOFILE
,
204
.priv_class = &img2mux_class,
205
};
206
#endif
207
#if CONFIG_IMAGE2PIPE_MUXER
208
AVOutputFormat
ff_image2pipe_muxer = {
209
.
name
=
"image2pipe"
,
210
.long_name =
NULL_IF_CONFIG_SMALL
(
"piped image2 sequence"
),
211
.priv_data_size =
sizeof
(
VideoMuxData
),
212
.video_codec =
AV_CODEC_ID_MJPEG
,
213
.
write_header
=
write_header
,
214
.
write_packet
=
write_packet
,
215
.
flags
=
AVFMT_NOTIMESTAMPS
|
AVFMT_NODIMENSIONS
216
};
217
#endif
Generated on Fri Dec 5 2014 04:42:11 for FFmpeg by
1.8.2