Commit de6d9b64 authored by Fabrice Bellard's avatar Fabrice Bellard

Initial revision


Originally committed as revision 5 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 1b58d58d
version 0.4.5:
- some header fixes (Zdenek Kabelac <kabi@informatics.muni.cz>).
- many MMX optimizations (Nick Kurshev <nickols_k@mail.ru>).
- added configure system (actually a small shell script).
- added mpeg audio layer 1/2/3 decoding using LGPL'ed mpglib by
Michael Hipp (temporary solution - waiting for integer only
decoder).
- fixed VIDIOCSYNC interrupt.
- added Intel H263 decoding support ('I263' avi fourCC)
- added Real Video 1.0 decoding (needs further testing).
- simplified image formats again. Added PGM format (=grey
pgm). Renamed old PGM to PGMYUV.
- fixed msmpeg4 slice issues (tell me if you still find problems).
- fixed opendivx bugs with newer versions (added VOL header decoding).
- added support for mplayer interface.
version 0.4.4:
- fixed some std header definitions (Bjorn Lindgren
<bjorn.e.lindgren@telia.com>).
- added mpeg demux (mpeg 1 and 2 compatible).
- added ASF demux.
- added prototype RM demux.
- added AC3 decoding (done with libac3 by Aaron Holtzman).
- added decoding codec parameter guessing (.e.g. for mpeg, because the
header does not include them).
- fixed header generation in mpeg1, AVI and ASF mux : wmplayer can now
play them (only tested video).
- fixed h263 white bug.
- fixed phase rounding in img resample filter.
- add mmx code for polyphase img resample filter.
- added CPU autodetect.
- added generic title/author/copyright/comment string handling (ASF and RM use them).
- added SWF demux to extract MP3 track (not usable yet because no MP3
decoder).
- added fractional frame rate support.
- codecs are no longer searched by read_header() (should fix ffserver
segfault).
version 0.4.3:
- BGR24 patch (initial patch by Jeroen Vreeken <pe1rxq@amsat.org>).
- fixed raw yuv output.
- added motion rounding support in MPEG4.
- fixed motion bug rounding in MSMPEG4.
- added B frame handling in video core.
- added full MPEG1 decoding support.
- added partial (frame only) MPEG2 support.
- changed the FOURCC code for H.263 to "U263" to be able to see the
+AVI/H.263 file with the UB Video H.263+ decoder. MPlayer works with
this +codec ;) (JuanJo).
- Halfpel motion estimation after mb type selection (JuanJo).
- added pgm and .Y.U.V output format.
- suppressed 'img:' protocol. Simply use: /tmp/test%d.[pgm|Y] as input or
output.
- added pgmpipe I/O format (original patch from Martin Aumueller
<lists@reserv.at>, but changed completely since we use a format
instead of a protocol).
version 0.4.2:
- added H263/MPEG4/MSMPEG4 decoding support. MPEG4 decoding support
(for openDIVX) is almost complete: 8x8 MVs and rounding are
missing. MSMPEG4 support is complete.
- added prototype MPEG1 decoder. Only I and P frames handled yet (it
can decode ffmpeg mpegs :-)).
- added libavcodec API documentation (see apiexample.c).
- fixed image polyphase bug (the bottom of some images could be
greenish).
- added support for non clipped motion vectors (decoding only)
and image sizes non multiple of 16.
- added support for AC prediction (decoding only).
- added file overwrite confirmation (can be disabled with -y).
- Added custom size picture to H.263 using H.263+ (Juanjo).
version 0.4.1:
- added MSMPEG4 (aka DIVX) compatible encoder. Changed default codec
of avi and asf to DIV3.
- added -me option to set motion estimation method
(default=log). suppressed redundant -hq option.
- added options -acodec and -vcodec to force a given codec (useful for
AVI for example).
- fixed -an option.
- improved dct_quantize speed.
- factorized some motion estimation code.
version 0.4.0:
- removing grab code from ffserver and moved it to ffmpeg. Added multi
stream support to ffmpeg.
- added timeshifting support for live feeds (option ?date=xxx in the
URL).
- added high quality image resize code with polyphase filter (need
mmx/see optimisation). Enable multiple image size support in ffserver.
- added multi live feed support in ffserver.
- suppressed master feature from ffserver (it should be done with an
external program which opens the .ffm url and writes it to another
ffserver).
- added preliminary support for video stream parsing (wav and avi half
done). Added proper support for audio/video file convertion in
ffmpeg.
- added preliminary support for video file sending from ffserver.
- redesigning I/O subsystem : now using URL based input and output
(see avio.h).
- added wav format support.
- added "tty user interface" to ffmpeg to stop grabbing gracefully.
- added MMX/SSE optimizations to SAD (Sums of Absolutes Diferences)
(Juan J. Sierralta P. a.k.a. "Juanjo" <juanjo@atmlab.utfsm.cl>).
- added MMX DCT from mpeg2_movie 1.5 (Juanjo).
- added new motion estimation algorithms, log and phods (Juanjo).
- changed directories : libav for format handling, libavcodec for
codecs.
version 0.3.4:
- added stereo in mpeg audio encoder.
version 0.3.3:
- added 'high quality' mode which use motion vectors. It can be used in
real time at low resolution.
- fixed rounding problems which caused quality problems at high
bitrates and large gop size.
version 0.3.2: small fixes
- asf fixes
- put_seek bug fix
version 0.3.1: added avi/divx support
- added avi support
- added mpeg4 codec compatible with open divx. It is based on the h263
codec.
- added sound for flash format (not tested)
version 0.3: initial public release
1) Type './configure' create the configuration (use './configure
--help' to have the configure options).
2) Then type 'make' to build ffmpeg.
3) Type 'make install' to install ffmpeg and ffserver in
/usr/local/bin.
#!/bin/sh
# default parameters
prefix="/usr/local"
cc="gcc"
ar="ar"
cpu=`uname -m`
case "$cpu" in
i386|i486|i586|i686)
cpu="x86"
mmx="yes"
;;
*)
mmx="no"
;;
esac
gprof="no"
if [ "$1" = "-h" -o "$1" = "--help" ] ; then
cat << EOF
Usage: configure [options]
Options: [defaults in brackets after descriptions]
--help print this message
EOF
echo " --prefix=PREFIX install in PREFIX [$prefix]"
echo " --cc=CC use C compiler CC [$cc]"
echo " --cpu=CPU force cpu to CPU [$cpu]"
echo " --disable-mmx disable mmx usage"
echo " --enable-gprof enable profiling with gprof [$gprof]"
exit 1
fi
for opt do
case "$opt" in
--prefix=*) prefix=`echo $opt | cut -d '=' -f 2`
;;
--cc=*) cc=`echo $opt | cut -d '=' -f 2`
;;
--cpu=*) cpu=`echo $opt | cut -d '=' -f 2`
;;
--disable-mmx) mmx="no"
;;
--enable-gprof) gprof="yes"
;;
esac
done
echo "Install prefix $prefix"
echo "C compiler $cc"
echo "CPU $cpu"
echo "MMX enabled $mmx"
echo "gprof enabled $gprof"
echo "Creating config.mk and config.h"
echo "# Automatically generated by configure - do not modify" > config.mk
echo "/* Automatically generated by configure - do not modify */" > config.h
echo "PREFIX=$prefix" >> config.mk
echo "CC=$cc" >> config.mk
echo "AR=$ar" >> config.mk
if [ "$cpu" = "x86" ] ; then
echo "CONFIG_CPU_X86=y" >> config.mk
echo "#define CONFIG_CPU_X86 1" >> config.h
fi
if [ "$mmx" = "yes" ] ; then
echo "CONFIG_MMX=y" >> config.mk
echo "#define CONFIG_MMX 1" >> config.h
fi
if [ "$gprof" = "yes" ] ; then
echo "CONFIG_GPROF=y" >> config.mk
echo "#define CONFIG_GPROF 1" >> config.h
fi
1) API
------
* libavcodec is the library containing the codecs (both encoding and
decoding). See libavcodec/apiexample.c to see how to use it.
* libav is the library containing the file formats handling (mux and
demux code for several formats). (no example yet, the API is likely
to evolve).
2) Coding Rules
---------------
ffmpeg is programmed in ANSI C language. GCC extension are
tolerated. TAB size is 4. The identation is the one specified by
'indent -i4 -kr'.
Main priority in ffmpeg is simplicity and small code size (=less
bugs).
source: MarsAttack, divx, 800 kbit/s
q=10 constant:
* full motion search, fcode=1, half pel:
Video: opendivx (hq), 640x352, 25 fps, 200 kb/s
frame= 500 q=10 size= 1815kB time=20.0 bitrate= 743.6kbits/s
* log motion search:
Video: opendivx (hq), 640x352, 25 fps, 200 kb/s
frame= 500 q=10 size= 1995kB time=20.0 bitrate= 817.2kbits/s
* no motion search:
Video: opendivx, 640x352, 25 fps, 200 kb/s
frame= 500 size= 3197kB time=20.0 fps=25.0 bitrate=1309.6kbits/s q=10
* log motion search:
Video: opendivx (hq), 640x352, 25 fps, 200 kb/s
frame= 500 q=10 size= 1995kB time=20.0 bitrate= 817.2kbits/s
./ffmpeg -me log -t 20 -g 100 -qscale 10 -i img:%d.pgm -an /tmp/b.avi
Stream #0.0: Video: msmpeg4, 640x352, 25 fps, 200 kb/s
frame= 500 q=10 size= 1833kB time=20.0 bitrate= 750.9kbits/s
./ffmpeg -me full -t 20 -g 100 -qscale 10 -i img:%d.pgm -an /tmp/b.avi
Stream #0.0: Video: msmpeg4, 640x352, 25 fps, 200 kb/s
frame= 500 q=10 size= 1793kB time=20.0 bitrate= 734.8kbits/s
-------------------------------------------
* with -sameq, -me log
./ffmpeg -g 100 -t 20 -sameq -i MarsAttacks_f800.avi -an /tmp/a.avi
Stream #0.0: Video: msmpeg4, 640x352, 25 fps, 200 kb/s
frame= 500 q= 5 size= 2605kB time=20.0 bitrate=1067.1kbits/s
./ffmpeg -g 100 -t 20 -sameq -i MarsAttacks_f800.avi -f mpeg1video -an /tmp/a.mpg
Stream #0.0: Video: mpeg1video, 640x352, 25 fps, 200 kb/s
frame= 500 q= 5 size= 2655kB time=20.0 bitrate=1087.7kbits/s
./ffmpeg -g 100 -t 20 -sameq -i MarsAttacks_f800.avi -vcodec opendivx -an /tmp/a.avi
frame= 500 q= 5 size= 2774kB time=20.0 bitrate=1136.2kbits/s
the matrix, complete, video only:
source=14147kB
ffmpeg:
mpeg1 17154kB (20%)
msmpeg4 17229kB
*************** FFserver live broadcast server *****************
0) Introduction
ffserver is a streaming server for both audio and video. It supports
several live feeds, streaming from files and time shifting on live
feeds (you can seek to positions in the past on each live feed,
provided you specify a big enough feed storage in ffserver.conf).
1) Quick help
- First you must ensure that your grab system is OK. Verify with
'xawtv' that your TV card is tuned on a correct video source.
- Try with ffmpeg that you can record correctly. For example:
ffmpeg /tmp/a.mpg
will record a ten seconds mpeg file from your TV card and audio
card. Use for example the mpegtv player or MPlayer to view the created
MPEG file.
- Launch ffserver on your PC with the sample config file:
ffserver -f doc/ffserver.conf
- Verify with your browser that ffserver is working correctly. For
that purpose, explore: http://localhost:8090/stat.html .
- Now launch ffmpeg to do real time encoding :
ffmpeg http://localhost:8090/feed1.ffm
- Then, use your favorite players to see each generated stream:
mtvp http://localhost:8090/test1.mpg
mpg123 http://localhost:8090/test.mp2
netscape http://localhost:8090/test.swf
realplayer http://localhost:8090/test.rm
etc...
Note that ffserver generate multiple streams in multiple formats AT
THE SAME TIME. It should be able to handle hundreds of users at the
same time if you internet connection is fast enough.
- Now you can configure ffserver for your real needs. Edit the
ffserver.conf file to use only the formats you want. Read the ffmpeg
documentation (ffmpeg.txt) to learn more about the codec and format
stuff.
- Report any bug you find (and the fix if you have it!).
2) URL Format
ffserver supports that you seek in some formats. The syntax is to
add a '?' option to the URL. Only the 'date' option is supported.
The date format is [YYYY-MM-DDT][[HH:]MM:]SS[.m...] (clost to ISO
date format). For live streams, the date is absolute and give in
GMT. If the day is not specified, the current day is used.
example:
mpg123 http://localhost:8090/test.mp2?date=10:00
play the stream starting at 10:00 AM GMT today.
mpg123 http://localhost:8090/test.mp2?date=2001-06-23T23:00
is also a valid date.
For file streams, the date is relative to the start of the file. No
day can be specified.
This diff is collapsed.
/*
* Linux audio play and grab interface
* Copyright (c) 2000, 2001 Gerard Lantau.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <linux/soundcard.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <errno.h>
#include <sys/time.h>
#include "avformat.h"
const char *audio_device = "/dev/dsp";
typedef struct {
int fd;
int rate;
int channels;
} AudioData;
#define AUDIO_BLOCK_SIZE 4096
/* audio read support */
static int audio_read(URLContext *h, UINT8 *buf, int size)
{
AudioData *s = h->priv_data;
int ret;
ret = read(s->fd, buf, size);
if (ret < 0)
return -errno;
else
return ret;
}
static int audio_write(URLContext *h, UINT8 *buf, int size)
{
AudioData *s = h->priv_data;
int ret;
ret = write(s->fd, buf, size);
if (ret < 0)
return -errno;
else
return ret;
}
static int audio_get_format(URLContext *h, URLFormat *f)
{
AudioData *s = h->priv_data;
strcpy(f->format_name, "pcm");
f->sample_rate = s->rate;
f->channels = s->channels;
return 0;
}
/* URI syntax: 'audio:[rate[,channels]]'
default: rate=44100, channels=2
*/
static int audio_open(URLContext *h, const char *uri, int flags)
{
AudioData *s;
const char *p;
int freq, channels, audio_fd;
int tmp, err;
h->is_streamed = 1;
h->packet_size = AUDIO_BLOCK_SIZE;
s = malloc(sizeof(AudioData));
if (!s)
return -ENOMEM;
h->priv_data = s;
/* extract parameters */
p = uri;
strstart(p, "audio:", &p);
freq = strtol(p, (char **)&p, 0);
if (freq <= 0)
freq = 44100;
if (*p == ',')
p++;
channels = strtol(p, (char **)&p, 0);
if (channels <= 0)
channels = 2;
s->rate = freq;
s->channels = channels;
/* open linux audio device */
if (flags & URL_WRONLY)
audio_fd = open(audio_device,O_WRONLY);
else
audio_fd = open(audio_device,O_RDONLY);
if (audio_fd < 0) {
perror(audio_device);
return -EIO;
}
/* non blocking mode */
fcntl(audio_fd, F_SETFL, O_NONBLOCK);
#if 0
tmp=(NB_FRAGMENTS << 16) | FRAGMENT_BITS;
err=ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &tmp);
if (err < 0) {
perror("SNDCTL_DSP_SETFRAGMENT");
}
#endif
tmp=AFMT_S16_LE;
err=ioctl(audio_fd,SNDCTL_DSP_SETFMT,&tmp);
if (err < 0) {
perror("SNDCTL_DSP_SETFMT");
goto fail;
}
tmp= (channels == 2);
err=ioctl(audio_fd,SNDCTL_DSP_STEREO,&tmp);
if (err < 0) {
perror("SNDCTL_DSP_STEREO");
goto fail;
}
tmp = freq;
err=ioctl(audio_fd, SNDCTL_DSP_SPEED, &tmp);
if (err < 0) {
perror("SNDCTL_DSP_SPEED");
goto fail;
}
s->rate = tmp;
s->fd = audio_fd;
return 0;
fail:
close(audio_fd);
free(s);
return -EIO;
}
static int audio_close(URLContext *h)
{
AudioData *s = h->priv_data;
close(s->fd);
free(s);
return 0;
}
URLProtocol audio_protocol = {
"audio",
audio_open,
audio_read,
audio_write,
NULL, /* seek */
audio_close,
audio_get_format,
};
#include "avcodec.h"
#define FFMPEG_VERSION "0.4.5"
#include "avio.h"
/* packet functions */
typedef struct AVPacket {
INT64 pts;
UINT8 *data;
int size;
int stream_index;
int flags;
#define PKT_FLAG_KEY 0x0001
} AVPacket;
int av_new_packet(AVPacket *pkt, int size);
void av_free_packet(AVPacket *pkt);
/*************************************************/
/* output formats */
struct AVFormatContext;
struct AVFormatInputContext;
typedef struct AVFormatParameters {
int frame_rate;
int sample_rate;
int channels;
int width;
int height;
int pix_fmt;
} AVFormatParameters;
typedef struct AVFormat {
const char *name;
const char *long_name;
const char *mime_type;
const char *extensions; /* comma separated extensions */
/* output support */
enum CodecID audio_codec; /* default audio codec */
enum CodecID video_codec; /* default video codec */
int (*write_header)(struct AVFormatContext *);
int (*write_packet)(struct AVFormatContext *,
int stream_index,
unsigned char *buf, int size);
int (*write_trailer)(struct AVFormatContext *);
/* optional input support */
/* read the format header and initialize the AVFormatInputContext
structure. Return 0 if OK. 'ap' if non NULL contains
additionnal paramters. Only used in raw format right now */
int (*read_header)(struct AVFormatContext *,
AVFormatParameters *ap);
/* read one packet and put it in 'pkt'. pts and flags are also set */
int (*read_packet)(struct AVFormatContext *, AVPacket *pkt);
/* close the stream. The AVFormatContext and AVStreams are not
freed by this function */
int (*read_close)(struct AVFormatContext *);
/* seek at or before a given pts (given in microsecond). The pts
origin is defined by the stream */
int (*read_seek)(struct AVFormatContext *, INT64 pts);
int flags;
#define AVFMT_NOFILE 0x0001 /* no file should be opened */
struct AVFormat *next;
} AVFormat;
typedef struct AVStream {
int id; /* internal stream id */
AVCodecContext codec; /* codec context */
void *priv_data;
} AVStream;
#define MAX_STREAMS 20
/* format I/O context */
typedef struct AVFormatContext {
struct AVFormat *format;
void *priv_data;
ByteIOContext pb;
int nb_streams;
AVStream *streams[MAX_STREAMS];
char filename[1024]; /* input or output filename */
/* stream info */
char title[512];
char author[512];
char copyright[512];
char comment[512];
/* This buffer is only needed when packets were already buffered but
not decoded, for example to get the codec parameters in mpeg
streams */
struct AVPacketList *packet_buffer;
} AVFormatContext;
typedef struct AVPacketList {
AVPacket pkt;
struct AVPacketList *next;
} AVPacketList;
extern AVFormat *first_format;
/* rv10enc.c */
extern AVFormat rm_format;
/* mpegmux.c */
extern AVFormat mpeg_mux_format;
/* asfenc.c */
extern AVFormat asf_format;
/* avienc.c */
extern AVFormat avi_format;
/* jpegenc.c */
extern AVFormat mpjpeg_format;
extern AVFormat jpeg_format;
/* swfenc.c */
extern AVFormat swf_format;
/* wav.c */
extern AVFormat wav_format;
/* img.c */
extern AVFormat pgm_format;
extern AVFormat pgmyuv_format;
extern AVFormat imgyuv_format;
extern AVFormat pgmpipe_format;
/* raw.c */
extern AVFormat mp2_format;
extern AVFormat ac3_format;
extern AVFormat h263_format;
extern AVFormat mpeg1video_format;
extern AVFormat pcm_format;
extern AVFormat rawvideo_format;
/* ffm.c */
extern AVFormat ffm_format;
/* formats.c */
#define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24))
#define MKBETAG(a,b,c,d) (d | (c << 8) | (b << 16) | (a << 24))
void register_avformat(AVFormat *format);
AVFormat *guess_format(const char *short_name, const char *filename, const char *mime_type);
int strstart(const char *str, const char *val, const char **ptr);
void nstrcpy(char *buf, int buf_size, const char *str);
int match_ext(const char *filename, const char *extensions);
void register_all(void);
INT64 gettime(void);
typedef struct FifoBuffer {
UINT8 *buffer;
UINT8 *rptr, *wptr, *end;
} FifoBuffer;
int fifo_init(FifoBuffer *f, int size);
void fifo_free(FifoBuffer *f);
int fifo_size(FifoBuffer *f, UINT8 *rptr);
int fifo_read(FifoBuffer *f, UINT8 *buf, int buf_size, UINT8 **rptr_ptr);
void fifo_write(FifoBuffer *f, UINT8 *buf, int size, UINT8 **wptr_ptr);
AVFormatContext *av_open_input_file(const char *filename, int buf_size);
int av_read_packet(AVFormatContext *s, AVPacket *pkt);
void av_close_input_file(AVFormatContext *s);
int av_write_packet(AVFormatContext *s, AVPacket *pkt);
void dump_format(AVFormatContext *ic,
int index,
const char *url,