Newer
Older
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#define HAVE_AV_CONFIG_H
#include "avformat.h"
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <termios.h>
#ifdef __BEOS__
/* for snooze() */
#include <OS.h>
#endif
#include <time.h>
#include <ctype.h>
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
typedef struct {
const char *name;
int flags;
#define HAS_ARG 0x0001
#define OPT_BOOL 0x0002
#define OPT_EXPERT 0x0004
#define OPT_STRING 0x0008
union {
void (*func_arg)();
int *int_arg;
char **str_arg;
} u;
const char *help;
const char *argname;
} OptionDef;
/* select an input stream for an output stream */
typedef struct AVStreamMap {
int file_index;
int stream_index;
} AVStreamMap;
extern const OptionDef options[];
void show_help(void);
#define MAX_FILES 20
static AVFormatContext *input_files[MAX_FILES];
static int nb_input_files = 0;
static AVFormatContext *output_files[MAX_FILES];
static int nb_output_files = 0;
static AVStreamMap stream_maps[MAX_FILES];
static int nb_stream_maps;
static AVInputFormat *file_iformat;
static AVOutputFormat *file_oformat;
Michael Niedermayer
committed
static int frame_topBand = 0;
static int frame_bottomBand = 0;
static int frame_leftBand = 0;
static int frame_rightBand = 0;
static int video_bit_rate = 200*1000;
static int video_bit_rate_tolerance = 4000*1000;
static int video_qmin = 2;
static int video_qmax = 31;
static int video_qdiff = 3;
static float video_qblur = 0.5;
static float video_qcomp = 0.5;
#if 0 //experimental, (can be removed)
static float video_rc_qsquish=1.0;
static float video_rc_qmod_amp=0;
static int video_rc_qmod_freq=0;
static char *video_rc_override_string=NULL;
static char *video_rc_eq="tex^qComp";
static int video_rc_buffer_size=0;
static float video_rc_buffer_aggressivity=1.0;
static int video_rc_max_rate=0;
static int video_rc_min_rate=0;
static float video_rc_initial_cplx=0;
static float video_b_qfactor = 1.25;
static float video_b_qoffset = 1.25;
Michael Niedermayer
committed
static float video_i_qfactor = -0.8;
static int video_disable = 0;
static int video_codec_id = CODEC_ID_NONE;
static int same_quality = 0;
static int use_hq = 0;
static int do_deinterlace = 0;
static int workaround_bugs = FF_BUG_AUTODETECT;
static int error_resilience = 2;
static int error_concealment = 3;
static int dct_algo = 0;
static int idct_algo = 0;
static int use_part = 0;
static int packet_size = 0;
static int gop_size = 12;
static int intra_only = 0;
static int audio_sample_rate = 44100;
static int audio_bit_rate = 64000;
static int audio_disable = 0;
static int audio_channels = 1;
static int audio_codec_id = CODEC_ID_NONE;
static INT64 recording_time = 0;
static int file_overwrite = 0;
static char *str_title = NULL;
static char *str_author = NULL;
static char *str_copyright = NULL;
static char *str_comment = NULL;
static int do_hex_dump = 0;
static int do_play = 0;
static int do_psnr = 0;
static int do_vstats = 0;
static int do_pass = 0;
static char *pass_logfilename = NULL;
static int audio_stream_copy = 0;
static int video_stream_copy = 0;
#define DEFAULT_PASS_LOGFILENAME "ffmpeg2pass"
#ifndef CONFIG_AUDIO_OSS
const char *audio_device = "none";
#endif
#ifndef CONFIG_VIDEO4LINUX
const char *v4l_device = "none";
#endif
typedef struct AVOutputStream {
int file_index; /* file index */
int index; /* stream index in the output file */
int source_index; /* AVInputStream index */
AVStream *st; /* stream in the output file */
Fabrice Bellard
committed
int encoding_needed; /* true if encoding needed for this stream */
int frame_number;
/* input pts and corresponding output pts
for A/V sync */
double sync_ipts;
INT64 sync_opts;
/* video only */
AVPicture pict_tmp; /* temporary image for resizing */
int video_resample;
ImgReSampleContext *img_resample_ctx; /* for image resampling */
/* audio only */
int audio_resample;
ReSampleContext *resample; /* for audio resampling */
FifoBuffer fifo; /* for compression: one audio fifo per codec */
} AVOutputStream;
typedef struct AVInputStream {
int file_index;
int index;
AVStream *st;
int discard; /* true if stream data should be discarded */
int decoding_needed; /* true if the packets must be decoded in 'raw_fifo' */
INT64 sample_index; /* current sample */
Fabrice Bellard
committed
int frame_decoded; /* true if a video or audio frame has been decoded */
} AVInputStream;
typedef struct AVInputFile {
int eof_reached; /* true if eof reached */
int ist_index; /* index of first stream in ist_table */
int buffer_size; /* current total buffer size */
int buffer_size_max; /* buffer size at which we consider we can stop
buffering */
int nb_streams; /* nb streams we are aware of */
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
/* init terminal so that we can grab keys */
static struct termios oldtty;
static void term_exit(void)
{
tcsetattr (0, TCSANOW, &oldtty);
}
static void term_init(void)
{
struct termios tty;
tcgetattr (0, &tty);
oldtty = tty;
tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
|INLCR|IGNCR|ICRNL|IXON);
tty.c_oflag |= OPOST;
tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
tty.c_cflag &= ~(CSIZE|PARENB);
tty.c_cflag |= CS8;
tty.c_cc[VMIN] = 1;
tty.c_cc[VTIME] = 0;
tcsetattr (0, TCSANOW, &tty);
atexit(term_exit);
}
/* read a key without blocking */
static int read_key(void)
{
struct timeval tv;
int n;
unsigned char ch;
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(0, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 0;
n = select(1, &rfds, NULL, NULL, &tv);
if (n > 0) {
n = read(0, &ch, 1);
if (n == 1)
return n;
#else
/* no interactive support */
static void term_exit(void)
}
static void term_init(void)
{
}
static int read_key(void)
{
return 0;
#endif
int read_ffserver_streams(AVFormatContext *s, const char *filename)
{
int i, err;
err = av_open_input_file(&ic, filename, NULL, FFM_PACKET_SIZE, NULL);
if (err < 0)
return err;
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
/* copy stream format */
s->nb_streams = ic->nb_streams;
for(i=0;i<ic->nb_streams;i++) {
AVStream *st;
st = av_mallocz(sizeof(AVFormatContext));
memcpy(st, ic->streams[i], sizeof(AVStream));
s->streams[i] = st;
}
av_close_input_file(ic);
return 0;
}
#define MAX_AUDIO_PACKET_SIZE 16384
static void do_audio_out(AVFormatContext *s,
AVOutputStream *ost,
AVInputStream *ist,
unsigned char *buf, int size)
{
UINT8 *buftmp;
UINT8 audio_buf[2*MAX_AUDIO_PACKET_SIZE]; /* XXX: allocate it */
UINT8 audio_out[MAX_AUDIO_PACKET_SIZE]; /* XXX: allocate it */
int size_out, frame_bytes, ret;
AVCodecContext *enc;
enc = &ost->st->codec;
if (ost->audio_resample) {
buftmp = audio_buf;
size_out = audio_resample(ost->resample,
(short *)buftmp, (short *)buf,
size / (ist->st->codec.channels * 2));
size_out = size_out * enc->channels * 2;
} else {
buftmp = buf;
size_out = size;
}
/* now encode as many frames as possible */
if (enc->frame_size > 1) {
/* output resampled raw samples */
fifo_write(&ost->fifo, buftmp, size_out,
&ost->fifo.wptr);
frame_bytes = enc->frame_size * 2 * enc->channels;
while (fifo_read(&ost->fifo, audio_buf, frame_bytes,
&ost->fifo.rptr) == 0) {
ret = avcodec_encode_audio(enc, audio_out, sizeof(audio_out),
(short *)audio_buf);
Fabrice Bellard
committed
av_write_frame(s, ost->index, audio_out, ret);
/* output a pcm frame */
/* XXX: change encoding codec API to avoid this ? */
switch(enc->codec->id) {
case CODEC_ID_PCM_S16LE:
case CODEC_ID_PCM_S16BE:
case CODEC_ID_PCM_U16LE:
case CODEC_ID_PCM_U16BE:
break;
default:
size_out = size_out >> 1;
break;
}
ret = avcodec_encode_audio(enc, audio_out, size_out,
(short *)buftmp);
Fabrice Bellard
committed
av_write_frame(s, ost->index, audio_out, ret);
static void write_picture(AVFormatContext *s, int index, AVPicture *picture,
int pix_fmt, int w, int h)
/* XXX: not efficient, should add test if we can take
directly the AVPicture */
switch(pix_fmt) {
case PIX_FMT_YUV420P:
size = avpicture_get_size(pix_fmt, w, h);
Loading
Loading full blame...