diff options
author | Fabrice Bellard <fabrice@bellard.org> | 2002-11-25 22:07:40 +0300 |
---|---|---|
committer | Fabrice Bellard <fabrice@bellard.org> | 2002-11-25 22:07:40 +0300 |
commit | abac6175916c57f59ddb51ffe41bfd1d9851fe38 (patch) | |
tree | 8fc5b70a143f0f74468c353afbf043d7e104cdc0 /libav | |
parent | 57fc25764261abe71b6cf7571eca182f8acf5795 (diff) |
renamed libav to libavformat
Originally committed as revision 1276 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libav')
-rw-r--r-- | libav/.cvsignore | 6 | ||||
-rw-r--r-- | libav/Makefile | 72 | ||||
-rw-r--r-- | libav/allformats.c | 74 | ||||
-rw-r--r-- | libav/asf.c | 1256 | ||||
-rw-r--r-- | libav/au.c | 214 | ||||
-rw-r--r-- | libav/audio.c | 330 | ||||
-rw-r--r-- | libav/avformat.h | 351 | ||||
-rw-r--r-- | libav/avi.h | 28 | ||||
-rw-r--r-- | libav/avidec.c | 256 | ||||
-rw-r--r-- | libav/avienc.c | 432 | ||||
-rw-r--r-- | libav/avio.c | 156 | ||||
-rw-r--r-- | libav/avio.h | 153 | ||||
-rw-r--r-- | libav/aviobuf.c | 687 | ||||
-rw-r--r-- | libav/barpainet.c | 25 | ||||
-rw-r--r-- | libav/barpainet.h | 23 | ||||
-rw-r--r-- | libav/beosaudio.cpp | 449 | ||||
-rw-r--r-- | libav/crc.c | 111 | ||||
-rw-r--r-- | libav/cutils.c | 110 | ||||
-rw-r--r-- | libav/dv.c | 134 | ||||
-rw-r--r-- | libav/ffm.c | 684 | ||||
-rw-r--r-- | libav/file.c | 130 | ||||
-rw-r--r-- | libav/framehook.c | 102 | ||||
-rw-r--r-- | libav/framehook.h | 19 | ||||
-rw-r--r-- | libav/gif.c | 375 | ||||
-rw-r--r-- | libav/grab.c | 829 | ||||
-rw-r--r-- | libav/http.c | 290 | ||||
-rw-r--r-- | libav/img.c | 945 | ||||
-rw-r--r-- | libav/jpeg.c | 266 | ||||
-rw-r--r-- | libav/mov.c | 1347 | ||||
-rw-r--r-- | libav/mpeg.c | 685 | ||||
-rw-r--r-- | libav/mpegts.c | 316 | ||||
-rw-r--r-- | libav/ogg.c | 269 | ||||
-rw-r--r-- | libav/raw.c | 509 | ||||
-rw-r--r-- | libav/rm.c | 773 | ||||
-rw-r--r-- | libav/rtp.c | 687 | ||||
-rw-r--r-- | libav/rtp.h | 40 | ||||
-rw-r--r-- | libav/rtpproto.c | 300 | ||||
-rw-r--r-- | libav/rtsp.c | 1163 | ||||
-rw-r--r-- | libav/rtsp.h | 86 | ||||
-rw-r--r-- | libav/rtspcodes.h | 11 | ||||
-rw-r--r-- | libav/strptime.c | 1004 | ||||
-rw-r--r-- | libav/strptime.h | 32 | ||||
-rw-r--r-- | libav/swf.c | 571 | ||||
-rw-r--r-- | libav/tcp.c | 176 | ||||
-rw-r--r-- | libav/udp.c | 272 | ||||
-rw-r--r-- | libav/utils.c | 1280 | ||||
-rw-r--r-- | libav/wav.c | 326 |
47 files changed, 0 insertions, 18354 deletions
diff --git a/libav/.cvsignore b/libav/.cvsignore deleted file mode 100644 index 0cc425cc33..0000000000 --- a/libav/.cvsignore +++ /dev/null @@ -1,6 +0,0 @@ -config.h -config.mak -*ffmpeg -ffserver -Makefile.* -.depend diff --git a/libav/Makefile b/libav/Makefile deleted file mode 100644 index 1051aa6543..0000000000 --- a/libav/Makefile +++ /dev/null @@ -1,72 +0,0 @@ -# -# libavformat Makefile -# (c) 2000, 2001, 2002 Fabrice Bellard -# -include ../config.mak - -VPATH=$(SRC_PATH)/libav - -CFLAGS= $(OPTFLAGS) -Wall -g -I.. -I$(SRC_PATH) -I$(SRC_PATH)/libavcodec -DHAVE_AV_CONFIG_H -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE - -OBJS= utils.o cutils.o allformats.o - -# mux and demuxes -OBJS+=mpeg.o mpegts.o ffm.o crc.o img.o raw.o rm.o asf.o \ - avienc.o avidec.o wav.o swf.o au.o gif.o mov.o jpeg.o dv.o framehook.o -# file I/O -OBJS+= avio.o aviobuf.o file.o - -ifeq ($(BUILD_STRPTIME),yes) -OBJS+= strptime.o -endif - -ifeq ($(CONFIG_VIDEO4LINUX),yes) -OBJS+= grab.o -endif - -ifeq ($(CONFIG_AUDIO_OSS),yes) -OBJS+= audio.o -endif - -ifeq ($(CONFIG_AUDIO_BEOS),yes) -OBJS+= beosaudio.o -endif - -ifeq ($(CONFIG_NETWORK),yes) -OBJS+= udp.o tcp.o http.o rtsp.o rtp.o rtpproto.o -# BeOS network stuff -ifeq ($(CONFIG_BEOS_NETSERVER),yes) -OBJS+= barpainet.o -endif -endif - -ifeq ($(CONFIG_VORBIS),yes) -OBJS+= ogg.o -endif - -LIB= libavformat.a - -all: $(LIB) - -$(LIB): $(OBJS) - rm -f $@ - $(AR) rc $@ $(OBJS) - $(RANLIB) $@ - -installlib: all - install -m 644 $(LIB) $(prefix)/lib - mkdir -p $(prefix)/include/ffmpeg - install -m 644 $(SRC_PATH)/libav/avformat.h $(SRC_PATH)/libav/avio.h \ - $(SRC_PATH)/libav/rtp.h $(SRC_PATH)/libav/rtsp.h \ - $(SRC_PATH)/libav/rtspcodes.h \ - $(prefix)/include/ffmpeg - -%.o: %.c - $(CC) $(CFLAGS) -c -o $@ $< - -# BeOS: remove -Wall to get rid of all the "multibyte constant" warnings -%.o: %.cpp - g++ $(subst -Wall,,$(CFLAGS)) -c -o $@ $< - -clean: - rm -f *.o *~ *.a diff --git a/libav/allformats.c b/libav/allformats.c deleted file mode 100644 index 8a65638e88..0000000000 --- a/libav/allformats.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Register all the formats and protocols - * 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" - -/* If you do not call this function, then you can select exactly which - formats you want to support */ - -/** - * Initialize libavcodec and register all the codecs and formats. - */ -void av_register_all(void) -{ - avcodec_init(); - avcodec_register_all(); - - mpegps_init(); - mpegts_init(); - crc_init(); - img_init(); - raw_init(); - rm_init(); - asf_init(); - avienc_init(); - avidec_init(); - wav_init(); - swf_init(); - au_init(); - gif_init(); - mov_init(); - jpeg_init(); - dv_init(); - -#ifdef CONFIG_VORBIS - ogg_init(); -#endif - -#ifndef CONFIG_WIN32 - ffm_init(); -#endif -#ifdef CONFIG_VIDEO4LINUX - video_grab_init(); -#endif -#if defined(CONFIG_AUDIO_OSS) || defined(CONFIG_AUDIO_BEOS) - audio_init(); -#endif - - /* file protocols */ - register_protocol(&file_protocol); - register_protocol(&pipe_protocol); -#ifdef CONFIG_NETWORK - rtsp_init(); - rtp_init(); - register_protocol(&udp_protocol); - register_protocol(&rtp_protocol); - register_protocol(&tcp_protocol); - register_protocol(&http_protocol); -#endif -} diff --git a/libav/asf.c b/libav/asf.c deleted file mode 100644 index 2f1ce12dc3..0000000000 --- a/libav/asf.c +++ /dev/null @@ -1,1256 +0,0 @@ -/* - * ASF compatible encoder and decoder. - * Copyright (c) 2000, 2001 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" -#include "avi.h" -#include "mpegaudio.h" - -#define PACKET_SIZE 3200 -#define PACKET_HEADER_SIZE 12 -#define FRAME_HEADER_SIZE 17 - -typedef struct { - int num; - int seq; - /* use for reading */ - AVPacket pkt; - int frag_offset; - int timestamp; - INT64 duration; - - int ds_span; /* descrambling */ - int ds_packet_size; - int ds_chunk_size; - int ds_data_size; - int ds_silence_data; - -} ASFStream; - -typedef struct { - UINT32 v1; - UINT16 v2; - UINT16 v3; - UINT8 v4[8]; -} GUID; - -typedef struct __attribute__((packed)) { - GUID guid; // generated by client computer - uint64_t file_size; // in bytes - // invalid if broadcasting - uint64_t create_time; // time of creation, in 100-nanosecond units since 1.1.1601 - // invalid if broadcasting - uint64_t packets_count; // how many packets are there in the file - // invalid if broadcasting - uint64_t play_time; // play time, in 100-nanosecond units - // invalid if broadcasting - uint64_t send_time; // time to send file, in 100-nanosecond units - // invalid if broadcasting (could be ignored) - uint32_t preroll; // timestamp of the first packet, in milliseconds - // if nonzero - substract from time - uint32_t ignore; // preroll is 64bit - but let's just ignore it - uint32_t flags; // 0x01 - broadcast - // 0x02 - seekable - // rest is reserved should be 0 - uint32_t min_pktsize; // size of a data packet - // invalid if broadcasting - uint32_t max_pktsize; // shall be the same as for min_pktsize - // invalid if broadcasting - uint32_t max_bitrate; // bandwith of stream in bps - // should be the sum of bitrates of the - // individual media streams -} ASFMainHeader; - - -typedef struct { - int seqno; - int packet_size; - int is_streamed; - int asfid2avid[128]; /* conversion table from asf ID 2 AVStream ID */ - ASFStream streams[128]; /* it's max number and it's not that big */ - /* non streamed additonnal info */ - INT64 nb_packets; - INT64 duration; /* in 100ns units */ - /* packet filling */ - int packet_size_left; - int packet_timestamp_start; - int packet_timestamp_end; - int packet_nb_frames; - UINT8 packet_buf[PACKET_SIZE]; - ByteIOContext pb; - /* only for reading */ - uint64_t data_offset; /* begining of the first data packet */ - - ASFMainHeader hdr; - - int packet_flags; - int packet_property; - int packet_timestamp; - int packet_segsizetype; - int packet_segments; - int packet_seq; - int packet_replic_size; - int packet_key_frame; - int packet_padsize; - int packet_frag_offset; - int packet_frag_size; - int packet_frag_timestamp; - int packet_multi_size; - int packet_obj_size; - int packet_time_delta; - int packet_time_start; - - int stream_index; - ASFStream* asf_st; /* currently decoded stream */ -} ASFContext; - -static const GUID asf_header = { - 0x75B22630, 0x668E, 0x11CF, { 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C }, -}; - -static const GUID file_header = { - 0x8CABDCA1, 0xA947, 0x11CF, { 0x8E, 0xE4, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65 }, -}; - -static const GUID stream_header = { - 0xB7DC0791, 0xA9B7, 0x11CF, { 0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65 }, -}; - -static const GUID audio_stream = { - 0xF8699E40, 0x5B4D, 0x11CF, { 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B }, -}; - -static const GUID audio_conceal_none = { - // 0x49f1a440, 0x4ece, 0x11d0, { 0xa3, 0xac, 0x00, 0xa0, 0xc9, 0x03, 0x48, 0xf6 }, - // New value lifted from avifile - 0x20fb5700, 0x5b55, 0x11cf, { 0xa8, 0xfd, 0x00, 0x80, 0x5f, 0x5c, 0x44, 0x2b }, -}; - -static const GUID video_stream = { - 0xBC19EFC0, 0x5B4D, 0x11CF, { 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B }, -}; - -static const GUID video_conceal_none = { - 0x20FB5700, 0x5B55, 0x11CF, { 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B }, -}; - - -static const GUID comment_header = { - 0x75b22633, 0x668e, 0x11cf, { 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c }, -}; - -static const GUID codec_comment_header = { - 0x86D15240, 0x311D, 0x11D0, { 0xA3, 0xA4, 0x00, 0xA0, 0xC9, 0x03, 0x48, 0xF6 }, -}; -static const GUID codec_comment1_header = { - 0x86d15241, 0x311d, 0x11d0, { 0xa3, 0xa4, 0x00, 0xa0, 0xc9, 0x03, 0x48, 0xf6 }, -}; - -static const GUID data_header = { - 0x75b22636, 0x668e, 0x11cf, { 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c }, -}; - -static const GUID index_guid = { - 0x33000890, 0xe5b1, 0x11cf, { 0x89, 0xf4, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xcb }, -}; - -static const GUID head1_guid = { - 0x5fbf03b5, 0xa92e, 0x11cf, { 0x8e, 0xe3, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65 }, -}; - -static const GUID head2_guid = { - 0xabd3d211, 0xa9ba, 0x11cf, { 0x8e, 0xe6, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65 }, -}; - -/* I am not a number !!! This GUID is the one found on the PC used to - generate the stream */ -static const GUID my_guid = { - 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, -}; - -static void put_guid(ByteIOContext *s, const GUID *g) -{ - int i; - - put_le32(s, g->v1); - put_le16(s, g->v2); - put_le16(s, g->v3); - for(i=0;i<8;i++) - put_byte(s, g->v4[i]); -} - -static void put_str16(ByteIOContext *s, const char *tag) -{ - int c; - - put_le16(s,strlen(tag) + 1); - for(;;) { - c = (UINT8)*tag++; - put_le16(s, c); - if (c == '\0') - break; - } -} - -static void put_str16_nolen(ByteIOContext *s, const char *tag) -{ - int c; - - for(;;) { - c = (UINT8)*tag++; - put_le16(s, c); - if (c == '\0') - break; - } -} - -static INT64 put_header(ByteIOContext *pb, const GUID *g) -{ - INT64 pos; - - pos = url_ftell(pb); - put_guid(pb, g); - put_le64(pb, 24); - return pos; -} - -/* update header size */ -static void end_header(ByteIOContext *pb, INT64 pos) -{ - INT64 pos1; - - pos1 = url_ftell(pb); - url_fseek(pb, pos + 16, SEEK_SET); - put_le64(pb, pos1 - pos); - url_fseek(pb, pos1, SEEK_SET); -} - -/* write an asf chunk (only used in streaming case) */ -static void put_chunk(AVFormatContext *s, int type, int payload_length, int flags) -{ - ASFContext *asf = s->priv_data; - ByteIOContext *pb = &s->pb; - int length; - - length = payload_length + 8; - put_le16(pb, type); - put_le16(pb, length); - put_le32(pb, asf->seqno); - put_le16(pb, flags); /* unknown bytes */ - put_le16(pb, length); - asf->seqno++; -} - -/* convert from unix to windows time */ -static INT64 unix_to_file_time(int ti) -{ - INT64 t; - - t = ti * INT64_C(10000000); - t += INT64_C(116444736000000000); - return t; -} - -/* write the header (used two times if non streamed) */ -static int asf_write_header1(AVFormatContext *s, INT64 file_size, INT64 data_chunk_size) -{ - ASFContext *asf = s->priv_data; - ByteIOContext *pb = &s->pb; - int header_size, n, extra_size, extra_size2, wav_extra_size, file_time; - int has_title; - AVCodecContext *enc; - INT64 header_offset, cur_pos, hpos; - int bit_rate; - - has_title = (s->title[0] || s->author[0] || s->copyright[0] || s->comment[0]); - - bit_rate = 0; - for(n=0;n<s->nb_streams;n++) { - enc = &s->streams[n]->codec; - - bit_rate += enc->bit_rate; - } - - if (asf->is_streamed) { - put_chunk(s, 0x4824, 0, 0xc00); /* start of stream (length will be patched later) */ - } - - put_guid(pb, &asf_header); - put_le64(pb, -1); /* header length, will be patched after */ - put_le32(pb, 3 + has_title + s->nb_streams); /* number of chunks in header */ - put_byte(pb, 1); /* ??? */ - put_byte(pb, 2); /* ??? */ - - /* file header */ - header_offset = url_ftell(pb); - hpos = put_header(pb, &file_header); - put_guid(pb, &my_guid); - put_le64(pb, file_size); - file_time = 0; - put_le64(pb, unix_to_file_time(file_time)); - put_le64(pb, asf->nb_packets); /* number of packets */ - put_le64(pb, asf->duration); /* end time stamp (in 100ns units) */ - put_le64(pb, asf->duration); /* duration (in 100ns units) */ - put_le32(pb, 0); /* start time stamp */ - put_le32(pb, 0); /* ??? */ - put_le32(pb, asf->is_streamed ? 1 : 0); /* ??? */ - put_le32(pb, asf->packet_size); /* packet size */ - put_le32(pb, asf->packet_size); /* packet size */ - put_le32(pb, bit_rate); /* Nominal data rate in bps */ - end_header(pb, hpos); - - /* unknown headers */ - hpos = put_header(pb, &head1_guid); - put_guid(pb, &head2_guid); - put_le32(pb, 6); - put_le16(pb, 0); - end_header(pb, hpos); - - /* title and other infos */ - if (has_title) { - hpos = put_header(pb, &comment_header); - put_le16(pb, 2 * (strlen(s->title) + 1)); - put_le16(pb, 2 * (strlen(s->author) + 1)); - put_le16(pb, 2 * (strlen(s->copyright) + 1)); - put_le16(pb, 2 * (strlen(s->comment) + 1)); - put_le16(pb, 0); - put_str16_nolen(pb, s->title); - put_str16_nolen(pb, s->author); - put_str16_nolen(pb, s->copyright); - put_str16_nolen(pb, s->comment); - end_header(pb, hpos); - } - - /* stream headers */ - for(n=0;n<s->nb_streams;n++) { - INT64 es_pos; - // ASFStream *stream = &asf->streams[n]; - - enc = &s->streams[n]->codec; - asf->streams[n].num = n + 1; - asf->streams[n].seq = 0; - - switch(enc->codec_type) { - case CODEC_TYPE_AUDIO: - wav_extra_size = 0; - extra_size = 18 + wav_extra_size; - extra_size2 = 0; - break; - default: - case CODEC_TYPE_VIDEO: - wav_extra_size = 0; - extra_size = 0x33; - extra_size2 = 0; - break; - } - - hpos = put_header(pb, &stream_header); - if (enc->codec_type == CODEC_TYPE_AUDIO) { - put_guid(pb, &audio_stream); - put_guid(pb, &audio_conceal_none); - } else { - put_guid(pb, &video_stream); - put_guid(pb, &video_conceal_none); - } - put_le64(pb, 0); /* ??? */ - es_pos = url_ftell(pb); - put_le32(pb, extra_size); /* wav header len */ - put_le32(pb, extra_size2); /* additional data len */ - put_le16(pb, n + 1); /* stream number */ - put_le32(pb, 0); /* ??? */ - - if (enc->codec_type == CODEC_TYPE_AUDIO) { - /* WAVEFORMATEX header */ - int wavsize = put_wav_header(pb, enc); - - if (wavsize < 0) - return -1; - if (wavsize != extra_size) { - cur_pos = url_ftell(pb); - url_fseek(pb, es_pos, SEEK_SET); - put_le32(pb, wavsize); /* wav header len */ - url_fseek(pb, cur_pos, SEEK_SET); - } - } else { - put_le32(pb, enc->width); - put_le32(pb, enc->height); - put_byte(pb, 2); /* ??? */ - put_le16(pb, 40); /* size */ - - /* BITMAPINFOHEADER header */ - put_bmp_header(pb, enc, codec_bmp_tags, 1); - } - end_header(pb, hpos); - } - - /* media comments */ - - hpos = put_header(pb, &codec_comment_header); - put_guid(pb, &codec_comment1_header); - put_le32(pb, s->nb_streams); - for(n=0;n<s->nb_streams;n++) { - AVCodec *p; - - enc = &s->streams[n]->codec; - p = avcodec_find_encoder(enc->codec_id); - - put_le16(pb, asf->streams[n].num); - put_str16(pb, p ? p->name : enc->codec_name); - put_le16(pb, 0); /* no parameters */ - /* id */ - if (enc->codec_type == CODEC_TYPE_AUDIO) { - put_le16(pb, 2); - put_le16(pb, codec_get_tag(codec_wav_tags, enc->codec_id)); - } else { - put_le16(pb, 4); - put_le32(pb, codec_get_tag(codec_bmp_tags, enc->codec_id)); - } - } - end_header(pb, hpos); - - /* patch the header size fields */ - - cur_pos = url_ftell(pb); - header_size = cur_pos - header_offset; - if (asf->is_streamed) { - header_size += 8 + 30 + 50; - - url_fseek(pb, header_offset - 10 - 30, SEEK_SET); - put_le16(pb, header_size); - url_fseek(pb, header_offset - 2 - 30, SEEK_SET); - put_le16(pb, header_size); - - header_size -= 8 + 30 + 50; - } - header_size += 24 + 6; - url_fseek(pb, header_offset - 14, SEEK_SET); - put_le64(pb, header_size); - url_fseek(pb, cur_pos, SEEK_SET); - - /* movie chunk, followed by packets of packet_size */ - asf->data_offset = cur_pos; - put_guid(pb, &data_header); - put_le64(pb, data_chunk_size); - put_guid(pb, &my_guid); - put_le64(pb, asf->nb_packets); /* nb packets */ - put_byte(pb, 1); /* ??? */ - put_byte(pb, 1); /* ??? */ - return 0; -} - -static int asf_write_header(AVFormatContext *s) -{ - ASFContext *asf = s->priv_data; - - av_set_pts_info(s, 32, 1, 1000); /* 32 bit pts in ms */ - - asf->packet_size = PACKET_SIZE; - asf->nb_packets = 0; - - if (asf_write_header1(s, 0, 50) < 0) { - //av_free(asf); - return -1; - } - - put_flush_packet(&s->pb); - - asf->packet_nb_frames = 0; - asf->packet_timestamp_start = -1; - asf->packet_timestamp_end = -1; - asf->packet_size_left = asf->packet_size - PACKET_HEADER_SIZE; - init_put_byte(&asf->pb, asf->packet_buf, asf->packet_size, 1, - NULL, NULL, NULL, NULL); - - return 0; -} - -static int asf_write_stream_header(AVFormatContext *s) -{ - ASFContext *asf = s->priv_data; - - asf->is_streamed = 1; - - return asf_write_header(s); -} - -/* write a fixed size packet */ -static int put_packet(AVFormatContext *s, - unsigned int timestamp, unsigned int duration, - int nb_frames, int padsize) -{ - ASFContext *asf = s->priv_data; - ByteIOContext *pb = &s->pb; - int flags; - - if (asf->is_streamed) { - put_chunk(s, 0x4424, asf->packet_size, 0); - } - - put_byte(pb, 0x82); - put_le16(pb, 0); - - flags = 0x01; /* nb segments present */ - if (padsize > 0) { - if (padsize < 256) - flags |= 0x08; - else - flags |= 0x10; - } - put_byte(pb, flags); /* flags */ - put_byte(pb, 0x5d); - if (flags & 0x10) - put_le16(pb, padsize - 2); - if (flags & 0x08) - put_byte(pb, padsize - 1); - put_le32(pb, timestamp); - put_le16(pb, duration); - put_byte(pb, nb_frames | 0x80); - - return PACKET_HEADER_SIZE + ((flags & 0x18) >> 3); -} - -static void flush_packet(AVFormatContext *s) -{ - ASFContext *asf = s->priv_data; - int hdr_size, ptr; - - hdr_size = put_packet(s, asf->packet_timestamp_start, - asf->packet_timestamp_end - asf->packet_timestamp_start, - asf->packet_nb_frames, asf->packet_size_left); - - /* Clear out the padding bytes */ - ptr = asf->packet_size - hdr_size - asf->packet_size_left; - memset(asf->packet_buf + ptr, 0, asf->packet_size_left); - - put_buffer(&s->pb, asf->packet_buf, asf->packet_size - hdr_size); - - put_flush_packet(&s->pb); - asf->nb_packets++; - asf->packet_nb_frames = 0; - asf->packet_timestamp_start = -1; - asf->packet_timestamp_end = -1; - asf->packet_size_left = asf->packet_size - PACKET_HEADER_SIZE; - init_put_byte(&asf->pb, asf->packet_buf, asf->packet_size, 1, - NULL, NULL, NULL, NULL); -} - -static void put_frame_header(AVFormatContext *s, ASFStream *stream, int timestamp, - int payload_size, int frag_offset, int frag_len) -{ - ASFContext *asf = s->priv_data; - ByteIOContext *pb = &asf->pb; - int val; - - val = stream->num; - if (s->streams[val - 1]->codec.key_frame /* && frag_offset == 0 */) - val |= 0x80; - put_byte(pb, val); - put_byte(pb, stream->seq); - put_le32(pb, frag_offset); /* fragment offset */ - put_byte(pb, 0x08); /* flags */ - put_le32(pb, payload_size); - put_le32(pb, timestamp); - put_le16(pb, frag_len); -} - - -/* Output a frame. We suppose that payload_size <= PACKET_SIZE. - - It is there that you understand that the ASF format is really - crap. They have misread the MPEG Systems spec ! - */ -static void put_frame(AVFormatContext *s, ASFStream *stream, int timestamp, - UINT8 *buf, int payload_size) -{ - ASFContext *asf = s->priv_data; - int frag_pos, frag_len, frag_len1; - - frag_pos = 0; - while (frag_pos < payload_size) { - frag_len = payload_size - frag_pos; - frag_len1 = asf->packet_size_left - FRAME_HEADER_SIZE; - if (frag_len1 > 0) { - if (frag_len > frag_len1) - frag_len = frag_len1; - put_frame_header(s, stream, timestamp+1, payload_size, frag_pos, frag_len); - put_buffer(&asf->pb, buf, frag_len); - asf->packet_size_left -= (frag_len + FRAME_HEADER_SIZE); - asf->packet_timestamp_end = timestamp; - if (asf->packet_timestamp_start == -1) - asf->packet_timestamp_start = timestamp; - asf->packet_nb_frames++; - } else { - frag_len = 0; - } - frag_pos += frag_len; - buf += frag_len; - /* output the frame if filled */ - if (asf->packet_size_left <= FRAME_HEADER_SIZE) - flush_packet(s); - } - stream->seq++; -} - - -static int asf_write_packet(AVFormatContext *s, int stream_index, - UINT8 *buf, int size, int timestamp) -{ - ASFContext *asf = s->priv_data; - ASFStream *stream; - INT64 duration; - AVCodecContext *codec; - - codec = &s->streams[stream_index]->codec; - stream = &asf->streams[stream_index]; - - if (codec->codec_type == CODEC_TYPE_AUDIO) { - duration = (codec->frame_number * codec->frame_size * INT64_C(10000000)) / - codec->sample_rate; - } else { - duration = codec->frame_number * - ((INT64_C(10000000) * FRAME_RATE_BASE) / codec->frame_rate); - } - if (duration > asf->duration) - asf->duration = duration; - - put_frame(s, stream, timestamp, buf, size); - return 0; -} - -static int asf_write_trailer(AVFormatContext *s) -{ - ASFContext *asf = s->priv_data; - INT64 file_size; - - /* flush the current packet */ - if (asf->pb.buf_ptr > asf->pb.buffer) - flush_packet(s); - - if (asf->is_streamed) { - put_chunk(s, 0x4524, 0, 0); /* end of stream */ - } else { - /* rewrite an updated header */ - file_size = url_ftell(&s->pb); - url_fseek(&s->pb, 0, SEEK_SET); - asf_write_header1(s, file_size, file_size - asf->data_offset); - } - - put_flush_packet(&s->pb); - return 0; -} - -/**********************************/ -/* decoding */ - -//#define DEBUG - -#ifdef DEBUG -static void print_guid(const GUID *g) -{ - int i; - printf("0x%08x, 0x%04x, 0x%04x, {", g->v1, g->v2, g->v3); - for(i=0;i<8;i++) - printf(" 0x%02x,", g->v4[i]); - printf("}\n"); -} -#endif - -static void get_guid(ByteIOContext *s, GUID *g) -{ - int i; - - g->v1 = get_le32(s); - g->v2 = get_le16(s); - g->v3 = get_le16(s); - for(i=0;i<8;i++) - g->v4[i] = get_byte(s); -} - -#if 0 -static void get_str16(ByteIOContext *pb, char *buf, int buf_size) -{ - int len, c; - char *q; - - len = get_le16(pb); - q = buf; - while (len > 0) { - c = get_le16(pb); - if ((q - buf) < buf_size - 1) - *q++ = c; - len--; - } - *q = '\0'; -} -#endif - -static void get_str16_nolen(ByteIOContext *pb, int len, char *buf, int buf_size) -{ - int c; - char *q; - - q = buf; - while (len > 0) { - c = get_le16(pb); - if ((q - buf) < buf_size - 1) - *q++ = c; - len-=2; - } - *q = '\0'; -} - -static int asf_probe(AVProbeData *pd) -{ - GUID g; - const unsigned char *p; - int i; - - /* check file header */ - if (pd->buf_size <= 32) - return 0; - p = pd->buf; - g.v1 = p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); - p += 4; - g.v2 = p[0] | (p[1] << 8); - p += 2; - g.v3 = p[0] | (p[1] << 8); - p += 2; - for(i=0;i<8;i++) - g.v4[i] = *p++; - - if (!memcmp(&g, &asf_header, sizeof(GUID))) - return AVPROBE_SCORE_MAX; - else - return 0; -} - -static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - ASFContext *asf = s->priv_data; - GUID g; - ByteIOContext *pb = &s->pb; - AVStream *st; - ASFStream *asf_st; - int size, i; - INT64 gsize; - - av_set_pts_info(s, 32, 1, 1000); /* 32 bit pts in ms */ - - get_guid(pb, &g); - if (memcmp(&g, &asf_header, sizeof(GUID))) - goto fail; - get_le64(pb); - get_le32(pb); - get_byte(pb); - get_byte(pb); - memset(&asf->asfid2avid, -1, sizeof(asf->asfid2avid)); - for(;;) { - get_guid(pb, &g); - gsize = get_le64(pb); -#ifdef DEBUG - printf("%08Lx: ", url_ftell(pb) - 24); - print_guid(&g); - printf(" size=0x%Lx\n", gsize); -#endif - if (gsize < 24) - goto fail; - if (!memcmp(&g, &file_header, sizeof(GUID))) { - get_guid(pb, &asf->hdr.guid); - asf->hdr.file_size = get_le64(pb); - asf->hdr.create_time = get_le64(pb); - asf->hdr.packets_count = get_le64(pb); - asf->hdr.play_time = get_le64(pb); - asf->hdr.send_time = get_le64(pb); - asf->hdr.preroll = get_le32(pb); - asf->hdr.ignore = get_le32(pb); - asf->hdr.flags = get_le32(pb); - asf->hdr.min_pktsize = get_le32(pb); - asf->hdr.max_pktsize = get_le32(pb); - asf->hdr.max_bitrate = get_le32(pb); - asf->packet_size = asf->hdr.max_pktsize; - asf->nb_packets = asf->hdr.packets_count; - } else if (!memcmp(&g, &stream_header, sizeof(GUID))) { - int type, total_size; - unsigned int tag1; - INT64 pos1, pos2; - - pos1 = url_ftell(pb); - - st = av_mallocz(sizeof(AVStream)); - if (!st) - goto fail; - s->streams[s->nb_streams] = st; - asf_st = av_mallocz(sizeof(ASFStream)); - if (!asf_st) - goto fail; - st->priv_data = asf_st; - st->time_length = (asf->hdr.send_time - asf->hdr.preroll) / 10; // us - get_guid(pb, &g); - if (!memcmp(&g, &audio_stream, sizeof(GUID))) { - type = CODEC_TYPE_AUDIO; - } else if (!memcmp(&g, &video_stream, sizeof(GUID))) { - type = CODEC_TYPE_VIDEO; - } else { - goto fail; - } - get_guid(pb, &g); - total_size = get_le64(pb); - get_le32(pb); - get_le32(pb); - st->id = get_le16(pb) & 0x7f; /* stream id */ - // mapping of asf ID to AV stream ID; - asf->asfid2avid[st->id] = s->nb_streams++; - - get_le32(pb); - st->codec.codec_type = type; - st->codec.frame_rate = 15 * s->pts_den / s->pts_num; // 15 fps default - if (type == CODEC_TYPE_AUDIO) { - get_wav_header(pb, &st->codec, 1); - /* We have to init the frame size at some point .... */ - pos2 = url_ftell(pb); - if (gsize > (pos2 + 8 - pos1 + 24)) { - asf_st->ds_span = get_byte(pb); - asf_st->ds_packet_size = get_le16(pb); - asf_st->ds_chunk_size = get_le16(pb); - asf_st->ds_data_size = get_le16(pb); - asf_st->ds_silence_data = get_byte(pb); - } - //printf("Descrambling: ps:%d cs:%d ds:%d s:%d sd:%d\n", - // asf_st->ds_packet_size, asf_st->ds_chunk_size, - // asf_st->ds_data_size, asf_st->ds_span, asf_st->ds_silence_data); - if (asf_st->ds_span > 1) { - if (!asf_st->ds_chunk_size - || (asf_st->ds_packet_size/asf_st->ds_chunk_size <= 1)) - asf_st->ds_span = 0; // disable descrambling - } - switch (st->codec.codec_id) { - case CODEC_ID_MP3LAME: - st->codec.frame_size = MPA_FRAME_SIZE; - break; - case CODEC_ID_PCM_S16LE: - case CODEC_ID_PCM_S16BE: - case CODEC_ID_PCM_U16LE: - case CODEC_ID_PCM_U16BE: - case CODEC_ID_PCM_S8: - case CODEC_ID_PCM_U8: - case CODEC_ID_PCM_ALAW: - case CODEC_ID_PCM_MULAW: - st->codec.frame_size = 1; - break; - default: - /* This is probably wrong, but it prevents a crash later */ - st->codec.frame_size = 1; - break; - } - } else { - get_le32(pb); - get_le32(pb); - get_byte(pb); - size = get_le16(pb); /* size */ - get_le32(pb); /* size */ - st->codec.width = get_le32(pb); - st->codec.height = get_le32(pb); - /* not available for asf */ - get_le16(pb); /* panes */ - get_le16(pb); /* depth */ - tag1 = get_le32(pb); - url_fskip(pb, 20); - if (size > 40) { - st->codec.extradata_size = size - 40; - st->codec.extradata = av_mallocz(st->codec.extradata_size); - get_buffer(pb, st->codec.extradata, st->codec.extradata_size); - } - st->codec.codec_tag = st->codec.fourcc = tag1; - st->codec.codec_id = codec_get_id(codec_bmp_tags, tag1); - } - pos2 = url_ftell(pb); - url_fskip(pb, gsize - (pos2 - pos1 + 24)); - } else if (!memcmp(&g, &data_header, sizeof(GUID))) { - break; - } else if (!memcmp(&g, &comment_header, sizeof(GUID))) { - int len1, len2, len3, len4, len5; - - len1 = get_le16(pb); - len2 = get_le16(pb); - len3 = get_le16(pb); - len4 = get_le16(pb); - len5 = get_le16(pb); - get_str16_nolen(pb, len1, s->title, sizeof(s->title)); - get_str16_nolen(pb, len2, s->author, sizeof(s->author)); - get_str16_nolen(pb, len3, s->copyright, sizeof(s->copyright)); - get_str16_nolen(pb, len4, s->comment, sizeof(s->comment)); - url_fskip(pb, len5); -#if 0 - } else if (!memcmp(&g, &head1_guid, sizeof(GUID))) { - int v1, v2; - get_guid(pb, &g); - v1 = get_le32(pb); - v2 = get_le16(pb); - } else if (!memcmp(&g, &codec_comment_header, sizeof(GUID))) { - int len, v1, n, num; - char str[256], *q; - char tag[16]; - - get_guid(pb, &g); - print_guid(&g); - - n = get_le32(pb); - for(i=0;i<n;i++) { - num = get_le16(pb); /* stream number */ - get_str16(pb, str, sizeof(str)); - get_str16(pb, str, sizeof(str)); - len = get_le16(pb); - q = tag; - while (len > 0) { - v1 = get_byte(pb); - if ((q - tag) < sizeof(tag) - 1) - *q++ = v1; - len--; - } - *q = '\0'; - } -#endif - } else if (url_feof(pb)) { - goto fail; - } else { - url_fseek(pb, gsize - 24, SEEK_CUR); - } - } - get_guid(pb, &g); - get_le64(pb); - get_byte(pb); - get_byte(pb); - if (url_feof(pb)) - goto fail; - asf->data_offset = url_ftell(pb); - asf->packet_size_left = 0; - - return 0; - - fail: - for(i=0;i<s->nb_streams;i++) { - AVStream *st = s->streams[i]; - if (st) { - av_free(st->priv_data); - av_free(st->codec.extradata); - } - av_free(st); - } - return -1; -} - -#define DO_2BITS(bits, var, defval) \ - switch (bits & 3) \ - { \ - case 3: var = get_le32(pb); rsize += 4; break; \ - case 2: var = get_le16(pb); rsize += 2; break; \ - case 1: var = get_byte(pb); rsize++; break; \ - default: var = defval; break; \ - } - -static int asf_get_packet(AVFormatContext *s) -{ - ASFContext *asf = s->priv_data; - ByteIOContext *pb = &s->pb; - uint32_t packet_length, padsize; - int rsize = 11; - int c = get_byte(pb); - if (c != 0x82) { - if (!url_feof(pb)) - printf("ff asf bad header %x at:%Ld\n", c, url_ftell(pb)); - return -EIO; - } - if ((c & 0x0f) == 2) { // always true for now - if (get_le16(pb) != 0) { - if (!url_feof(pb)) - printf("ff asf bad non zero\n"); - return -EIO; - } - } - - asf->packet_flags = get_byte(pb); - asf->packet_property = get_byte(pb); - - DO_2BITS(asf->packet_flags >> 5, packet_length, asf->packet_size); - DO_2BITS(asf->packet_flags >> 1, padsize, 0); // sequence ignored - DO_2BITS(asf->packet_flags >> 3, padsize, 0); // padding length - - asf->packet_timestamp = get_le32(pb); - get_le16(pb); /* duration */ - // rsize has at least 11 bytes which have to be present - - if (asf->packet_flags & 0x01) { - asf->packet_segsizetype = get_byte(pb); rsize++; - asf->packet_segments = asf->packet_segsizetype & 0x3f; - } else { - asf->packet_segments = 1; - asf->packet_segsizetype = 0x80; - } - asf->packet_size_left = packet_length - padsize - rsize; - if (packet_length < asf->hdr.min_pktsize) - padsize += asf->hdr.min_pktsize - packet_length; - asf->packet_padsize = padsize; -#ifdef DEBUG - printf("packet: size=%d padsize=%d left=%d\n", asf->packet_size, asf->packet_padsize, asf->packet_size_left); -#endif - return 0; -} - -static int asf_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - ASFContext *asf = s->priv_data; - ASFStream *asf_st = 0; - ByteIOContext *pb = &s->pb; - //static int pc = 0; - for (;;) { - int rsize = 0; - if (asf->packet_size_left < FRAME_HEADER_SIZE - || asf->packet_segments < 1) { - //asf->packet_size_left <= asf->packet_padsize) { - int ret = asf->packet_size_left + asf->packet_padsize; - //printf("PacketLeftSize:%d Pad:%d Pos:%Ld\n", asf->packet_size_left, asf->packet_padsize, url_ftell(pb)); - /* fail safe */ - url_fskip(pb, ret); - ret = asf_get_packet(s); - //printf("READ ASF PACKET %d r:%d c:%d\n", ret, asf->packet_size_left, pc++); - if (ret < 0 || url_feof(pb)) - return -EIO; - asf->packet_time_start = 0; - continue; - } - if (asf->packet_time_start == 0) { - /* read frame header */ - int num = get_byte(pb); - asf->packet_segments--; - rsize++; - asf->packet_key_frame = (num & 0x80) >> 7; - asf->stream_index = asf->asfid2avid[num & 0x7f]; - // sequence should be ignored! - DO_2BITS(asf->packet_property >> 4, asf->packet_seq, 0); - DO_2BITS(asf->packet_property >> 2, asf->packet_frag_offset, 0); - DO_2BITS(asf->packet_property, asf->packet_replic_size, 0); - - if (asf->packet_replic_size > 1) { - // it should be always at least 8 bytes - FIXME validate - asf->packet_obj_size = get_le32(pb); - asf->packet_frag_timestamp = get_le32(pb); // timestamp - if (asf->packet_replic_size > 8) - url_fskip(pb, asf->packet_replic_size - 8); - rsize += asf->packet_replic_size; // FIXME - check validity - } else { - // multipacket - frag_offset is begining timestamp - asf->packet_time_start = asf->packet_frag_offset; - asf->packet_frag_offset = 0; - asf->packet_frag_timestamp = asf->packet_timestamp; - - if (asf->packet_replic_size == 1) { - asf->packet_time_delta = get_byte(pb); - rsize++; - } - } - if (asf->packet_flags & 0x01) { - DO_2BITS(asf->packet_segsizetype >> 6, asf->packet_frag_size, 0); // 0 is illegal -#undef DO_2BITS - //printf("Fragsize %d\n", asf->packet_frag_size); - } else { - asf->packet_frag_size = asf->packet_size_left - rsize; - //printf("Using rest %d %d %d\n", asf->packet_frag_size, asf->packet_size_left, rsize); - } - if (asf->packet_replic_size == 1) { - asf->packet_multi_size = asf->packet_frag_size; - if (asf->packet_multi_size > asf->packet_size_left) { - asf->packet_segments = 0; - continue; - } - } - asf->packet_size_left -= rsize; - //printf("___objsize____ %d %d rs:%d\n", asf->packet_obj_size, asf->packet_frag_offset, rsize); - - if (asf->stream_index < 0) { - asf->packet_time_start = 0; - /* unhandled packet (should not happen) */ - url_fskip(pb, asf->packet_frag_size); - asf->packet_size_left -= asf->packet_frag_size; - printf("ff asf skip %d %d\n", asf->packet_frag_size, num & 0x7f); - continue; - } - asf->asf_st = s->streams[asf->stream_index]->priv_data; - } - asf_st = asf->asf_st; - - if ((asf->packet_frag_offset != asf_st->frag_offset - || (asf->packet_frag_offset - && asf->packet_seq != asf_st->seq)) // seq should be ignored - ) { - /* cannot continue current packet: free it */ - // FIXME better check if packet was already allocated - printf("ff asf parser skips: %d - %d o:%d - %d %d %d fl:%d\n", - asf_st->pkt.size, - asf->packet_obj_size, - asf->packet_frag_offset, asf_st->frag_offset, - asf->packet_seq, asf_st->seq, asf->packet_frag_size); - if (asf_st->pkt.size) - av_free_packet(&asf_st->pkt); - asf_st->frag_offset = 0; - if (asf->packet_frag_offset != 0) { - url_fskip(pb, asf->packet_frag_size); - printf("ff asf parser skiping %db\n", asf->packet_frag_size); - asf->packet_size_left -= asf->packet_frag_size; - continue; - } - } - if (asf->packet_replic_size == 1) { - // frag_offset is here used as the begining timestamp - asf->packet_frag_timestamp = asf->packet_time_start; - asf->packet_time_start += asf->packet_time_delta; - asf->packet_obj_size = asf->packet_frag_size = get_byte(pb); - asf->packet_size_left--; - asf->packet_multi_size--; - if (asf->packet_multi_size < asf->packet_obj_size) - { - asf->packet_time_start = 0; - url_fskip(pb, asf->packet_multi_size); - asf->packet_size_left -= asf->packet_multi_size; - continue; - } - asf->packet_multi_size -= asf->packet_obj_size; - //printf("COMPRESS size %d %d %d ms:%d\n", asf->packet_obj_size, asf->packet_frag_timestamp, asf->packet_size_left, asf->packet_multi_size); - } - if (asf_st->frag_offset == 0) { - /* new packet */ - av_new_packet(&asf_st->pkt, asf->packet_obj_size); - asf_st->seq = asf->packet_seq; - asf_st->pkt.pts = asf->packet_frag_timestamp - asf->hdr.preroll; - asf_st->pkt.stream_index = asf->stream_index; - if (asf->packet_key_frame) - asf_st->pkt.flags |= PKT_FLAG_KEY; - } - - /* read data */ - //printf("READ PACKET s:%d os:%d o:%d,%d l:%d DATA:%p\n", - // asf->packet_size, asf_st->pkt.size, asf->packet_frag_offset, - // asf_st->frag_offset, asf->packet_frag_size, asf_st->pkt.data); - asf->packet_size_left -= asf->packet_frag_size; - if (asf->packet_size_left < 0) - continue; - get_buffer(pb, asf_st->pkt.data + asf->packet_frag_offset, - asf->packet_frag_size); - asf_st->frag_offset += asf->packet_frag_size; - /* test if whole packet is read */ - if (asf_st->frag_offset == asf_st->pkt.size) { - /* return packet */ - if (asf_st->ds_span > 1) { - /* packet descrambling */ - char* newdata = av_malloc(asf_st->pkt.size); - if (newdata) { - int offset = 0; - while (offset < asf_st->pkt.size) { - int off = offset / asf_st->ds_chunk_size; - int row = off / asf_st->ds_span; - int col = off % asf_st->ds_span; - int idx = row + col * asf_st->ds_packet_size / asf_st->ds_chunk_size; - //printf("off:%d row:%d col:%d idx:%d\n", off, row, col, idx); - memcpy(newdata + offset, - asf_st->pkt.data + idx * asf_st->ds_chunk_size, - asf_st->ds_chunk_size); - offset += asf_st->ds_chunk_size; - } - av_free(asf_st->pkt.data); - asf_st->pkt.data = newdata; - } - } - asf_st->frag_offset = 0; - memcpy(pkt, &asf_st->pkt, sizeof(AVPacket)); - //printf("packet %d %d\n", asf_st->pkt.size, asf->packet_frag_size); - asf_st->pkt.size = 0; - asf_st->pkt.data = 0; - break; // packet completed - } - } - return 0; -} - -static int asf_read_close(AVFormatContext *s) -{ - int i; - - for(i=0;i<s->nb_streams;i++) { - AVStream *st = s->streams[i]; - av_free(st->priv_data); - av_free(st->codec.extradata); - } - return 0; -} - -static int asf_read_seek(AVFormatContext *s, int64_t pts) -{ - printf("SEEK TO %Ld", pts); - return -1; -} - -static AVInputFormat asf_iformat = { - "asf", - "asf format", - sizeof(ASFContext), - asf_probe, - asf_read_header, - asf_read_packet, - asf_read_close, - asf_read_seek, -}; - -static AVOutputFormat asf_oformat = { - "asf", - "asf format", - "application/octet-stream", - "asf,wmv", - sizeof(ASFContext), -#ifdef CONFIG_MP3LAME - CODEC_ID_MP3LAME, -#else - CODEC_ID_MP2, -#endif - CODEC_ID_MSMPEG4V3, - asf_write_header, - asf_write_packet, - asf_write_trailer, -}; - -static AVOutputFormat asf_stream_oformat = { - "asf_stream", - "asf format", - "application/octet-stream", - "asf,wmv", - sizeof(ASFContext), -#ifdef CONFIG_MP3LAME - CODEC_ID_MP3LAME, -#else - CODEC_ID_MP2, -#endif - CODEC_ID_MSMPEG4V3, - asf_write_stream_header, - asf_write_packet, - asf_write_trailer, -}; - -int asf_init(void) -{ - av_register_input_format(&asf_iformat); - av_register_output_format(&asf_oformat); - av_register_output_format(&asf_stream_oformat); - return 0; -} diff --git a/libav/au.c b/libav/au.c deleted file mode 100644 index 8c3d62a595..0000000000 --- a/libav/au.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * AU encoder and decoder - * Copyright (c) 2001 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ - -/* - * First version by Francois Revol revol@free.fr - * - * Reference documents: - * http://www.opengroup.org/public/pubs/external/auformat.html - * http://www.goice.co.jp/member/mo/formats/au.html - */ - -#include "avformat.h" -#include "avi.h" - -/* if we don't know the size in advance */ -#define AU_UNKOWN_SIZE ((UINT32)(~0)) - -/* The ffmpeg codecs we support, and the IDs they have in the file */ -static const CodecTag codec_au_tags[] = { - { CODEC_ID_PCM_MULAW, 1 }, - { CODEC_ID_PCM_S16BE, 3 }, - { CODEC_ID_PCM_ALAW, 27 }, - { 0, 0 }, -}; - -/* AUDIO_FILE header */ -static int put_au_header(ByteIOContext *pb, AVCodecContext *enc) -{ - int tag; - - tag = codec_get_tag(codec_au_tags, enc->codec_id); - if (tag == 0) - return -1; - put_tag(pb, ".snd"); /* magic number */ - put_be32(pb, 24); /* header size */ - put_be32(pb, AU_UNKOWN_SIZE); /* data size */ - put_be32(pb, (UINT32)tag); /* codec ID */ - put_be32(pb, enc->sample_rate); - put_be32(pb, (UINT32)enc->channels); - return 0; -} - -static int au_write_header(AVFormatContext *s) -{ - ByteIOContext *pb = &s->pb; - - s->priv_data = NULL; - - /* format header */ - if (put_au_header(pb, &s->streams[0]->codec) < 0) { - return -1; - } - - put_flush_packet(pb); - - return 0; -} - -static int au_write_packet(AVFormatContext *s, int stream_index_ptr, - UINT8 *buf, int size, int force_pts) -{ - ByteIOContext *pb = &s->pb; - put_buffer(pb, buf, size); - return 0; -} - -static int au_write_trailer(AVFormatContext *s) -{ - ByteIOContext *pb = &s->pb; - offset_t file_size; - - if (!url_is_streamed(&s->pb)) { - - /* update file size */ - file_size = url_ftell(pb); - url_fseek(pb, 8, SEEK_SET); - put_be32(pb, (UINT32)(file_size - 24)); - url_fseek(pb, file_size, SEEK_SET); - - put_flush_packet(pb); - } - - return 0; -} - -static int au_probe(AVProbeData *p) -{ - /* check file header */ - if (p->buf_size <= 24) - return 0; - if (p->buf[0] == '.' && p->buf[1] == 's' && - p->buf[2] == 'n' && p->buf[3] == 'd') - return AVPROBE_SCORE_MAX; - else - return 0; -} - -/* au input */ -static int au_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - int size; - unsigned int tag; - ByteIOContext *pb = &s->pb; - unsigned int id, codec, channels, rate; - AVStream *st; - - /* check ".snd" header */ - tag = get_le32(pb); - if (tag != MKTAG('.', 's', 'n', 'd')) - return -1; - size = get_be32(pb); /* header size */ - get_be32(pb); /* data size */ - - id = get_be32(pb); - rate = get_be32(pb); - channels = get_be32(pb); - - codec = codec_get_id(codec_au_tags, id); - - if (size >= 24) { - /* skip unused data */ - url_fseek(pb, size - 24, SEEK_CUR); - } - - /* now we are ready: build format streams */ - st = av_malloc(sizeof(AVStream)); - if (!st) - return -1; - s->nb_streams = 1; - s->streams[0] = st; - - st->id = 0; - - st->codec.codec_type = CODEC_TYPE_AUDIO; - st->codec.codec_tag = id; - st->codec.codec_id = codec; - st->codec.channels = channels; - st->codec.sample_rate = rate; - return 0; -} - -#define MAX_SIZE 4096 - -static int au_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - int ret; - - if (url_feof(&s->pb)) - return -EIO; - if (av_new_packet(pkt, MAX_SIZE)) - return -EIO; - pkt->stream_index = 0; - - ret = get_buffer(&s->pb, pkt->data, pkt->size); - if (ret < 0) - av_free_packet(pkt); - /* note: we need to modify the packet size here to handle the last - packet */ - pkt->size = ret; - return 0; -} - -static int au_read_close(AVFormatContext *s) -{ - return 0; -} - -static AVInputFormat au_iformat = { - "au", - "SUN AU Format", - 0, - au_probe, - au_read_header, - au_read_packet, - au_read_close, -}; - -static AVOutputFormat au_oformat = { - "au", - "SUN AU Format", - "audio/basic", - "au", - 0, - CODEC_ID_PCM_S16BE, - CODEC_ID_NONE, - au_write_header, - au_write_packet, - au_write_trailer, -}; - -int au_init(void) -{ - av_register_input_format(&au_iformat); - av_register_output_format(&au_oformat); - return 0; -} diff --git a/libav/audio.c b/libav/audio.c deleted file mode 100644 index 4fa155c85d..0000000000 --- a/libav/audio.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Linux audio play and grab interface - * Copyright (c) 2000, 2001 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <sys/soundcard.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <sys/time.h> - -const char *audio_device = "/dev/dsp"; - -#define AUDIO_BLOCK_SIZE 4096 - -typedef struct { - int fd; - int sample_rate; - int channels; - int frame_size; /* in bytes ! */ - int codec_id; - int flip_left : 1; - UINT8 buffer[AUDIO_BLOCK_SIZE]; - int buffer_ptr; -} AudioData; - -static int audio_open(AudioData *s, int is_output) -{ - int audio_fd; - int tmp, err; - char *flip = getenv("AUDIO_FLIP_LEFT"); - - /* open linux audio device */ - if (is_output) - audio_fd = open(audio_device, O_WRONLY); - else - audio_fd = open(audio_device, O_RDONLY); - if (audio_fd < 0) { - perror(audio_device); - return -EIO; - } - - if (flip && *flip == '1') { - s->flip_left = 1; - } - - /* non blocking mode */ - if (!is_output) - fcntl(audio_fd, F_SETFL, O_NONBLOCK); - - s->frame_size = AUDIO_BLOCK_SIZE; -#if 0 - tmp = (NB_FRAGMENTS << 16) | FRAGMENT_BITS; - err = ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &tmp); - if (err < 0) { - perror("SNDCTL_DSP_SETFRAGMENT"); - } -#endif - - /* select format : favour native format */ - err = ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &tmp); - -#ifdef WORDS_BIGENDIAN - if (tmp & AFMT_S16_BE) { - tmp = AFMT_S16_BE; - } else if (tmp & AFMT_S16_LE) { - tmp = AFMT_S16_LE; - } else { - tmp = 0; - } -#else - if (tmp & AFMT_S16_LE) { - tmp = AFMT_S16_LE; - } else if (tmp & AFMT_S16_BE) { - tmp = AFMT_S16_BE; - } else { - tmp = 0; - } -#endif - - switch(tmp) { - case AFMT_S16_LE: - s->codec_id = CODEC_ID_PCM_S16LE; - break; - case AFMT_S16_BE: - s->codec_id = CODEC_ID_PCM_S16BE; - break; - default: - fprintf(stderr, "Soundcard does not support 16 bit sample format\n"); - close(audio_fd); - return -EIO; - } - err=ioctl(audio_fd, SNDCTL_DSP_SETFMT, &tmp); - if (err < 0) { - perror("SNDCTL_DSP_SETFMT"); - goto fail; - } - - tmp = (s->channels == 2); - err = ioctl(audio_fd, SNDCTL_DSP_STEREO, &tmp); - if (err < 0) { - perror("SNDCTL_DSP_STEREO"); - goto fail; - } - if (tmp) - s->channels = 2; - - tmp = s->sample_rate; - err = ioctl(audio_fd, SNDCTL_DSP_SPEED, &tmp); - if (err < 0) { - perror("SNDCTL_DSP_SPEED"); - goto fail; - } - s->sample_rate = tmp; /* store real sample rate */ - s->fd = audio_fd; - - return 0; - fail: - close(audio_fd); - return -EIO; -} - -static int audio_close(AudioData *s) -{ - close(s->fd); - return 0; -} - -/* sound output support */ -static int audio_write_header(AVFormatContext *s1) -{ - AudioData *s = s1->priv_data; - AVStream *st; - int ret; - - st = s1->streams[0]; - s->sample_rate = st->codec.sample_rate; - s->channels = st->codec.channels; - ret = audio_open(s, 1); - if (ret < 0) { - return -EIO; - } else { - return 0; - } -} - -static int audio_write_packet(AVFormatContext *s1, int stream_index, - UINT8 *buf, int size, int force_pts) -{ - AudioData *s = s1->priv_data; - int len, ret; - - while (size > 0) { - len = AUDIO_BLOCK_SIZE - s->buffer_ptr; - if (len > size) - len = size; - memcpy(s->buffer + s->buffer_ptr, buf, len); - s->buffer_ptr += len; - if (s->buffer_ptr >= AUDIO_BLOCK_SIZE) { - for(;;) { - ret = write(s->fd, s->buffer, AUDIO_BLOCK_SIZE); - if (ret > 0) - break; - if (ret < 0 && (errno != EAGAIN && errno != EINTR)) - return -EIO; - } - s->buffer_ptr = 0; - } - buf += len; - size -= len; - } - return 0; -} - -static int audio_write_trailer(AVFormatContext *s1) -{ - AudioData *s = s1->priv_data; - - audio_close(s); - return 0; -} - -/* grab support */ - -static int audio_read_header(AVFormatContext *s1, AVFormatParameters *ap) -{ - AudioData *s = s1->priv_data; - AVStream *st; - int ret; - - if (!ap || ap->sample_rate <= 0 || ap->channels <= 0) - return -1; - - st = av_new_stream(s1, 0); - if (!st) { - return -ENOMEM; - } - s->sample_rate = ap->sample_rate; - s->channels = ap->channels; - - ret = audio_open(s, 0); - if (ret < 0) { - av_free(st); - return -EIO; - } - - /* take real parameters */ - st->codec.codec_type = CODEC_TYPE_AUDIO; - st->codec.codec_id = s->codec_id; - st->codec.sample_rate = s->sample_rate; - st->codec.channels = s->channels; - - av_set_pts_info(s1, 48, 1, 1000000); /* 48 bits pts in us */ - return 0; -} - -static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt) -{ - AudioData *s = s1->priv_data; - int ret, bdelay; - int64_t cur_time; - struct audio_buf_info abufi; - - if (av_new_packet(pkt, s->frame_size) < 0) - return -EIO; - for(;;) { - ret = read(s->fd, pkt->data, pkt->size); - if (ret > 0) - break; - if (ret == -1 && (errno == EAGAIN || errno == EINTR)) { - av_free_packet(pkt); - pkt->size = 0; - return 0; - } - if (!(ret == 0 || (ret == -1 && (errno == EAGAIN || errno == EINTR)))) { - av_free_packet(pkt); - return -EIO; - } - } - pkt->size = ret; - - /* compute pts of the start of the packet */ - cur_time = av_gettime(); - bdelay = ret; - if (ioctl(s->fd, SNDCTL_DSP_GETISPACE, &abufi) == 0) { - bdelay += abufi.bytes; - } - /* substract time represented by the number of bytes in the audio fifo */ - cur_time -= (bdelay * 1000000LL) / (s->sample_rate * s->channels); - - /* convert to wanted units */ - pkt->pts = cur_time & ((1LL << 48) - 1); - - if (s->flip_left && s->channels == 2) { - int i; - short *p = (short *) pkt->data; - - for (i = 0; i < ret; i += 4) { - *p = ~*p; - p += 2; - } - } - return 0; -} - -static int audio_read_close(AVFormatContext *s1) -{ - AudioData *s = s1->priv_data; - - audio_close(s); - return 0; -} - -static AVInputFormat audio_in_format = { - "audio_device", - "audio grab and output", - sizeof(AudioData), - NULL, - audio_read_header, - audio_read_packet, - audio_read_close, - .flags = AVFMT_NOFILE, -}; - -static AVOutputFormat audio_out_format = { - "audio_device", - "audio grab and output", - "", - "", - sizeof(AudioData), - /* XXX: we make the assumption that the soundcard accepts this format */ - /* XXX: find better solution with "preinit" method, needed also in - other formats */ -#ifdef WORDS_BIGENDIAN - CODEC_ID_PCM_S16BE, -#else - CODEC_ID_PCM_S16LE, -#endif - CODEC_ID_NONE, - audio_write_header, - audio_write_packet, - audio_write_trailer, - .flags = AVFMT_NOFILE, -}; - -int audio_init(void) -{ - av_register_input_format(&audio_in_format); - av_register_output_format(&audio_out_format); - return 0; -} diff --git a/libav/avformat.h b/libav/avformat.h deleted file mode 100644 index 0ea10f7dfe..0000000000 --- a/libav/avformat.h +++ /dev/null @@ -1,351 +0,0 @@ -#ifndef AVFORMAT_H -#define AVFORMAT_H - -#define LIBAVFORMAT_VERSION_INT 0x000406 -#define LIBAVFORMAT_VERSION "0.4.6" -#define LIBAVFORMAT_BUILD 4602 - -#include "avcodec.h" - -#include "avio.h" - -/* packet functions */ - -#define AV_NOPTS_VALUE 0 - -typedef struct AVPacket { - INT64 pts; /* presentation time stamp in stream units (set av_set_pts_info) */ - UINT8 *data; - int size; - int stream_index; - int flags; - int duration; -#define PKT_FLAG_KEY 0x0001 -} AVPacket; - -int av_new_packet(AVPacket *pkt, int size); -void av_free_packet(AVPacket *pkt); - -/*************************************************/ -/* fractional numbers for exact pts handling */ - -/* the exact value of the fractional number is: 'val + num / den'. num - is assumed to be such as 0 <= num < den */ -typedef struct AVFrac { - INT64 val, num, den; -} AVFrac; - -void av_frac_init(AVFrac *f, INT64 val, INT64 num, INT64 den); -void av_frac_add(AVFrac *f, INT64 incr); -void av_frac_set(AVFrac *f, INT64 val); - -/*************************************************/ -/* input/output formats */ - -struct AVFormatContext; - -/* this structure contains the data a format has to probe a file */ -typedef struct AVProbeData { - char *filename; - unsigned char *buf; - int buf_size; -} AVProbeData; - -#define AVPROBE_SCORE_MAX 100 - -typedef struct AVFormatParameters { - int frame_rate; - int sample_rate; - int channels; - int width; - int height; - enum PixelFormat pix_fmt; -} AVFormatParameters; - -#define AVFMT_NOFILE 0x0001 /* no file should be opened */ -#define AVFMT_NEEDNUMBER 0x0002 /* needs '%d' in filename */ -#define AVFMT_NOHEADER 0x0004 /* signal that no header is present - (streams are added dynamically) */ -#define AVFMT_SHOW_IDS 0x0008 /* show format stream IDs numbers */ -#define AVFMT_RGB24 0x0010 /* force RGB24 output for ppm (hack - - need better api) */ -#define AVFMT_RAWPICTURE 0x0020 /* format wants AVPicture structure for - raw picture data */ - -typedef struct AVOutputFormat { - const char *name; - const char *long_name; - const char *mime_type; - const char *extensions; /* comma separated extensions */ - /* size of private data so that it can be allocated in the wrapper */ - int priv_data_size; - /* output support */ - enum CodecID audio_codec; /* default audio codec */ - enum CodecID video_codec; /* default video codec */ - int (*write_header)(struct AVFormatContext *); - /* XXX: change prototype for 64 bit pts */ - int (*write_packet)(struct AVFormatContext *, - int stream_index, - unsigned char *buf, int size, int force_pts); - int (*write_trailer)(struct AVFormatContext *); - /* can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER */ - int flags; - /* private fields */ - struct AVOutputFormat *next; -} AVOutputFormat; - -typedef struct AVInputFormat { - const char *name; - const char *long_name; - /* size of private data so that it can be allocated in the wrapper */ - int priv_data_size; - /* tell if a given file has a chance of being parsing by this format */ - int (*read_probe)(AVProbeData *); - /* read the format header and initialize the AVFormatContext - structure. Return 0 if OK. 'ap' if non NULL contains - additionnal paramters. Only used in raw format right - now. 'av_new_stream' should be called to create new streams. */ - int (*read_header)(struct AVFormatContext *, - AVFormatParameters *ap); - /* read one packet and put it in 'pkt'. pts and flags are also - set. 'av_new_stream' can be called only if the flag - AVFMT_NOHEADER is used. */ - 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); - /* can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_NOHEADER */ - int flags; - /* if extensions are defined, then no probe is done. You should - usually not use extension format guessing because it is not - reliable enough */ - const char *extensions; - /* general purpose read only value that the format can use */ - int value; - /* private fields */ - struct AVInputFormat *next; -} AVInputFormat; - -typedef struct AVStream { - int index; /* stream index in AVFormatContext */ - int id; /* format specific stream id */ - AVCodecContext codec; /* codec context */ - int r_frame_rate; /* real frame rate of the stream */ - uint64_t time_length; /* real length of the stream in miliseconds */ - void *priv_data; - /* internal data used in av_find_stream_info() */ - int codec_info_state; - int codec_info_nb_repeat_frames; - int codec_info_nb_real_frames; - /* PTS generation when outputing stream */ - AVFrac pts; - /* ffmpeg.c private use */ - int stream_copy; /* if TRUE, just copy stream */ -} AVStream; - -#define MAX_STREAMS 20 - -/* format I/O context */ -typedef struct AVFormatContext { - /* can only be iformat or oformat, not both at the same time */ - struct AVInputFormat *iformat; - struct AVOutputFormat *oformat; - 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]; - int flags; /* format specific flags */ - /* private data for pts handling (do not modify directly) */ - int pts_wrap_bits; /* number of bits in pts (used for wrapping control) */ - int pts_num, pts_den; /* value to convert to seconds */ - /* 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 AVInputFormat *first_iformat; -extern AVOutputFormat *first_oformat; - -/* XXX: use automatic init with either ELF sections or C file parser */ -/* modules */ - -/* mpeg.c */ -int mpegps_init(void); - -/* mpegts.c */ -extern AVInputFormat mpegts_demux; -int mpegts_init(void); - -/* rm.c */ -int rm_init(void); - -/* crc.c */ -int crc_init(void); - -/* img.c */ -int img_init(void); - -/* asf.c */ -int asf_init(void); - -/* avienc.c */ -int avienc_init(void); - -/* avidec.c */ -int avidec_init(void); - -/* swf.c */ -int swf_init(void); - -/* mov.c */ -int mov_init(void); - -/* jpeg.c */ -int jpeg_init(void); - -/* gif.c */ -int gif_init(void); - -/* au.c */ -int au_init(void); - -/* wav.c */ -int wav_init(void); - -/* raw.c */ -int raw_init(void); - -/* ogg.c */ -int ogg_init(void); - -/* dv.c */ -int dv_init(void); - -/* ffm.c */ -int ffm_init(void); - -/* rtsp.c */ -extern AVInputFormat redir_demux; -int redir_open(AVFormatContext **ic_ptr, ByteIOContext *f); - -#include "rtp.h" - -#include "rtsp.h" - -/* utils.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 av_register_input_format(AVInputFormat *format); -void av_register_output_format(AVOutputFormat *format); -AVOutputFormat *guess_stream_format(const char *short_name, - const char *filename, const char *mime_type); -AVOutputFormat *guess_format(const char *short_name, - const char *filename, const char *mime_type); - -void av_hex_dump(UINT8 *buf, int size); - -void av_register_all(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); - -/* media file input */ -AVInputFormat *av_find_input_format(const char *short_name); -AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened); -int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, - AVInputFormat *fmt, - int buf_size, - AVFormatParameters *ap); - -#define AVERROR_UNKNOWN (-1) /* unknown error */ -#define AVERROR_IO (-2) /* i/o error */ -#define AVERROR_NUMEXPECTED (-3) /* number syntax expected in filename */ -#define AVERROR_INVALIDDATA (-4) /* invalid data found */ -#define AVERROR_NOMEM (-5) /* not enough memory */ -#define AVERROR_NOFMT (-6) /* unknown format */ - -int av_find_stream_info(AVFormatContext *ic); -int av_read_packet(AVFormatContext *s, AVPacket *pkt); -void av_close_input_file(AVFormatContext *s); -AVStream *av_new_stream(AVFormatContext *s, int id); -void av_set_pts_info(AVFormatContext *s, int pts_wrap_bits, - int pts_num, int pts_den); - -/* media file output */ -int av_write_header(AVFormatContext *s); -int av_write_frame(AVFormatContext *s, int stream_index, const uint8_t *buf, - int size); -int av_write_trailer(AVFormatContext *s); - -void dump_format(AVFormatContext *ic, - int index, - const char *url, - int is_output); -int parse_image_size(int *width_ptr, int *height_ptr, const char *str); -INT64 parse_date(const char *datestr, int duration); - -INT64 av_gettime(void); - -/* ffm specific for ffserver */ -#define FFM_PACKET_SIZE 4096 -offset_t ffm_read_write_index(int fd); -void ffm_write_write_index(int fd, offset_t pos); -void ffm_set_write_index(AVFormatContext *s, offset_t pos, offset_t file_size); - -int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info); - -int get_frame_filename(char *buf, int buf_size, - const char *path, int number); -int filename_number_test(const char *filename); - -/* grab specific */ -int video_grab_init(void); -int audio_init(void); - -extern const char *v4l_device; -extern const char *audio_device; - -#ifdef HAVE_AV_CONFIG_H -int strstart(const char *str, const char *val, const char **ptr); -int stristart(const char *str, const char *val, const char **ptr); -void pstrcpy(char *buf, int buf_size, const char *str); -char *pstrcat(char *buf, int buf_size, const char *s); - -struct in_addr; -int resolve_host(struct in_addr *sin_addr, const char *hostname); - -void url_split(char *proto, int proto_size, - char *hostname, int hostname_size, - int *port_ptr, - char *path, int path_size, - const char *url); - -int match_ext(const char *filename, const char *extensions); - -#endif /* HAVE_AV_CONFIG_H */ - -#endif /* AVFORMAT_H */ diff --git a/libav/avi.h b/libav/avi.h deleted file mode 100644 index d1b5eb5789..0000000000 --- a/libav/avi.h +++ /dev/null @@ -1,28 +0,0 @@ - -#define AVIF_HASINDEX 0x00000010 // Index at end of file? -#define AVIF_MUSTUSEINDEX 0x00000020 -#define AVIF_ISINTERLEAVED 0x00000100 -#define AVIF_TRUSTCKTYPE 0x00000800 // Use CKType to find key frames? -#define AVIF_WASCAPTUREFILE 0x00010000 -#define AVIF_COPYRIGHTED 0x00020000 - -offset_t start_tag(ByteIOContext *pb, const char *tag); -void end_tag(ByteIOContext *pb, offset_t start); - -typedef struct CodecTag { - int id; - unsigned int tag; - unsigned int invalid_asf : 1; -} CodecTag; - -void put_bmp_header(ByteIOContext *pb, AVCodecContext *enc, const CodecTag *tags, int for_asf); -int put_wav_header(ByteIOContext *pb, AVCodecContext *enc); -int wav_codec_get_id(unsigned int tag, int bps); -void get_wav_header(ByteIOContext *pb, AVCodecContext *codec, - int has_extra_data); - -extern const CodecTag codec_bmp_tags[]; -extern const CodecTag codec_wav_tags[]; - -unsigned int codec_get_tag(const CodecTag *tags, int id); -int codec_get_id(const CodecTag *tags, unsigned int tag); diff --git a/libav/avidec.c b/libav/avidec.c deleted file mode 100644 index 9646408cd1..0000000000 --- a/libav/avidec.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * AVI decoder. - * Copyright (c) 2001 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" -#include "avi.h" - -//#define DEBUG - -typedef struct AVIIndex { - unsigned char tag[4]; - unsigned int flags, pos, len; - struct AVIIndex *next; -} AVIIndex; - -typedef struct { - INT64 movi_end; - offset_t movi_list; - AVIIndex *first, *last; -} AVIContext; - -#ifdef DEBUG -static void print_tag(const char *str, unsigned int tag, int size) -{ - printf("%s: tag=%c%c%c%c size=0x%x\n", - str, tag & 0xff, - (tag >> 8) & 0xff, - (tag >> 16) & 0xff, - (tag >> 24) & 0xff, - size); -} -#endif - -static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - AVIContext *avi = s->priv_data; - ByteIOContext *pb = &s->pb; - UINT32 tag, tag1; - int codec_type, stream_index, size, frame_period, bit_rate; - int i; - AVStream *st; - - /* check RIFF header */ - tag = get_le32(pb); - - if (tag != MKTAG('R', 'I', 'F', 'F')) - return -1; - get_le32(pb); /* file size */ - tag = get_le32(pb); - if (tag != MKTAG('A', 'V', 'I', ' ')) - return -1; - - /* first list tag */ - stream_index = -1; - codec_type = -1; - frame_period = 0; - for(;;) { - if (url_feof(pb)) - goto fail; - tag = get_le32(pb); - size = get_le32(pb); -#ifdef DEBUG - print_tag("tag", tag, size); -#endif - - switch(tag) { - case MKTAG('L', 'I', 'S', 'T'): - /* ignored, except when start of video packets */ - tag1 = get_le32(pb); -#ifdef DEBUG - print_tag("list", tag1, 0); -#endif - if (tag1 == MKTAG('m', 'o', 'v', 'i')) { - avi->movi_end = url_ftell(pb) + size - 4; -#ifdef DEBUG - printf("movi end=%Lx\n", avi->movi_end); -#endif - goto end_of_header; - } - break; - case MKTAG('a', 'v', 'i', 'h'): - /* avi header */ - /* using frame_period is bad idea */ - frame_period = get_le32(pb); - bit_rate = get_le32(pb) * 8; - url_fskip(pb, 4 * 4); - s->nb_streams = get_le32(pb); - for(i=0;i<s->nb_streams;i++) { - AVStream *st = av_mallocz(sizeof(AVStream)); - if (!st) - goto fail; - s->streams[i] = st; - } - url_fskip(pb, size - 7 * 4); - break; - case MKTAG('s', 't', 'r', 'h'): - /* stream header */ - stream_index++; - tag1 = get_le32(pb); - switch(tag1) { - case MKTAG('v', 'i', 'd', 's'): - codec_type = CODEC_TYPE_VIDEO; - get_le32(pb); /* codec tag */ - get_le32(pb); /* flags */ - get_le16(pb); /* priority */ - get_le16(pb); /* language */ - get_le32(pb); /* XXX: initial frame ? */ - get_le32(pb); /* scale */ - get_le32(pb); /* rate */ - size -= 6 * 4; - break; - case MKTAG('a', 'u', 'd', 's'): - codec_type = CODEC_TYPE_AUDIO; - /* nothing really useful */ - } - url_fskip(pb, size - 4); - break; - case MKTAG('s', 't', 'r', 'f'): - /* stream header */ - if (stream_index >= s->nb_streams) { - url_fskip(pb, size); - } else { - st = s->streams[stream_index]; - switch(codec_type) { - case CODEC_TYPE_VIDEO: - get_le32(pb); /* size */ - st->codec.width = get_le32(pb); - st->codec.height = get_le32(pb); - if (frame_period) - st->codec.frame_rate = (INT64_C(1000000) * FRAME_RATE_BASE) / frame_period; - else - st->codec.frame_rate = 25 * FRAME_RATE_BASE; - get_le16(pb); /* panes */ - get_le16(pb); /* depth */ - tag1 = get_le32(pb); -#ifdef DEBUG - print_tag("video", tag1, 0); -#endif - st->codec.codec_type = CODEC_TYPE_VIDEO; - st->codec.codec_tag = tag1; - st->codec.codec_id = codec_get_id(codec_bmp_tags, tag1); - url_fskip(pb, size - 5 * 4); - break; - case CODEC_TYPE_AUDIO: - get_wav_header(pb, &st->codec, (size >= 18)); - break; - default: - url_fskip(pb, size); - break; - } - } - break; - default: - /* skip tag */ - size += (size & 1); - url_fskip(pb, size); - break; - } - } - end_of_header: - /* check stream number */ - if (stream_index != s->nb_streams - 1) { - fail: - for(i=0;i<s->nb_streams;i++) { - av_freep(&s->streams[i]); - } - return -1; - } - - return 0; -} - -static int avi_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - AVIContext *avi = s->priv_data; - ByteIOContext *pb = &s->pb; - int n, d1, d2, size; - - for(;;) { - if (url_feof(pb) || url_ftell(pb) >= avi->movi_end) - return -1; - d1 = get_byte(pb) - '0'; - d2 = get_byte(pb) - '0'; - if (d1 < 0 || d1 > 9 || d2 < 0 || d2 > 9) - continue; - - n = d1 * 10 + d2; - if (n < 0 || n >= s->nb_streams) - continue; - - d1 = get_byte(pb); - d2 = get_byte(pb); - if ((d1 == 'd' && d2 == 'c') - || (d1 == 'w' && d2 == 'b')) - break; - } - size = get_le32(pb); - av_new_packet(pkt, size); - pkt->stream_index = n; - - get_buffer(pb, pkt->data, pkt->size); - - if (size & 1) - get_byte(pb); - - return 0; -} - -static int avi_read_close(AVFormatContext *s) -{ - return 0; -} - -static int avi_probe(AVProbeData *p) -{ - /* check file header */ - if (p->buf_size <= 32) - return 0; - if (p->buf[0] == 'R' && p->buf[1] == 'I' && - p->buf[2] == 'F' && p->buf[3] == 'F' && - p->buf[8] == 'A' && p->buf[9] == 'V' && - p->buf[10] == 'I' && p->buf[11] == ' ') - return AVPROBE_SCORE_MAX; - else - return 0; -} - -static AVInputFormat avi_iformat = { - "avi", - "avi format", - sizeof(AVIContext), - avi_probe, - avi_read_header, - avi_read_packet, - avi_read_close, -}; - -int avidec_init(void) -{ - av_register_input_format(&avi_iformat); - return 0; -} diff --git a/libav/avienc.c b/libav/avienc.c deleted file mode 100644 index b4298b0b39..0000000000 --- a/libav/avienc.c +++ /dev/null @@ -1,432 +0,0 @@ -/* - * AVI encoder. - * Copyright (c) 2000 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" -#include "avi.h" - -/* - * TODO: - * - fill all fields if non streamed (nb_frames for example) - */ - -typedef struct AVIIndex { - unsigned char tag[4]; - unsigned int flags, pos, len; - struct AVIIndex *next; -} AVIIndex; - -typedef struct { - offset_t movi_list, frames_hdr_all, frames_hdr_strm[MAX_STREAMS]; - int audio_strm_length[MAX_STREAMS]; - AVIIndex *first, *last; -} AVIContext; - -offset_t start_tag(ByteIOContext *pb, const char *tag) -{ - put_tag(pb, tag); - put_le32(pb, 0); - return url_ftell(pb); -} - -void end_tag(ByteIOContext *pb, offset_t start) -{ - offset_t pos; - - pos = url_ftell(pb); - url_fseek(pb, start - 4, SEEK_SET); - put_le32(pb, (UINT32)(pos - start)); - url_fseek(pb, pos, SEEK_SET); -} - -/* Note: when encoding, the first matching tag is used, so order is - important if multiple tags possible for a given codec. */ -const CodecTag codec_bmp_tags[] = { - { CODEC_ID_H263, MKTAG('H', '2', '6', '3') }, - { CODEC_ID_H263P, MKTAG('H', '2', '6', '3') }, - { CODEC_ID_H263I, MKTAG('I', '2', '6', '3') }, /* intel h263 */ - { CODEC_ID_MJPEG, MKTAG('M', 'J', 'P', 'G') }, - { CODEC_ID_MPEG4, MKTAG('D', 'I', 'V', 'X'), .invalid_asf = 1 }, - { CODEC_ID_MPEG4, MKTAG('d', 'i', 'v', 'x'), .invalid_asf = 1 }, - { CODEC_ID_MPEG4, MKTAG('D', 'X', '5', '0'), .invalid_asf = 1 }, - { CODEC_ID_MPEG4, MKTAG('X', 'V', 'I', 'D'), .invalid_asf = 1 }, - { CODEC_ID_MPEG4, MKTAG('x', 'v', 'i', 'd'), .invalid_asf = 1 }, - { CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 's'), .invalid_asf = 1 }, - { CODEC_ID_MPEG4, MKTAG('M', 'P', '4', 'S') }, - { CODEC_ID_MPEG4, MKTAG('M', '4', 'S', '2') }, - { CODEC_ID_MPEG4, MKTAG('m', '4', 's', '2') }, - { CODEC_ID_MPEG4, MKTAG(0x04, 0, 0, 0) }, /* some broken avi use this */ - { CODEC_ID_MSMPEG4V3, MKTAG('D', 'I', 'V', '3'), .invalid_asf = 1 }, /* default signature when using MSMPEG4 */ - { CODEC_ID_MSMPEG4V3, MKTAG('d', 'i', 'v', '3'), .invalid_asf = 1 }, - { CODEC_ID_MSMPEG4V3, MKTAG('M', 'P', '4', '3') }, - { CODEC_ID_MSMPEG4V2, MKTAG('M', 'P', '4', '2') }, - { CODEC_ID_MSMPEG4V1, MKTAG('M', 'P', 'G', '4') }, - { CODEC_ID_WMV1, MKTAG('W', 'M', 'V', '1') }, - { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 's', 'l') }, - { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 's', 'd') }, - { CODEC_ID_DVVIDEO, MKTAG('D', 'V', 'S', 'D') }, - { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', 'd') }, - { CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'g', '1') }, - { CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'g', '2') }, - { CODEC_ID_MPEG1VIDEO, MKTAG('P', 'I', 'M', '1') }, - { CODEC_ID_MJPEG, MKTAG('M', 'J', 'P', 'G') }, - { 0, 0 }, -}; - -unsigned int codec_get_tag(const CodecTag *tags, int id) -{ - while (tags->id != 0) { - if (tags->id == id) - return tags->tag; - tags++; - } - return 0; -} - -static unsigned int codec_get_asf_tag(const CodecTag *tags, int id) -{ - while (tags->id != 0) { - if (!tags->invalid_asf && tags->id == id) - return tags->tag; - tags++; - } - return 0; -} - -int codec_get_id(const CodecTag *tags, unsigned int tag) -{ - while (tags->id != 0) { - if (tags->tag == tag) - return tags->id; - tags++; - } - return 0; -} - -unsigned int codec_get_bmp_tag(int id) -{ - return codec_get_tag(codec_bmp_tags, id); -} - -/* BITMAPINFOHEADER header */ -void put_bmp_header(ByteIOContext *pb, AVCodecContext *enc, const CodecTag *tags, int for_asf) -{ - put_le32(pb, 40); /* size */ - put_le32(pb, enc->width); - put_le32(pb, enc->height); - put_le16(pb, 1); /* planes */ - put_le16(pb, 24); /* depth */ - /* compression type */ - put_le32(pb, for_asf ? codec_get_asf_tag(tags, enc->codec_id) : codec_get_tag(tags, enc->codec_id)); - put_le32(pb, enc->width * enc->height * 3); - put_le32(pb, 0); - put_le32(pb, 0); - put_le32(pb, 0); - put_le32(pb, 0); -} - -static void parse_specific_params(AVCodecContext *stream, int *au_byterate, int *au_ssize, int *au_scale) -{ - switch(stream->codec_id) { - case CODEC_ID_PCM_S16LE: - *au_scale = *au_ssize = 2*stream->channels; - *au_byterate = *au_ssize * stream->sample_rate; - break; - case CODEC_ID_PCM_U8: - case CODEC_ID_PCM_ALAW: - case CODEC_ID_PCM_MULAW: - *au_scale = *au_ssize = stream->channels; - *au_byterate = *au_ssize * stream->sample_rate; - break; - case CODEC_ID_MP2: - *au_ssize = 1; - *au_scale = 1; - *au_byterate = stream->bit_rate / 8; - case CODEC_ID_MP3LAME: - *au_ssize = 1; - *au_scale = 1; - *au_byterate = stream->bit_rate / 8; - default: - *au_ssize = 1; - *au_scale = 1; - *au_byterate = stream->bit_rate / 8; - break; - } -} - -static int avi_write_header(AVFormatContext *s) -{ - AVIContext *avi = s->priv_data; - ByteIOContext *pb = &s->pb; - int bitrate, n, i, nb_frames, au_byterate, au_ssize, au_scale; - AVCodecContext *stream, *video_enc; - offset_t list1, list2, strh, strf; - - put_tag(pb, "RIFF"); - put_le32(pb, 0); /* file length */ - put_tag(pb, "AVI "); - - /* header list */ - list1 = start_tag(pb, "LIST"); - put_tag(pb, "hdrl"); - - /* avi header */ - put_tag(pb, "avih"); - put_le32(pb, 14 * 4); - bitrate = 0; - - video_enc = NULL; - for(n=0;n<s->nb_streams;n++) { - stream = &s->streams[n]->codec; - bitrate += stream->bit_rate; - if (stream->codec_type == CODEC_TYPE_VIDEO) - video_enc = stream; - } - - if (!video_enc) { - av_free(avi); - return -1; - } - nb_frames = 0; - - put_le32(pb, (UINT32)(INT64_C(1000000) * FRAME_RATE_BASE / video_enc->frame_rate)); - put_le32(pb, bitrate / 8); /* XXX: not quite exact */ - put_le32(pb, 0); /* padding */ - put_le32(pb, AVIF_TRUSTCKTYPE | AVIF_HASINDEX | AVIF_ISINTERLEAVED); /* flags */ - avi->frames_hdr_all = url_ftell(pb); /* remember this offset to fill later */ - put_le32(pb, nb_frames); /* nb frames, filled later */ - put_le32(pb, 0); /* initial frame */ - put_le32(pb, s->nb_streams); /* nb streams */ - put_le32(pb, 1024 * 1024); /* suggested buffer size */ - put_le32(pb, video_enc->width); - put_le32(pb, video_enc->height); - put_le32(pb, 0); /* reserved */ - put_le32(pb, 0); /* reserved */ - put_le32(pb, 0); /* reserved */ - put_le32(pb, 0); /* reserved */ - - /* stream list */ - for(i=0;i<n;i++) { - list2 = start_tag(pb, "LIST"); - put_tag(pb, "strl"); - - stream = &s->streams[i]->codec; - - /* stream generic header */ - strh = start_tag(pb, "strh"); - switch(stream->codec_type) { - case CODEC_TYPE_VIDEO: - put_tag(pb, "vids"); - put_le32(pb, codec_get_bmp_tag(stream->codec_id)); - put_le32(pb, 0); /* flags */ - put_le16(pb, 0); /* priority */ - put_le16(pb, 0); /* language */ - put_le32(pb, 0); /* initial frame */ - put_le32(pb, 1000); /* scale */ - put_le32(pb, (1000 * stream->frame_rate) / FRAME_RATE_BASE); /* rate */ - put_le32(pb, 0); /* start */ - avi->frames_hdr_strm[i] = url_ftell(pb); /* remember this offset to fill later */ - put_le32(pb, nb_frames); /* length, XXX: fill later */ - put_le32(pb, 1024 * 1024); /* suggested buffer size */ - put_le32(pb, -1); /* quality */ - put_le32(pb, stream->width * stream->height * 3); /* sample size */ - put_le16(pb, 0); - put_le16(pb, 0); - put_le16(pb, stream->width); - put_le16(pb, stream->height); - break; - case CODEC_TYPE_AUDIO: - put_tag(pb, "auds"); - put_le32(pb, 1); /* tag */ - put_le32(pb, 0); /* flags */ - put_le16(pb, 0); /* priority */ - put_le16(pb, 0); /* language */ - put_le32(pb, 0); /* initial frame */ - parse_specific_params(stream, &au_byterate, &au_ssize, &au_scale); - put_le32(pb, au_scale); /* scale */ - put_le32(pb, au_byterate); /* rate */ - put_le32(pb, 0); /* start */ - avi->frames_hdr_strm[i] = url_ftell(pb); /* remember this offset to fill later */ - put_le32(pb, 0); /* length, XXX: filled later */ - put_le32(pb, 12 * 1024); /* suggested buffer size */ - put_le32(pb, -1); /* quality */ - put_le32(pb, au_ssize); /* sample size */ - put_le32(pb, 0); - put_le32(pb, 0); - break; - default: - av_abort(); - } - end_tag(pb, strh); - - strf = start_tag(pb, "strf"); - switch(stream->codec_type) { - case CODEC_TYPE_VIDEO: - put_bmp_header(pb, stream, codec_bmp_tags, 0); - break; - case CODEC_TYPE_AUDIO: - if (put_wav_header(pb, stream) < 0) { - av_free(avi); - return -1; - } - break; - default: - av_abort(); - } - end_tag(pb, strf); - end_tag(pb, list2); - } - - end_tag(pb, list1); - - avi->movi_list = start_tag(pb, "LIST"); - avi->first = NULL; - avi->last = NULL; - put_tag(pb, "movi"); - - put_flush_packet(pb); - - return 0; -} - -static int avi_write_packet(AVFormatContext *s, int stream_index, - UINT8 *buf, int size, int force_pts) -{ - AVIContext *avi = s->priv_data; - ByteIOContext *pb = &s->pb; - AVIIndex *idx; - unsigned char tag[5]; - unsigned int flags; - AVCodecContext *enc; - - enc = &s->streams[stream_index]->codec; - - tag[0] = '0'; - tag[1] = '0' + stream_index; - if (enc->codec_type == CODEC_TYPE_VIDEO) { - tag[2] = 'd'; - tag[3] = 'c'; - flags = enc->key_frame ? 0x10 : 0x00; - } else { - tag[2] = 'w'; - tag[3] = 'b'; - flags = 0x10; - } - if (enc->codec_type == CODEC_TYPE_AUDIO) - avi->audio_strm_length[stream_index] += size; - - if (!url_is_streamed(&s->pb)) { - idx = av_malloc(sizeof(AVIIndex)); - memcpy(idx->tag, tag, 4); - idx->flags = flags; - idx->pos = url_ftell(pb) - avi->movi_list; - idx->len = size; - idx->next = NULL; - if (!avi->last) - avi->first = idx; - else - avi->last->next = idx; - avi->last = idx; - } - - put_buffer(pb, tag, 4); - put_le32(pb, size); - put_buffer(pb, buf, size); - if (size & 1) - put_byte(pb, 0); - - put_flush_packet(pb); - return 0; -} - -static int avi_write_trailer(AVFormatContext *s) -{ - ByteIOContext *pb = &s->pb; - AVIContext *avi = s->priv_data; - offset_t file_size, idx_chunk; - int n, nb_frames, au_byterate, au_ssize, au_scale; - AVCodecContext *stream; - AVIIndex *idx; - - if (!url_is_streamed(&s->pb)) { - end_tag(pb, avi->movi_list); - - idx_chunk = start_tag(pb, "idx1"); - idx = avi->first; - while (idx != NULL) { - put_buffer(pb, idx->tag, 4); - put_le32(pb, idx->flags); - put_le32(pb, idx->pos); - put_le32(pb, idx->len); - idx = idx->next; - } - end_tag(pb, idx_chunk); - - /* update file size */ - file_size = url_ftell(pb); - url_fseek(pb, 4, SEEK_SET); - put_le32(pb, (UINT32)(file_size - 8)); - - /* Fill in frame/sample counters */ - nb_frames = 0; - for(n=0;n<s->nb_streams;n++) { - if (avi->frames_hdr_strm[n] != 0) { - stream = &s->streams[n]->codec; - url_fseek(pb, avi->frames_hdr_strm[n], SEEK_SET); - if (stream->codec_type == CODEC_TYPE_VIDEO) { - put_le32(pb, stream->frame_number); - if (nb_frames < stream->frame_number) - nb_frames = stream->frame_number; - } else { - if (stream->codec_id == CODEC_ID_MP2 || stream->codec_id == CODEC_ID_MP3LAME) { - put_le32(pb, stream->frame_number); - nb_frames += stream->frame_number; - } else { - parse_specific_params(stream, &au_byterate, &au_ssize, &au_scale); - put_le32(pb, avi->audio_strm_length[n] / au_ssize); - } - } - } - } - if (avi->frames_hdr_all != 0) { - url_fseek(pb, avi->frames_hdr_all, SEEK_SET); - put_le32(pb, nb_frames); - } - url_fseek(pb, file_size, SEEK_SET); - } - put_flush_packet(pb); - return 0; -} - -static AVOutputFormat avi_oformat = { - "avi", - "avi format", - "video/x-msvideo", - "avi", - sizeof(AVIContext), - CODEC_ID_MP2, - CODEC_ID_MSMPEG4V3, - avi_write_header, - avi_write_packet, - avi_write_trailer, -}; - -int avienc_init(void) -{ - av_register_output_format(&avi_oformat); - return 0; -} diff --git a/libav/avio.c b/libav/avio.c deleted file mode 100644 index 37af56f9af..0000000000 --- a/libav/avio.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Unbuffered io for ffmpeg system - * Copyright (c) 2001 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" - -URLProtocol *first_protocol = NULL; - -int register_protocol(URLProtocol *protocol) -{ - URLProtocol **p; - p = &first_protocol; - while (*p != NULL) p = &(*p)->next; - *p = protocol; - protocol->next = NULL; - return 0; -} - -int url_open(URLContext **puc, const char *filename, int flags) -{ - URLContext *uc; - URLProtocol *up; - const char *p; - char proto_str[128], *q; - int err; - - p = filename; - q = proto_str; - while (*p != '\0' && *p != ':') { - if ((q - proto_str) < sizeof(proto_str) - 1) - *q++ = *p; - p++; - } - /* if the protocol has length 1, we consider it is a dos drive */ - if (*p == '\0' || (q - proto_str) <= 1) { - strcpy(proto_str, "file"); - } else { - *q = '\0'; - } - - up = first_protocol; - while (up != NULL) { - if (!strcmp(proto_str, up->name)) - goto found; - up = up->next; - } - err = -ENOENT; - goto fail; - found: - uc = av_malloc(sizeof(URLContext)); - if (!uc) { - err = -ENOMEM; - goto fail; - } - uc->prot = up; - uc->flags = flags; - uc->is_streamed = 0; /* default = not streamed */ - uc->max_packet_size = 0; /* default: stream file */ - err = up->url_open(uc, filename, flags); - if (err < 0) { - av_free(uc); - *puc = NULL; - return err; - } - *puc = uc; - return 0; - fail: - *puc = NULL; - return err; -} - -int url_read(URLContext *h, unsigned char *buf, int size) -{ - int ret; - if (h->flags & URL_WRONLY) - return -EIO; - ret = h->prot->url_read(h, buf, size); - return ret; -} - -int url_write(URLContext *h, unsigned char *buf, int size) -{ - int ret; - if (!(h->flags & (URL_WRONLY | URL_RDWR))) - return -EIO; - /* avoid sending too big packets */ - if (h->max_packet_size && size > h->max_packet_size) - return -EIO; - ret = h->prot->url_write(h, buf, size); - return ret; -} - -offset_t url_seek(URLContext *h, offset_t pos, int whence) -{ - offset_t ret; - - if (!h->prot->url_seek) - return -EPIPE; - ret = h->prot->url_seek(h, pos, whence); - return ret; -} - -int url_close(URLContext *h) -{ - int ret; - - ret = h->prot->url_close(h); - av_free(h); - return ret; -} - -int url_exist(const char *filename) -{ - URLContext *h; - if (url_open(&h, filename, URL_RDONLY) < 0) - return 0; - url_close(h); - return 1; -} - -offset_t url_filesize(URLContext *h) -{ - offset_t pos, size; - - pos = url_seek(h, 0, SEEK_CUR); - size = url_seek(h, 0, SEEK_END); - url_seek(h, pos, SEEK_SET); - return size; -} - -/* - * Return the maximum packet size associated to packetized file - * handle. If the file is not packetized (stream like http or file on - * disk), then 0 is returned. - * - * @param h file handle - * @return maximum packet size in bytes - */ -int url_get_max_packet_size(URLContext *h) -{ - return h->max_packet_size; -} diff --git a/libav/avio.h b/libav/avio.h deleted file mode 100644 index 541eff5ae0..0000000000 --- a/libav/avio.h +++ /dev/null @@ -1,153 +0,0 @@ -#ifndef AVIO_H -#define AVIO_H - -/* output byte stream handling */ - -typedef INT64 offset_t; - -/* unbuffered I/O */ - -struct URLContext { - struct URLProtocol *prot; - int flags; - int is_streamed; /* true if streamed (no seek possible), default = false */ - int max_packet_size; /* if non zero, the stream is packetized with this max packet size */ - void *priv_data; -}; - -typedef struct URLContext URLContext; - -typedef struct URLPollEntry { - URLContext *handle; - int events; - int revents; -} URLPollEntry; - -#define URL_RDONLY 0 -#define URL_WRONLY 1 -#define URL_RDWR 2 - -int url_open(URLContext **h, const char *filename, int flags); -int url_read(URLContext *h, unsigned char *buf, int size); -int url_write(URLContext *h, unsigned char *buf, int size); -offset_t url_seek(URLContext *h, offset_t pos, int whence); -int url_close(URLContext *h); -int url_exist(const char *filename); -offset_t url_filesize(URLContext *h); -int url_get_max_packet_size(URLContext *h); -/* not implemented */ -int url_poll(URLPollEntry *poll_table, int n, int timeout); - -typedef struct URLProtocol { - const char *name; - int (*url_open)(URLContext *h, const char *filename, int flags); - int (*url_read)(URLContext *h, unsigned char *buf, int size); - int (*url_write)(URLContext *h, unsigned char *buf, int size); - offset_t (*url_seek)(URLContext *h, offset_t pos, int whence); - int (*url_close)(URLContext *h); - struct URLProtocol *next; -} URLProtocol; - -extern URLProtocol *first_protocol; - -int register_protocol(URLProtocol *protocol); - -typedef struct { - unsigned char *buffer; - int buffer_size; - unsigned char *buf_ptr, *buf_end; - void *opaque; - int (*read_packet)(void *opaque, UINT8 *buf, int buf_size); - void (*write_packet)(void *opaque, UINT8 *buf, int buf_size); - int (*seek)(void *opaque, offset_t offset, int whence); - offset_t pos; /* position in the file of the current buffer */ - int must_flush; /* true if the next seek should flush */ - int eof_reached; /* true if eof reached */ - int write_flag; /* true if open for writing */ - int is_streamed; - int max_packet_size; -} ByteIOContext; - -int init_put_byte(ByteIOContext *s, - unsigned char *buffer, - int buffer_size, - int write_flag, - void *opaque, - int (*read_packet)(void *opaque, UINT8 *buf, int buf_size), - void (*write_packet)(void *opaque, UINT8 *buf, int buf_size), - int (*seek)(void *opaque, offset_t offset, int whence)); - -void put_byte(ByteIOContext *s, int b); -void put_buffer(ByteIOContext *s, const unsigned char *buf, int size); -void put_le64(ByteIOContext *s, UINT64 val); -void put_be64(ByteIOContext *s, UINT64 val); -void put_le32(ByteIOContext *s, unsigned int val); -void put_be32(ByteIOContext *s, unsigned int val); -void put_le16(ByteIOContext *s, unsigned int val); -void put_be16(ByteIOContext *s, unsigned int val); -void put_tag(ByteIOContext *s, const char *tag); - -void put_be64_double(ByteIOContext *s, double val); -void put_strz(ByteIOContext *s, const char *buf); - -offset_t url_fseek(ByteIOContext *s, offset_t offset, int whence); -void url_fskip(ByteIOContext *s, offset_t offset); -offset_t url_ftell(ByteIOContext *s); -int url_feof(ByteIOContext *s); - -#define URL_EOF (-1) -int url_fgetc(ByteIOContext *s); -int url_fprintf(ByteIOContext *s, const char *fmt, ...); -char *url_fgets(ByteIOContext *s, char *buf, int buf_size); - -void put_flush_packet(ByteIOContext *s); - -int get_buffer(ByteIOContext *s, unsigned char *buf, int size); -int get_byte(ByteIOContext *s); -unsigned int get_le32(ByteIOContext *s); -UINT64 get_le64(ByteIOContext *s); -unsigned int get_le16(ByteIOContext *s); - -double get_be64_double(ByteIOContext *s); -char *get_strz(ByteIOContext *s, char *buf, int maxlen); -unsigned int get_be16(ByteIOContext *s); -unsigned int get_be32(ByteIOContext *s); -UINT64 get_be64(ByteIOContext *s); - -static inline int url_is_streamed(ByteIOContext *s) -{ - return s->is_streamed; -} - -int url_fdopen(ByteIOContext *s, URLContext *h); -int url_setbufsize(ByteIOContext *s, int buf_size); -int url_fopen(ByteIOContext *s, const char *filename, int flags); -int url_fclose(ByteIOContext *s); -URLContext *url_fileno(ByteIOContext *s); -int url_fget_max_packet_size(ByteIOContext *s); - -int url_open_buf(ByteIOContext *s, UINT8 *buf, int buf_size, int flags); -int url_close_buf(ByteIOContext *s); - -int url_open_dyn_buf(ByteIOContext *s); -int url_open_dyn_packet_buf(ByteIOContext *s, int max_packet_size); -int url_close_dyn_buf(ByteIOContext *s, UINT8 **pbuffer); - -/* file.c */ -extern URLProtocol file_protocol; -extern URLProtocol pipe_protocol; - -/* udp.c */ -extern URLProtocol udp_protocol; -int udp_set_remote_url(URLContext *h, const char *uri); -int udp_get_local_port(URLContext *h); -int udp_get_file_handle(URLContext *h); - -/* tcp.c */ -extern URLProtocol tcp_protocol; - -/* http.c */ -extern URLProtocol http_protocol; - -#endif - diff --git a/libav/aviobuf.c b/libav/aviobuf.c deleted file mode 100644 index 2e931bd849..0000000000 --- a/libav/aviobuf.c +++ /dev/null @@ -1,687 +0,0 @@ -/* - * Buffered I/O for ffmpeg system - * Copyright (c) 2000,2001 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" -#include <stdarg.h> - -#define IO_BUFFER_SIZE 32768 - -int init_put_byte(ByteIOContext *s, - unsigned char *buffer, - int buffer_size, - int write_flag, - void *opaque, - int (*read_packet)(void *opaque, UINT8 *buf, int buf_size), - void (*write_packet)(void *opaque, UINT8 *buf, int buf_size), - int (*seek)(void *opaque, offset_t offset, int whence)) -{ - s->buffer = buffer; - s->buffer_size = buffer_size; - s->buf_ptr = buffer; - s->write_flag = write_flag; - if (!s->write_flag) - s->buf_end = buffer; - else - s->buf_end = buffer + buffer_size; - s->opaque = opaque; - s->write_packet = write_packet; - s->read_packet = read_packet; - s->seek = seek; - s->pos = 0; - s->must_flush = 0; - s->eof_reached = 0; - s->is_streamed = 0; - s->max_packet_size = 0; - return 0; -} - - -static void flush_buffer(ByteIOContext *s) -{ - if (s->buf_ptr > s->buffer) { - if (s->write_packet) - s->write_packet(s->opaque, s->buffer, s->buf_ptr - s->buffer); - s->pos += s->buf_ptr - s->buffer; - } - s->buf_ptr = s->buffer; -} - -void put_byte(ByteIOContext *s, int b) -{ - *(s->buf_ptr)++ = b; - if (s->buf_ptr >= s->buf_end) - flush_buffer(s); -} - -void put_buffer(ByteIOContext *s, const unsigned char *buf, int size) -{ - int len; - - while (size > 0) { - len = (s->buf_end - s->buf_ptr); - if (len > size) - len = size; - memcpy(s->buf_ptr, buf, len); - s->buf_ptr += len; - - if (s->buf_ptr >= s->buf_end) - flush_buffer(s); - - buf += len; - size -= len; - } -} - -void put_flush_packet(ByteIOContext *s) -{ - flush_buffer(s); - s->must_flush = 0; -} - -offset_t url_fseek(ByteIOContext *s, offset_t offset, int whence) -{ - offset_t offset1; - - if (whence != SEEK_CUR && whence != SEEK_SET) - return -EINVAL; - - if (s->write_flag) { - if (whence == SEEK_CUR) { - offset1 = s->pos + (s->buf_ptr - s->buffer); - if (offset == 0) - return offset1; - offset += offset1; - } - offset1 = offset - s->pos; - if (!s->must_flush && - offset1 >= 0 && offset1 < (s->buf_end - s->buffer)) { - /* can do the seek inside the buffer */ - s->buf_ptr = s->buffer + offset1; - } else { - if (!s->seek) - return -EPIPE; - flush_buffer(s); - s->must_flush = 1; - s->buf_ptr = s->buffer; - s->seek(s->opaque, offset, SEEK_SET); - s->pos = offset; - } - } else { - if (whence == SEEK_CUR) { - offset1 = s->pos - (s->buf_end - s->buffer) + (s->buf_ptr - s->buffer); - if (offset == 0) - return offset1; - offset += offset1; - } - offset1 = offset - (s->pos - (s->buf_end - s->buffer)); - if (offset1 >= 0 && offset1 <= (s->buf_end - s->buffer)) { - /* can do the seek inside the buffer */ - s->buf_ptr = s->buffer + offset1; - } else { - if (!s->seek) - return -EPIPE; - s->buf_ptr = s->buffer; - s->buf_end = s->buffer; - s->seek(s->opaque, offset, SEEK_SET); - s->pos = offset; - } - s->eof_reached = 0; - } - return offset; -} - -void url_fskip(ByteIOContext *s, offset_t offset) -{ - url_fseek(s, offset, SEEK_CUR); -} - -offset_t url_ftell(ByteIOContext *s) -{ - return url_fseek(s, 0, SEEK_CUR); -} - -int url_feof(ByteIOContext *s) -{ - return s->eof_reached; -} - -void put_le32(ByteIOContext *s, unsigned int val) -{ - put_byte(s, val); - put_byte(s, val >> 8); - put_byte(s, val >> 16); - put_byte(s, val >> 24); -} - -void put_be32(ByteIOContext *s, unsigned int val) -{ - put_byte(s, val >> 24); - put_byte(s, val >> 16); - put_byte(s, val >> 8); - put_byte(s, val); -} - -/* IEEE format is assumed */ -void put_be64_double(ByteIOContext *s, double val) -{ - union { - double d; - UINT64 ull; - } u; - u.d = val; - put_be64(s, u.ull); -} - -void put_strz(ByteIOContext *s, const char *str) -{ - if (str) - put_buffer(s, (const unsigned char *) str, strlen(str) + 1); - else - put_byte(s, 0); -} - -void put_le64(ByteIOContext *s, UINT64 val) -{ - put_le32(s, (UINT32)(val & 0xffffffff)); - put_le32(s, (UINT32)(val >> 32)); -} - -void put_be64(ByteIOContext *s, UINT64 val) -{ - put_be32(s, (UINT32)(val >> 32)); - put_be32(s, (UINT32)(val & 0xffffffff)); -} - -void put_le16(ByteIOContext *s, unsigned int val) -{ - put_byte(s, val); - put_byte(s, val >> 8); -} - -void put_be16(ByteIOContext *s, unsigned int val) -{ - put_byte(s, val >> 8); - put_byte(s, val); -} - -void put_tag(ByteIOContext *s, const char *tag) -{ - while (*tag) { - put_byte(s, *tag++); - } -} - -/* Input stream */ - -static void fill_buffer(ByteIOContext *s) -{ - int len; - - /* no need to do anything if EOF already reached */ - if (s->eof_reached) - return; - len = s->read_packet(s->opaque, s->buffer, s->buffer_size); - if (len <= 0) { - /* do not modify buffer if EOF reached so that a seek back can - be done without rereading data */ - s->eof_reached = 1; - } else { - s->pos += len; - s->buf_ptr = s->buffer; - s->buf_end = s->buffer + len; - } -} - -/* NOTE: return 0 if EOF, so you cannot use it if EOF handling is - necessary */ -/* XXX: put an inline version */ -int get_byte(ByteIOContext *s) -{ - if (s->buf_ptr < s->buf_end) { - return *s->buf_ptr++; - } else { - fill_buffer(s); - if (s->buf_ptr < s->buf_end) - return *s->buf_ptr++; - else - return 0; - } -} - -/* NOTE: return URL_EOF (-1) if EOF */ -int url_fgetc(ByteIOContext *s) -{ - if (s->buf_ptr < s->buf_end) { - return *s->buf_ptr++; - } else { - fill_buffer(s); - if (s->buf_ptr < s->buf_end) - return *s->buf_ptr++; - else - return URL_EOF; - } -} - -int get_buffer(ByteIOContext *s, unsigned char *buf, int size) -{ - int len, size1; - - size1 = size; - while (size > 0) { - len = s->buf_end - s->buf_ptr; - if (len > size) - len = size; - if (len == 0) { - fill_buffer(s); - len = s->buf_end - s->buf_ptr; - if (len == 0) - break; - } else { - memcpy(buf, s->buf_ptr, len); - buf += len; - s->buf_ptr += len; - size -= len; - } - } - return size1 - size; -} - -unsigned int get_le16(ByteIOContext *s) -{ - unsigned int val; - val = get_byte(s); - val |= get_byte(s) << 8; - return val; -} - -unsigned int get_le32(ByteIOContext *s) -{ - unsigned int val; - val = get_byte(s); - val |= get_byte(s) << 8; - val |= get_byte(s) << 16; - val |= get_byte(s) << 24; - return val; -} - -UINT64 get_le64(ByteIOContext *s) -{ - UINT64 val; - val = (UINT64)get_le32(s); - val |= (UINT64)get_le32(s) << 32; - return val; -} - -unsigned int get_be16(ByteIOContext *s) -{ - unsigned int val; - val = get_byte(s) << 8; - val |= get_byte(s); - return val; -} - -unsigned int get_be32(ByteIOContext *s) -{ - unsigned int val; - val = get_byte(s) << 24; - val |= get_byte(s) << 16; - val |= get_byte(s) << 8; - val |= get_byte(s); - return val; -} - -double get_be64_double(ByteIOContext *s) -{ - union { - double d; - UINT64 ull; - } u; - - u.ull = get_be64(s); - return u.d; -} - -char *get_strz(ByteIOContext *s, char *buf, int maxlen) -{ - int i = 0; - char c; - - while ((c = get_byte(s))) { - if (i < maxlen-1) - buf[i++] = c; - } - - buf[i] = 0; /* Ensure null terminated, but may be truncated */ - - return buf; -} - -UINT64 get_be64(ByteIOContext *s) -{ - UINT64 val; - val = (UINT64)get_be32(s) << 32; - val |= (UINT64)get_be32(s); - return val; -} - -/* link with avio functions */ - -void url_write_packet(void *opaque, UINT8 *buf, int buf_size) -{ - URLContext *h = opaque; - url_write(h, buf, buf_size); -} - -int url_read_packet(void *opaque, UINT8 *buf, int buf_size) -{ - URLContext *h = opaque; - return url_read(h, buf, buf_size); -} - -int url_seek_packet(void *opaque, INT64 offset, int whence) -{ - URLContext *h = opaque; - url_seek(h, offset, whence); - return 0; -} - -int url_fdopen(ByteIOContext *s, URLContext *h) -{ - UINT8 *buffer; - int buffer_size, max_packet_size; - - - max_packet_size = url_get_max_packet_size(h); - if (max_packet_size) { - buffer_size = max_packet_size; /* no need to bufferize more than one packet */ - } else { - buffer_size = IO_BUFFER_SIZE; - } - buffer = av_malloc(buffer_size); - if (!buffer) - return -ENOMEM; - - if (init_put_byte(s, buffer, buffer_size, - (h->flags & URL_WRONLY) != 0, h, - url_read_packet, url_write_packet, url_seek_packet) < 0) { - av_free(buffer); - return -EIO; - } - s->is_streamed = h->is_streamed; - s->max_packet_size = max_packet_size; - return 0; -} - -/* XXX: must be called before any I/O */ -int url_setbufsize(ByteIOContext *s, int buf_size) -{ - UINT8 *buffer; - buffer = av_malloc(buf_size); - if (!buffer) - return -ENOMEM; - - av_free(s->buffer); - s->buffer = buffer; - s->buffer_size = buf_size; - s->buf_ptr = buffer; - if (!s->write_flag) - s->buf_end = buffer; - else - s->buf_end = buffer + buf_size; - return 0; -} - -/* NOTE: when opened as read/write, the buffers are only used for - reading */ -int url_fopen(ByteIOContext *s, const char *filename, int flags) -{ - URLContext *h; - int err; - - err = url_open(&h, filename, flags); - if (err < 0) - return err; - err = url_fdopen(s, h); - if (err < 0) { - url_close(h); - return err; - } - return 0; -} - -int url_fclose(ByteIOContext *s) -{ - URLContext *h = s->opaque; - - av_free(s->buffer); - memset(s, 0, sizeof(ByteIOContext)); - return url_close(h); -} - -URLContext *url_fileno(ByteIOContext *s) -{ - return s->opaque; -} - -/* XXX: currently size is limited */ -int url_fprintf(ByteIOContext *s, const char *fmt, ...) -{ - va_list ap; - char buf[4096]; - int ret; - - va_start(ap, fmt); - ret = vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - put_buffer(s, buf, strlen(buf)); - return ret; -} - -/* note: unlike fgets, the EOL character is not returned and a whole - line is parsed. return NULL if first char read was EOF */ -char *url_fgets(ByteIOContext *s, char *buf, int buf_size) -{ - int c; - char *q; - - c = url_fgetc(s); - if (c == EOF) - return NULL; - q = buf; - for(;;) { - if (c == EOF || c == '\n') - break; - if ((q - buf) < buf_size - 1) - *q++ = c; - c = url_fgetc(s); - } - if (buf_size > 0) - *q = '\0'; - return buf; -} - -/* - * Return the maximum packet size associated to packetized buffered file - * handle. If the file is not packetized (stream like http or file on - * disk), then 0 is returned. - * - * @param h buffered file handle - * @return maximum packet size in bytes - */ -int url_fget_max_packet_size(ByteIOContext *s) -{ - return s->max_packet_size; -} - -/* buffer handling */ -int url_open_buf(ByteIOContext *s, UINT8 *buf, int buf_size, int flags) -{ - return init_put_byte(s, buf, buf_size, - (flags & URL_WRONLY) != 0, NULL, NULL, NULL, NULL); -} - -/* return the written or read size */ -int url_close_buf(ByteIOContext *s) -{ - put_flush_packet(s); - return s->buf_ptr - s->buffer; -} - -/* output in a dynamic buffer */ - -typedef struct DynBuffer { - int pos, size, allocated_size; - UINT8 *buffer; - int io_buffer_size; - UINT8 io_buffer[1]; -} DynBuffer; - -static void dyn_buf_write(void *opaque, UINT8 *buf, int buf_size) -{ - DynBuffer *d = opaque; - int new_size, new_allocated_size; - UINT8 *new_buffer; - - /* reallocate buffer if needed */ - new_size = d->pos + buf_size; - new_allocated_size = d->allocated_size; - while (new_size > new_allocated_size) { - if (!new_allocated_size) - new_allocated_size = new_size; - else - new_allocated_size = (new_allocated_size * 3) / 2 + 1; - } - - if (new_allocated_size > d->allocated_size) { - new_buffer = av_malloc(new_allocated_size); - if (!new_buffer) - return; - memcpy(new_buffer, d->buffer, d->size); - av_free(d->buffer); - d->buffer = new_buffer; - d->allocated_size = new_allocated_size; - } - memcpy(d->buffer + d->pos, buf, buf_size); - d->pos = new_size; - if (d->pos > d->size) - d->size = d->pos; -} - -static void dyn_packet_buf_write(void *opaque, UINT8 *buf, int buf_size) -{ - unsigned char buf1[4]; - - /* packetized write: output the header */ - buf1[0] = (buf_size >> 24); - buf1[1] = (buf_size >> 16); - buf1[2] = (buf_size >> 8); - buf1[3] = (buf_size); - dyn_buf_write(opaque, buf1, 4); - - /* then the data */ - dyn_buf_write(opaque, buf, buf_size); -} - -static int dyn_buf_seek(void *opaque, offset_t offset, int whence) -{ - DynBuffer *d = opaque; - - if (whence == SEEK_CUR) - offset += d->pos; - else if (whence == SEEK_END) - offset += d->size; - if (offset < 0 || offset > 0x7fffffffLL) - return -1; - d->pos = offset; - return 0; -} - -static int url_open_dyn_buf_internal(ByteIOContext *s, int max_packet_size) -{ - DynBuffer *d; - int io_buffer_size, ret; - - if (max_packet_size) - io_buffer_size = max_packet_size; - else - io_buffer_size = 1024; - - d = av_malloc(sizeof(DynBuffer) + io_buffer_size); - if (!d) - return -1; - d->io_buffer_size = io_buffer_size; - d->buffer = NULL; - d->pos = 0; - d->size = 0; - d->allocated_size = 0; - ret = init_put_byte(s, d->io_buffer, io_buffer_size, - 1, d, NULL, - max_packet_size ? dyn_packet_buf_write : dyn_buf_write, - max_packet_size ? NULL : dyn_buf_seek); - if (ret == 0) { - s->max_packet_size = max_packet_size; - } - return ret; -} - -/* - * Open a write only memory stream. - * - * @param s new IO context - * @return zero if no error. - */ -int url_open_dyn_buf(ByteIOContext *s) -{ - return url_open_dyn_buf_internal(s, 0); -} - -/* - * Open a write only packetized memory stream with a maximum packet - * size of 'max_packet_size'. The stream is stored in a memory buffer - * with a big endian 4 byte header giving the packet size in bytes. - * - * @param s new IO context - * @param max_packet_size maximum packet size (must be > 0) - * @return zero if no error. - */ -int url_open_dyn_packet_buf(ByteIOContext *s, int max_packet_size) -{ - if (max_packet_size <= 0) - return -1; - return url_open_dyn_buf_internal(s, max_packet_size); -} - -/* - * Return the written size and a pointer to the buffer. The buffer - * must be freed with av_free(). - * @param s IO context - * @param pointer to a byte buffer - * @return the length of the byte buffer - */ -int url_close_dyn_buf(ByteIOContext *s, UINT8 **pbuffer) -{ - DynBuffer *d = s->opaque; - int size; - - put_flush_packet(s); - - *pbuffer = d->buffer; - size = d->size; - av_free(d); - return size; -} diff --git a/libav/barpainet.c b/libav/barpainet.c deleted file mode 100644 index c1e8877718..0000000000 --- a/libav/barpainet.c +++ /dev/null @@ -1,25 +0,0 @@ - -#include <stdlib.h> -#include <strings.h> -#include "barpainet.h" - -int inet_aton (const char * str, struct in_addr * add) { - const char * pch = str; - unsigned int add1 = 0, add2 = 0, add3 = 0, add4 = 0; - - add1 = atoi(pch); - pch = strpbrk(pch,"."); - if (pch == 0 || ++pch == 0) goto done; - add2 = atoi(pch); - pch = strpbrk(pch,"."); - if (pch == 0 || ++pch == 0) goto done; - add3 = atoi(pch); - pch = strpbrk(pch,"."); - if (pch == 0 || ++pch == 0) goto done; - add4 = atoi(pch); - -done: - add->s_addr=(add4<<24)+(add3<<16)+(add2<<8)+add1; - - return 1; -} diff --git a/libav/barpainet.h b/libav/barpainet.h deleted file mode 100644 index 461403b3fa..0000000000 --- a/libav/barpainet.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef BARPA_INET_H -#define BARPA_INET_H - -#include "../config.h" - -#ifdef CONFIG_BEOS_NETSERVER - -# include <socket.h> -int inet_aton (const char * str, struct in_addr * add); -# define PF_INET AF_INET -# define SO_SNDBUF 0x40000001 - -/* fake */ -struct ip_mreq { - struct in_addr imr_multiaddr; /* IP multicast address of group */ - struct in_addr imr_interface; /* local IP address of interface */ -}; - -#else -# include <arpa/inet.h> -#endif - -#endif /* BARPA_INET_H */ diff --git a/libav/beosaudio.cpp b/libav/beosaudio.cpp deleted file mode 100644 index a1ae0a53c8..0000000000 --- a/libav/beosaudio.cpp +++ /dev/null @@ -1,449 +0,0 @@ -/* - * BeOS audio play interface - * Copyright (c) 2000, 2001 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ - -#include <signal.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <sys/time.h> - -#include <Application.h> -#include <SoundPlayer.h> - -extern "C" { -#include "avformat.h" -} - -/* enable performance checks */ -//#define PERF_CHECK - -//const char *audio_device = "/dev/dsp"; -const char *audio_device = "beosaudio:"; - -/* Pipes are 4k in BeOS IIRC */ -#define AUDIO_BLOCK_SIZE 4096 -//#define AUDIO_BLOCK_SIZE 2048 -#define AUDIO_BLOCK_COUNT 8 - -#define AUDIO_BUFFER_SIZE (AUDIO_BLOCK_SIZE*AUDIO_BLOCK_COUNT) - -/* pipes suck for realtime */ -#define USE_RING_BUFFER 1 - -typedef struct { - int fd; - int sample_rate; - int channels; - int frame_size; /* in bytes ! */ - CodecID codec_id; - int flip_left : 1; - UINT8 buffer[AUDIO_BUFFER_SIZE]; - int buffer_ptr; - int pipefd; /* the other end of the pipe */ - /* ring buffer */ - sem_id input_sem; - int input_index; - sem_id output_sem; - int output_index; - int queued; - BSoundPlayer *player; - int has_quit; /* signal callbacks not to wait */ - volatile bigtime_t starve_time; -} AudioData; - -static thread_id main_thid; -static thread_id bapp_thid; -static int own_BApp_created = 0; -static int refcount = 0; - -/* create the BApplication and Run() it */ -static int32 bapp_thread(void *arg) -{ - new BApplication("application/x-vnd.ffmpeg"); - own_BApp_created = 1; - be_app->Run(); - /* kill the process group */ -// kill(0, SIGINT); -// kill(main_thid, SIGHUP); - return B_OK; -} - -/* create the BApplication only if needed */ -static void create_bapp_if_needed(void) -{ - if (refcount++ == 0) { - /* needed by libmedia */ - if (be_app == NULL) { - bapp_thid = spawn_thread(bapp_thread, "ffmpeg BApplication", B_NORMAL_PRIORITY, NULL); - resume_thread(bapp_thid); - while (!own_BApp_created) - snooze(50000); - } - } -} - -static void destroy_bapp_if_needed(void) -{ - if (--refcount == 0 && own_BApp_created) { - be_app->Lock(); - be_app->Quit(); - be_app = NULL; - } -} - -/* called back by BSoundPlayer */ -static void audioplay_callback(void *cookie, void *buffer, size_t bufferSize, const media_raw_audio_format &format) -{ - AudioData *s; - size_t len, amount; - unsigned char *buf = (unsigned char *)buffer; - - s = (AudioData *)cookie; - if (s->has_quit) - return; - while (bufferSize > 0) { -#ifdef PERF_CHECK - bigtime_t t; - t = system_time(); -#endif -#ifdef USE_RING_BUFFER - len = MIN(AUDIO_BLOCK_SIZE, bufferSize); - if (acquire_sem_etc(s->output_sem, len, B_CAN_INTERRUPT, 0LL) < B_OK) { - s->has_quit = 1; - s->player->SetHasData(false); - return; - } - amount = MIN(len, (AUDIO_BUFFER_SIZE - s->output_index)); - memcpy(buf, &s->buffer[s->output_index], amount); - s->output_index += amount; - if (s->output_index >= AUDIO_BUFFER_SIZE) { - s->output_index %= AUDIO_BUFFER_SIZE; - memcpy(buf + amount, &s->buffer[s->output_index], len - amount); - s->output_index += len-amount; - s->output_index %= AUDIO_BUFFER_SIZE; - } - release_sem_etc(s->input_sem, len, 0); -#else - len = read(s->pipefd, buf, bufferSize); -#endif -#ifdef PERF_CHECK - t = system_time() - t; - s->starve_time = MAX(s->starve_time, t); -#endif -#ifndef USE_RING_BUFFER - if (len < B_OK) { - puts("EPIPE"); - s->player->SetHasData(false); - snooze(100000); - return; - } - if (len == 0) { - s->player->SetHasData(false); - snooze(100000); - return; - } -#endif - buf += len; - bufferSize -= len; - } -} - -static int audio_open(AudioData *s, int is_output) -{ - int p[2]; - int ret; - media_raw_audio_format format; - - if (!is_output) - return -EIO; /* not for now */ -#ifdef USE_RING_BUFFER - s->input_sem = create_sem(AUDIO_BUFFER_SIZE, "ffmpeg_ringbuffer_input"); -// s->input_sem = create_sem(AUDIO_BLOCK_SIZE, "ffmpeg_ringbuffer_input"); - if (s->input_sem < B_OK) - return -EIO; - s->output_sem = create_sem(0, "ffmpeg_ringbuffer_output"); - if (s->output_sem < B_OK) { - delete_sem(s->input_sem); - return -EIO; - } - s->input_index = 0; - s->output_index = 0; - s->queued = 0; -#else - ret = pipe(p); - if (ret < 0) - return -EIO; - s->fd = p[is_output?1:0]; - s->pipefd = p[is_output?0:1]; - if (s->fd < 0) { - perror(is_output?"audio out":"audio in"); - return -EIO; - } -#endif - create_bapp_if_needed(); - /* non blocking mode */ -// fcntl(s->fd, F_SETFL, O_NONBLOCK); -// fcntl(s->pipefd, F_SETFL, O_NONBLOCK); - s->frame_size = AUDIO_BLOCK_SIZE; - format = media_raw_audio_format::wildcard; - format.format = media_raw_audio_format::B_AUDIO_SHORT; - format.byte_order = B_HOST_IS_LENDIAN ? B_MEDIA_LITTLE_ENDIAN : B_MEDIA_BIG_ENDIAN; - format.channel_count = s->channels; - format.buffer_size = s->frame_size; - format.frame_rate = s->sample_rate; - s->player = new BSoundPlayer(&format, "ffmpeg output", audioplay_callback); - if (s->player->InitCheck() != B_OK) { - delete s->player; - s->player = NULL; -#ifdef USE_RING_BUFFER - if (s->input_sem) - delete_sem(s->input_sem); - if (s->output_sem) - delete_sem(s->output_sem); -#else - close(s->fd); - close(s->pipefd); -#endif - return -EIO; - } - s->player->SetCookie(s); - s->player->SetVolume(1.0); - s->player->Start(); - s->player->SetHasData(true); - /* bump up the priority (avoid realtime though) */ - set_thread_priority(find_thread(NULL), B_DISPLAY_PRIORITY+1); - return 0; -} - -static int audio_close(AudioData *s) -{ -#ifdef USE_RING_BUFFER - if (s->input_sem) - delete_sem(s->input_sem); - if (s->output_sem) - delete_sem(s->output_sem); -#endif - s->has_quit = 1; - if (s->player) { - s->player->Stop(); - } - if (s->player) - delete s->player; -#ifndef USE_RING_BUFFER - close(s->pipefd); - close(s->fd); -#endif - destroy_bapp_if_needed(); - return 0; -} - -/* sound output support */ -static int audio_write_header(AVFormatContext *s1) -{ - AudioData *s = (AudioData *)s1->priv_data; - AVStream *st; - int ret; - - st = s1->streams[0]; - s->sample_rate = st->codec.sample_rate; - s->channels = st->codec.channels; - ret = audio_open(s, 1); - if (ret < 0) - return -EIO; - return 0; -} - -static int audio_write_packet(AVFormatContext *s1, int stream_index, - UINT8 *buf, int size, int force_pts) -{ - AudioData *s = (AudioData *)s1->priv_data; - int len, ret; -#ifdef PERF_CHECK - bigtime_t t = s->starve_time; - s->starve_time = 0; - printf("starve_time: %lld \n", t); -#endif -#ifdef USE_RING_BUFFER - while (size > 0) { - int amount; - len = MIN(size, AUDIO_BLOCK_SIZE); - if (acquire_sem_etc(s->input_sem, len, B_CAN_INTERRUPT, 0LL) < B_OK) - return -EIO; - amount = MIN(len, (AUDIO_BUFFER_SIZE - s->input_index)); - memcpy(&s->buffer[s->input_index], buf, amount); - s->input_index += amount; - if (s->input_index >= AUDIO_BUFFER_SIZE) { - s->input_index %= AUDIO_BUFFER_SIZE; - memcpy(&s->buffer[s->input_index], buf + amount, len - amount); - s->input_index += len - amount; - } - release_sem_etc(s->output_sem, len, 0); - buf += len; - size -= len; - } -#else - while (size > 0) { - len = AUDIO_BLOCK_SIZE - s->buffer_ptr; - if (len > size) - len = size; - memcpy(s->buffer + s->buffer_ptr, buf, len); - s->buffer_ptr += len; - if (s->buffer_ptr >= AUDIO_BLOCK_SIZE) { - for(;;) { -//snooze(1000); - ret = write(s->fd, s->buffer, AUDIO_BLOCK_SIZE); - if (ret != 0) - break; - if (ret < 0 && (errno != EAGAIN && errno != EINTR)) - return -EIO; - } - s->buffer_ptr = 0; - } - buf += len; - size -= len; - } -#endif - return 0; -} - -static int audio_write_trailer(AVFormatContext *s1) -{ - AudioData *s = (AudioData *)s1->priv_data; - - audio_close(s); - return 0; -} - -/* grab support */ - -static int audio_read_header(AVFormatContext *s1, AVFormatParameters *ap) -{ - AudioData *s = (AudioData *)s1->priv_data; - AVStream *st; - int ret; - - if (!ap || ap->sample_rate <= 0 || ap->channels <= 0) - return -1; - - st = av_new_stream(s1, 0); - if (!st) { - return -ENOMEM; - } - s->sample_rate = ap->sample_rate; - s->channels = ap->channels; - - ret = audio_open(s, 0); - if (ret < 0) { - av_free(st); - return -EIO; - } else { - /* take real parameters */ - st->codec.codec_type = CODEC_TYPE_AUDIO; - st->codec.codec_id = s->codec_id; - st->codec.sample_rate = s->sample_rate; - st->codec.channels = s->channels; - return 0; - } -} - -static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt) -{ - AudioData *s = (AudioData *)s1->priv_data; - int ret; - - if (av_new_packet(pkt, s->frame_size) < 0) - return -EIO; - for(;;) { - ret = read(s->fd, pkt->data, pkt->size); - if (ret > 0) - break; - if (ret == -1 && (errno == EAGAIN || errno == EINTR)) { - av_free_packet(pkt); - pkt->size = 0; - return 0; - } - if (!(ret == 0 || (ret == -1 && (errno == EAGAIN || errno == EINTR)))) { - av_free_packet(pkt); - return -EIO; - } - } - pkt->size = ret; - if (s->flip_left && s->channels == 2) { - int i; - short *p = (short *) pkt->data; - - for (i = 0; i < ret; i += 4) { - *p = ~*p; - p += 2; - } - } - return 0; -} - -static int audio_read_close(AVFormatContext *s1) -{ - AudioData *s = (AudioData *)s1->priv_data; - - audio_close(s); - return 0; -} - -AVInputFormat audio_in_format = { - "audio_device", - "audio grab and output", - sizeof(AudioData), - NULL, - audio_read_header, - audio_read_packet, - audio_read_close, - NULL, - AVFMT_NOFILE, -}; - -AVOutputFormat audio_out_format = { - "audio_device", - "audio grab and output", - "", - "", - sizeof(AudioData), -#ifdef WORDS_BIGENDIAN - CODEC_ID_PCM_S16BE, -#else - CODEC_ID_PCM_S16LE, -#endif - CODEC_ID_NONE, - audio_write_header, - audio_write_packet, - audio_write_trailer, - AVFMT_NOFILE, -}; - -extern "C" { - -int audio_init(void) -{ - main_thid = find_thread(NULL); - av_register_input_format(&audio_in_format); - av_register_output_format(&audio_out_format); - return 0; -} - -} // "C" - diff --git a/libav/crc.c b/libav/crc.c deleted file mode 100644 index 553ab537cb..0000000000 --- a/libav/crc.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * CRC decoder (for codec/format testing) - * Copyright (c) 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" - -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#define BASE 65521L /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf) {s1 += *buf++; s2 += s1;} -#define DO2(buf) DO1(buf); DO1(buf); -#define DO4(buf) DO2(buf); DO2(buf); -#define DO8(buf) DO4(buf); DO4(buf); -#define DO16(buf) DO8(buf); DO8(buf); - -static UINT32 adler32(UINT32 adler, UINT8 *buf, unsigned int len) -{ - unsigned long s1 = adler & 0xffff; - unsigned long s2 = (adler >> 16) & 0xffff; - int k; - - if (buf == NULL) return 1L; - - while (len > 0) { - k = len < NMAX ? len : NMAX; - len -= k; - while (k >= 16) { - DO16(buf); - k -= 16; - } - if (k != 0) do { - DO1(buf); - } while (--k); - s1 %= BASE; - s2 %= BASE; - } - return (s2 << 16) | s1; -} - -typedef struct CRCState { - UINT32 crcval; -} CRCState; - -static int crc_write_header(struct AVFormatContext *s) -{ - CRCState *crc = s->priv_data; - - /* init CRC */ - crc->crcval = adler32(0, NULL, 0); - - return 0; -} - -static int crc_write_packet(struct AVFormatContext *s, - int stream_index, - unsigned char *buf, int size, int force_pts) -{ - CRCState *crc = s->priv_data; - crc->crcval = adler32(crc->crcval, buf, size); - return 0; -} - -static int crc_write_trailer(struct AVFormatContext *s) -{ - CRCState *crc = s->priv_data; - char buf[64]; - - snprintf(buf, sizeof(buf), "CRC=%08x\n", crc->crcval); - put_buffer(&s->pb, buf, strlen(buf)); - put_flush_packet(&s->pb); - return 0; -} - -static AVOutputFormat crc_format = { - "crc", - "crc testing format", - NULL, - "", - sizeof(CRCState), - CODEC_ID_PCM_S16LE, - CODEC_ID_RAWVIDEO, - crc_write_header, - crc_write_packet, - crc_write_trailer, -}; - -int crc_init(void) -{ - av_register_output_format(&crc_format); - return 0; -} diff --git a/libav/cutils.c b/libav/cutils.c deleted file mode 100644 index ce2c845226..0000000000 --- a/libav/cutils.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Various simple utilities for ffmpeg system - * 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" -#include <ctype.h> - -#if !defined(CONFIG_NOCUTILS) -/** - * Return TRUE if val is a prefix of str. If it returns TRUE, ptr is - * set to the next character in 'str' after the prefix. - * - * @param str input string - * @param val prefix to test - * @param ptr updated after the prefix in str in there is a match - * @return TRUE if there is a match - */ -int strstart(const char *str, const char *val, const char **ptr) -{ - const char *p, *q; - p = str; - q = val; - while (*q != '\0') { - if (*p != *q) - return 0; - p++; - q++; - } - if (ptr) - *ptr = p; - return 1; -} - -/** - * Return TRUE if val is a prefix of str (case independent). If it - * returns TRUE, ptr is set to the next character in 'str' after the - * prefix. - * - * @param str input string - * @param val prefix to test - * @param ptr updated after the prefix in str in there is a match - * @return TRUE if there is a match */ -int stristart(const char *str, const char *val, const char **ptr) -{ - const char *p, *q; - p = str; - q = val; - while (*q != '\0') { - if (toupper(*(unsigned char *)p) != toupper(*(unsigned char *)q)) - return 0; - p++; - q++; - } - if (ptr) - *ptr = p; - return 1; -} - -/** - * Copy the string str to buf. If str length is bigger than buf_size - - * 1 then it is clamped to buf_size - 1. - * NOTE: this function does what strncpy should have done to be - * useful. NEVER use strncpy. - * - * @param buf destination buffer - * @param buf_size size of destination buffer - * @param str source string - */ -void pstrcpy(char *buf, int buf_size, const char *str) -{ - int c; - char *q = buf; - - if (buf_size <= 0) - return; - - for(;;) { - c = *str++; - if (c == 0 || q >= buf + buf_size - 1) - break; - *q++ = c; - } - *q = '\0'; -} - -/* strcat and truncate. */ -char *pstrcat(char *buf, int buf_size, const char *s) -{ - int len; - len = strlen(buf); - if (len < buf_size) - pstrcpy(buf + len, buf_size - len, s); - return buf; -} - -#endif diff --git a/libav/dv.c b/libav/dv.c deleted file mode 100644 index 1f152a2fba..0000000000 --- a/libav/dv.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Raw DV format - * Copyright (c) 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" - -#define NTSC_FRAME_SIZE 120000 -#define PAL_FRAME_SIZE 144000 - -typedef struct DVDemuxContext { - int is_audio; -} DVDemuxContext; - -/* raw input */ -static int dv_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - AVStream *vst, *ast; - - vst = av_new_stream(s, 0); - if (!vst) - return AVERROR_NOMEM; - vst->codec.codec_type = CODEC_TYPE_VIDEO; - vst->codec.codec_id = CODEC_ID_DVVIDEO; - -#if 0 - ast = av_new_stream(s, 1); - if (!ast) - return AVERROR_NOMEM; - - ast->codec.codec_type = CODEC_TYPE_AUDIO; - ast->codec.codec_id = CODEC_ID_DVAUDIO; -#endif - return 0; -} - -/* XXX: build fake audio stream when DV audio decoder will be finished */ -static int dv_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int ret, size, dsf; - uint8_t buf[4]; - - ret = get_buffer(&s->pb, buf, 4); - if (ret <= 0) - return -EIO; - dsf = buf[3] & 0x80; - if (!dsf) - size = NTSC_FRAME_SIZE; - else - size = PAL_FRAME_SIZE; - - if (av_new_packet(pkt, size) < 0) - return -EIO; - - pkt->stream_index = 0; - memcpy(pkt->data, buf, 4); - ret = get_buffer(&s->pb, pkt->data + 4, size - 4); - if (ret <= 0) { - av_free_packet(pkt); - return -EIO; - } - return ret; -} - -static int dv_read_close(AVFormatContext *s) -{ - return 0; -} - -static AVInputFormat dv_iformat = { - "dv", - "DV video format", - sizeof(DVDemuxContext), - NULL, - dv_read_header, - dv_read_packet, - dv_read_close, - .extensions = "dv", -}; - -#if 0 -int dv_write_header(struct AVFormatContext *s) -{ - return 0; -} - -int dv_write_packet(struct AVFormatContext *s, - int stream_index, - unsigned char *buf, int size, int force_pts) -{ - put_buffer(&s->pb, buf, size); - put_flush_packet(&s->pb); - return 0; -} - -int dv_write_trailer(struct AVFormatContext *s) -{ - return 0; -} - -AVOutputFormat dv_oformat = { - "dv", - "DV video format", - NULL, - "dv", - 0, - CODEC_ID_DVVIDEO, - CODEC_ID_DVAUDIO, - dv_write_header, - dv_write_packet, - dv_write_trailer, -}; -#endif - -int dv_init(void) -{ - av_register_input_format(&dv_iformat); - // av_register_output_format(&dv_oformat); - return 0; -} diff --git a/libav/ffm.c b/libav/ffm.c deleted file mode 100644 index c21599c69f..0000000000 --- a/libav/ffm.c +++ /dev/null @@ -1,684 +0,0 @@ -/* - * FFM (ffserver live feed) encoder and decoder - * Copyright (c) 2001 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" -#include <unistd.h> - -/* The FFM file is made of blocks of fixed size */ -#define FFM_HEADER_SIZE 14 -#define PACKET_ID 0x666d - -/* each packet contains frames (which can span several packets */ -#define FRAME_HEADER_SIZE 8 -#define FLAG_KEY_FRAME 0x01 - -typedef struct FFMStream { - INT64 pts; -} FFMStream; - -enum { - READ_HEADER, - READ_DATA, -}; - -typedef struct FFMContext { - /* only reading mode */ - offset_t write_index, file_size; - int read_state; - UINT8 header[FRAME_HEADER_SIZE]; - - /* read and write */ - int first_packet; /* true if first packet, needed to set the discontinuity tag */ - int packet_size; - int frame_offset; - INT64 pts; - UINT8 *packet_ptr, *packet_end; - UINT8 packet[FFM_PACKET_SIZE]; -} FFMContext; - -/* disable pts hack for testing */ -int ffm_nopts = 0; - -static void flush_packet(AVFormatContext *s) -{ - FFMContext *ffm = s->priv_data; - int fill_size, h; - ByteIOContext *pb = &s->pb; - - fill_size = ffm->packet_end - ffm->packet_ptr; - memset(ffm->packet_ptr, 0, fill_size); - - /* put header */ - put_be16(pb, PACKET_ID); - put_be16(pb, fill_size); - put_be64(pb, ffm->pts); - h = ffm->frame_offset; - if (ffm->first_packet) - h |= 0x8000; - put_be16(pb, h); - put_buffer(pb, ffm->packet, ffm->packet_end - ffm->packet); - - /* prepare next packet */ - ffm->frame_offset = 0; /* no key frame */ - ffm->pts = 0; /* no pts */ - ffm->packet_ptr = ffm->packet; - ffm->first_packet = 0; -} - -/* 'first' is true if first data of a frame */ -static void ffm_write_data(AVFormatContext *s, - UINT8 *buf, int size, - INT64 pts, int first) -{ - FFMContext *ffm = s->priv_data; - int len; - - if (first && ffm->frame_offset == 0) - ffm->frame_offset = ffm->packet_ptr - ffm->packet + FFM_HEADER_SIZE; - if (first && ffm->pts == 0) - ffm->pts = pts; - - /* write as many packets as needed */ - while (size > 0) { - len = ffm->packet_end - ffm->packet_ptr; - if (len > size) - len = size; - memcpy(ffm->packet_ptr, buf, len); - - ffm->packet_ptr += len; - buf += len; - size -= len; - if (ffm->packet_ptr >= ffm->packet_end) { - /* special case : no pts in packet : we leave the current one */ - if (ffm->pts == 0) - ffm->pts = pts; - - flush_packet(s); - } - } -} - -static int ffm_write_header(AVFormatContext *s) -{ - FFMContext *ffm = s->priv_data; - AVStream *st; - FFMStream *fst; - ByteIOContext *pb = &s->pb; - AVCodecContext *codec; - int bit_rate, i; - - ffm->packet_size = FFM_PACKET_SIZE; - - /* header */ - put_tag(pb, "FFM1"); - put_be32(pb, ffm->packet_size); - /* XXX: store write position in other file ? */ - put_be64(pb, ffm->packet_size); /* current write position */ - - put_be32(pb, s->nb_streams); - bit_rate = 0; - for(i=0;i<s->nb_streams;i++) { - st = s->streams[i]; - bit_rate += st->codec.bit_rate; - } - put_be32(pb, bit_rate); - - /* list of streams */ - for(i=0;i<s->nb_streams;i++) { - st = s->streams[i]; - fst = av_mallocz(sizeof(FFMStream)); - if (!fst) - goto fail; - st->priv_data = fst; - - codec = &st->codec; - /* generic info */ - put_be32(pb, codec->codec_id); - put_byte(pb, codec->codec_type); - put_be32(pb, codec->bit_rate); - put_be32(pb, codec->quality); - put_be32(pb, codec->flags); - /* specific info */ - switch(codec->codec_type) { - case CODEC_TYPE_VIDEO: - put_be32(pb, (codec->frame_rate * 1000) / FRAME_RATE_BASE); - put_be16(pb, codec->width); - put_be16(pb, codec->height); - put_be16(pb, codec->gop_size); - put_byte(pb, codec->qmin); - put_byte(pb, codec->qmax); - put_byte(pb, codec->max_qdiff); - put_be16(pb, (int) (codec->qcompress * 10000.0)); - put_be16(pb, (int) (codec->qblur * 10000.0)); - put_be32(pb, codec->bit_rate_tolerance); - put_strz(pb, codec->rc_eq); - put_be32(pb, codec->rc_max_rate); - put_be32(pb, codec->rc_min_rate); - put_be32(pb, codec->rc_buffer_size); - put_be64_double(pb, codec->i_quant_factor); - put_be64_double(pb, codec->b_quant_factor); - put_be64_double(pb, codec->i_quant_offset); - put_be64_double(pb, codec->b_quant_offset); - put_be32(pb, codec->dct_algo); - break; - case CODEC_TYPE_AUDIO: - put_be32(pb, codec->sample_rate); - put_le16(pb, codec->channels); - put_le16(pb, codec->frame_size); - break; - default: - av_abort(); - } - /* hack to have real time */ - if (ffm_nopts) - fst->pts = 0; - else - fst->pts = av_gettime(); - } - - /* flush until end of block reached */ - while ((url_ftell(pb) % ffm->packet_size) != 0) - put_byte(pb, 0); - - put_flush_packet(pb); - - /* init packet mux */ - ffm->packet_ptr = ffm->packet; - ffm->packet_end = ffm->packet + ffm->packet_size - FFM_HEADER_SIZE; - ffm->frame_offset = 0; - ffm->pts = 0; - ffm->first_packet = 1; - - return 0; - fail: - for(i=0;i<s->nb_streams;i++) { - st = s->streams[i]; - av_freep(&st->priv_data); - } - return -1; -} - -static int ffm_write_packet(AVFormatContext *s, int stream_index, - UINT8 *buf, int size, int force_pts) -{ - AVStream *st = s->streams[stream_index]; - FFMStream *fst = st->priv_data; - INT64 pts; - UINT8 header[FRAME_HEADER_SIZE]; - int duration; - - if (st->codec.codec_type == CODEC_TYPE_AUDIO) { - duration = ((float)st->codec.frame_size / st->codec.sample_rate * 1000000.0); - } else { - duration = (1000000.0 * FRAME_RATE_BASE / (float)st->codec.frame_rate); - } - - pts = fst->pts; - /* packet size & key_frame */ - header[0] = stream_index; - header[1] = 0; - if (st->codec.key_frame) - header[1] |= FLAG_KEY_FRAME; - header[2] = (size >> 16) & 0xff; - header[3] = (size >> 8) & 0xff; - header[4] = size & 0xff; - header[5] = (duration >> 16) & 0xff; - header[6] = (duration >> 8) & 0xff; - header[7] = duration & 0xff; - ffm_write_data(s, header, FRAME_HEADER_SIZE, pts, 1); - ffm_write_data(s, buf, size, pts, 0); - - fst->pts += duration; - return 0; -} - -static int ffm_write_trailer(AVFormatContext *s) -{ - ByteIOContext *pb = &s->pb; - FFMContext *ffm = s->priv_data; - int i; - - /* flush packets */ - if (ffm->packet_ptr > ffm->packet) - flush_packet(s); - - put_flush_packet(pb); - - if (!url_is_streamed(pb)) { - INT64 size; - /* update the write offset */ - size = url_ftell(pb); - url_fseek(pb, 8, SEEK_SET); - put_be64(pb, size); - put_flush_packet(pb); - } - - for(i=0;i<s->nb_streams;i++) - av_freep(&s->streams[i]->priv_data); - return 0; -} - -/* ffm demux */ - -static int ffm_is_avail_data(AVFormatContext *s, int size) -{ - FFMContext *ffm = s->priv_data; - offset_t pos, avail_size; - int len; - - len = ffm->packet_end - ffm->packet_ptr; - if (!ffm_nopts) { - /* XXX: I don't understand this test, so I disabled it for testing */ - if (size <= len) - return 1; - } - pos = url_ftell(&s->pb); - if (pos == ffm->write_index) { - /* exactly at the end of stream */ - return 0; - } else if (pos < ffm->write_index) { - avail_size = ffm->write_index - pos; - } else { - avail_size = (ffm->file_size - pos) + (ffm->write_index - FFM_PACKET_SIZE); - } - avail_size = (avail_size / ffm->packet_size) * (ffm->packet_size - FFM_HEADER_SIZE) + len; - if (size <= avail_size) - return 1; - else - return 0; -} - -/* first is true if we read the frame header */ -static int ffm_read_data(AVFormatContext *s, - UINT8 *buf, int size, int first) -{ - FFMContext *ffm = s->priv_data; - ByteIOContext *pb = &s->pb; - int len, fill_size, size1, frame_offset; - - size1 = size; - while (size > 0) { - redo: - len = ffm->packet_end - ffm->packet_ptr; - if (len > size) - len = size; - if (len == 0) { - if (url_ftell(pb) == ffm->file_size) - url_fseek(pb, ffm->packet_size, SEEK_SET); - retry_read: - get_be16(pb); /* PACKET_ID */ - fill_size = get_be16(pb); - ffm->pts = get_be64(pb); - frame_offset = get_be16(pb); - get_buffer(pb, ffm->packet, ffm->packet_size - FFM_HEADER_SIZE); - ffm->packet_end = ffm->packet + (ffm->packet_size - FFM_HEADER_SIZE - fill_size); - /* if first packet or resynchronization packet, we must - handle it specifically */ - if (ffm->first_packet || (frame_offset & 0x8000)) { - if (!frame_offset) { - /* This packet has no frame headers in it */ - if (url_ftell(pb) >= ffm->packet_size * 3) { - url_fseek(pb, -ffm->packet_size * 2, SEEK_CUR); - goto retry_read; - } - /* This is bad, we cannot find a valid frame header */ - return 0; - } - ffm->first_packet = 0; - if ((frame_offset & 0x7ffff) < FFM_HEADER_SIZE) - av_abort(); - ffm->packet_ptr = ffm->packet + (frame_offset & 0x7fff) - FFM_HEADER_SIZE; - if (!first) - break; - } else { - ffm->packet_ptr = ffm->packet; - } - goto redo; - } - memcpy(buf, ffm->packet_ptr, len); - buf += len; - ffm->packet_ptr += len; - size -= len; - first = 0; - } - return size1 - size; -} - - -static int ffm_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - FFMContext *ffm = s->priv_data; - AVStream *st; - FFMStream *fst; - ByteIOContext *pb = &s->pb; - AVCodecContext *codec; - int i; - UINT32 tag; - - /* header */ - tag = get_le32(pb); - if (tag != MKTAG('F', 'F', 'M', '1')) - goto fail; - ffm->packet_size = get_be32(pb); - if (ffm->packet_size != FFM_PACKET_SIZE) - goto fail; - ffm->write_index = get_be64(pb); - /* get also filesize */ - if (!url_is_streamed(pb)) { - ffm->file_size = url_filesize(url_fileno(pb)); - } else { - ffm->file_size = (UINT64_C(1) << 63) - 1; - } - - s->nb_streams = get_be32(pb); - get_be32(pb); /* total bitrate */ - /* read each stream */ - for(i=0;i<s->nb_streams;i++) { - char rc_eq_buf[128]; - - st = av_mallocz(sizeof(AVStream)); - if (!st) - goto fail; - s->streams[i] = st; - fst = av_mallocz(sizeof(FFMStream)); - if (!fst) - goto fail; - st->priv_data = fst; - - codec = &st->codec; - /* generic info */ - st->codec.codec_id = get_be32(pb); - st->codec.codec_type = get_byte(pb); /* codec_type */ - codec->bit_rate = get_be32(pb); - codec->quality = get_be32(pb); - codec->flags = get_be32(pb); - /* specific info */ - switch(codec->codec_type) { - case CODEC_TYPE_VIDEO: - codec->frame_rate = ((INT64)get_be32(pb) * FRAME_RATE_BASE) / 1000; - codec->width = get_be16(pb); - codec->height = get_be16(pb); - codec->gop_size = get_be16(pb); - codec->qmin = get_byte(pb); - codec->qmax = get_byte(pb); - codec->max_qdiff = get_byte(pb); - codec->qcompress = get_be16(pb) / 10000.0; - codec->qblur = get_be16(pb) / 10000.0; - codec->bit_rate_tolerance = get_be32(pb); - codec->rc_eq = strdup(get_strz(pb, rc_eq_buf, sizeof(rc_eq_buf))); - codec->rc_max_rate = get_be32(pb); - codec->rc_min_rate = get_be32(pb); - codec->rc_buffer_size = get_be32(pb); - codec->i_quant_factor = get_be64_double(pb); - codec->b_quant_factor = get_be64_double(pb); - codec->i_quant_offset = get_be64_double(pb); - codec->b_quant_offset = get_be64_double(pb); - codec->dct_algo = get_be32(pb); - break; - case CODEC_TYPE_AUDIO: - codec->sample_rate = get_be32(pb); - codec->channels = get_le16(pb); - codec->frame_size = get_le16(pb); - break; - default: - goto fail; - } - - } - - /* get until end of block reached */ - while ((url_ftell(pb) % ffm->packet_size) != 0) - get_byte(pb); - - /* init packet demux */ - ffm->packet_ptr = ffm->packet; - ffm->packet_end = ffm->packet; - ffm->frame_offset = 0; - ffm->pts = 0; - ffm->read_state = READ_HEADER; - ffm->first_packet = 1; - return 0; - fail: - for(i=0;i<s->nb_streams;i++) { - st = s->streams[i]; - if (st) { - av_freep(&st->priv_data); - av_free(st); - } - } - return -1; -} - -/* return < 0 if eof */ -static int ffm_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int size; - FFMContext *ffm = s->priv_data; - int duration; - - switch(ffm->read_state) { - case READ_HEADER: - if (!ffm_is_avail_data(s, FRAME_HEADER_SIZE)) { - return -EAGAIN; - } -#if 0 - printf("pos=%08Lx spos=%Lx, write_index=%Lx size=%Lx\n", - url_ftell(&s->pb), s->pb.pos, ffm->write_index, ffm->file_size); -#endif - if (ffm_read_data(s, ffm->header, FRAME_HEADER_SIZE, 1) != - FRAME_HEADER_SIZE) - return -EAGAIN; -#if 0 - { - int i; - for(i=0;i<FRAME_HEADER_SIZE;i++) - printf("%02x ", ffm->header[i]); - printf("\n"); - } -#endif - ffm->read_state = READ_DATA; - /* fall thru */ - case READ_DATA: - size = (ffm->header[2] << 16) | (ffm->header[3] << 8) | ffm->header[4]; - if (!ffm_is_avail_data(s, size)) { - return -EAGAIN; - } - - duration = (ffm->header[5] << 16) | (ffm->header[6] << 8) | ffm->header[7]; - - av_new_packet(pkt, size); - pkt->stream_index = ffm->header[0]; - if (ffm->header[1] & FLAG_KEY_FRAME) - pkt->flags |= PKT_FLAG_KEY; - - ffm->read_state = READ_HEADER; - if (ffm_read_data(s, pkt->data, size, 0) != size) { - /* bad case: desynchronized packet. we cancel all the packet loading */ - av_free_packet(pkt); - return -EAGAIN; - } - pkt->pts = ffm->pts; - pkt->duration = duration; - break; - } - return 0; -} - -//#define DEBUG_SEEK - -/* pos is between 0 and file_size - FFM_PACKET_SIZE. It is translated - by the write position inside this function */ -static void ffm_seek1(AVFormatContext *s, offset_t pos1) -{ - FFMContext *ffm = s->priv_data; - ByteIOContext *pb = &s->pb; - offset_t pos; - - pos = pos1 + ffm->write_index; - if (pos >= ffm->file_size) - pos -= (ffm->file_size - FFM_PACKET_SIZE); -#ifdef DEBUG_SEEK - printf("seek to %Lx -> %Lx\n", pos1, pos); -#endif - url_fseek(pb, pos, SEEK_SET); -} - -static INT64 get_pts(AVFormatContext *s, offset_t pos) -{ - ByteIOContext *pb = &s->pb; - INT64 pts; - - ffm_seek1(s, pos); - url_fskip(pb, 4); - pts = get_be64(pb); -#ifdef DEBUG_SEEK - printf("pts=%0.6f\n", pts / 1000000.0); -#endif - return pts; -} - -/* seek to a given time in the file. The file read pointer is - positionned at or before pts. XXX: the following code is quite - approximative */ -static int ffm_seek(AVFormatContext *s, INT64 wanted_pts) -{ - FFMContext *ffm = s->priv_data; - offset_t pos_min, pos_max, pos; - INT64 pts_min, pts_max, pts; - double pos1; - -#ifdef DEBUG_SEEK - printf("wanted_pts=%0.6f\n", wanted_pts / 1000000.0); -#endif - /* find the position using linear interpolation (better than - dichotomy in typical cases) */ - pos_min = 0; - pos_max = ffm->file_size - 2 * FFM_PACKET_SIZE; - while (pos_min <= pos_max) { - pts_min = get_pts(s, pos_min); - pts_max = get_pts(s, pos_max); - /* linear interpolation */ - pos1 = (double)(pos_max - pos_min) * (double)(wanted_pts - pts_min) / - (double)(pts_max - pts_min); - pos = (((INT64)pos1) / FFM_PACKET_SIZE) * FFM_PACKET_SIZE; - if (pos <= pos_min) - pos = pos_min; - else if (pos >= pos_max) - pos = pos_max; - pts = get_pts(s, pos); - /* check if we are lucky */ - if (pts == wanted_pts) { - goto found; - } else if (pts > wanted_pts) { - pos_max = pos - FFM_PACKET_SIZE; - } else { - pos_min = pos + FFM_PACKET_SIZE; - } - } - pos = pos_min; - if (pos > 0) - pos -= FFM_PACKET_SIZE; - found: - ffm_seek1(s, pos); - return 0; -} - -offset_t ffm_read_write_index(int fd) -{ - UINT8 buf[8]; - offset_t pos; - int i; - - lseek(fd, 8, SEEK_SET); - read(fd, buf, 8); - pos = 0; - for(i=0;i<8;i++) - pos |= buf[i] << (56 - i * 8); - return pos; -} - -void ffm_write_write_index(int fd, offset_t pos) -{ - UINT8 buf[8]; - int i; - - for(i=0;i<8;i++) - buf[i] = (pos >> (56 - i * 8)) & 0xff; - lseek(fd, 8, SEEK_SET); - write(fd, buf, 8); -} - -void ffm_set_write_index(AVFormatContext *s, offset_t pos, offset_t file_size) -{ - FFMContext *ffm = s->priv_data; - ffm->write_index = pos; - ffm->file_size = file_size; -} - -static int ffm_read_close(AVFormatContext *s) -{ - AVStream *st; - int i; - - for(i=0;i<s->nb_streams;i++) { - st = s->streams[i]; - av_freep(&st->priv_data); - } - return 0; -} - -static int ffm_probe(AVProbeData *p) -{ - if (p->buf_size >= 4 && - p->buf[0] == 'F' && p->buf[1] == 'F' && p->buf[2] == 'M' && - p->buf[3] == '1') - return AVPROBE_SCORE_MAX + 1; - return 0; -} - -static AVInputFormat ffm_iformat = { - "ffm", - "ffm format", - sizeof(FFMContext), - ffm_probe, - ffm_read_header, - ffm_read_packet, - ffm_read_close, - ffm_seek, -}; - -static AVOutputFormat ffm_oformat = { - "ffm", - "ffm format", - "", - "ffm", - sizeof(FFMContext), - /* not really used */ - CODEC_ID_MP2, - CODEC_ID_MPEG1VIDEO, - ffm_write_header, - ffm_write_packet, - ffm_write_trailer, -}; - -int ffm_init(void) -{ - av_register_input_format(&ffm_iformat); - av_register_output_format(&ffm_oformat); - return 0; -} diff --git a/libav/file.c b/libav/file.c deleted file mode 100644 index 8206ff9255..0000000000 --- a/libav/file.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Buffered file io for ffmpeg system - * Copyright (c) 2001 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" -#include <fcntl.h> -#ifndef CONFIG_WIN32 -#include <unistd.h> -#include <sys/ioctl.h> -#include <sys/time.h> -#else -#include <io.h> -#define open(fname,oflag,pmode) _open(fname,oflag,pmode) -#endif /* CONFIG_WIN32 */ - - -/* standard file protocol */ - -static int file_open(URLContext *h, const char *filename, int flags) -{ - int access; - int fd; - - if (flags & URL_WRONLY) { - access = O_CREAT | O_TRUNC | O_WRONLY; - } else { - access = O_RDONLY; - } -#ifdef CONFIG_WIN32 - access |= O_BINARY; -#endif - fd = open(filename, access, 0666); - if (fd < 0) - return -ENOENT; - h->priv_data = (void *)fd; - return 0; -} - -static int file_read(URLContext *h, unsigned char *buf, int size) -{ - int fd = (int)h->priv_data; - return read(fd, buf, size); -} - -static int file_write(URLContext *h, unsigned char *buf, int size) -{ - int fd = (int)h->priv_data; - return write(fd, buf, size); -} - -/* XXX: use llseek */ -static offset_t file_seek(URLContext *h, offset_t pos, int whence) -{ - int fd = (int)h->priv_data; -#ifdef CONFIG_WIN32 - return _lseeki64(fd, pos, whence); -#else - return lseek(fd, pos, whence); -#endif -} - -static int file_close(URLContext *h) -{ - int fd = (int)h->priv_data; - return close(fd); -} - -URLProtocol file_protocol = { - "file", - file_open, - file_read, - file_write, - file_seek, - file_close, -}; - -/* pipe protocol */ - -static int pipe_open(URLContext *h, const char *filename, int flags) -{ - int fd; - - if (flags & URL_WRONLY) { - fd = 1; - } else { - fd = 0; - } - h->priv_data = (void *)fd; - return 0; -} - -static int pipe_read(URLContext *h, unsigned char *buf, int size) -{ - int fd = (int)h->priv_data; - return read(fd, buf, size); -} - -static int pipe_write(URLContext *h, unsigned char *buf, int size) -{ - int fd = (int)h->priv_data; - return write(fd, buf, size); -} - -static int pipe_close(URLContext *h) -{ - return 0; -} - -URLProtocol pipe_protocol = { - "pipe", - pipe_open, - pipe_read, - pipe_write, - NULL, - pipe_close, -}; diff --git a/libav/framehook.c b/libav/framehook.c deleted file mode 100644 index 03ee32e188..0000000000 --- a/libav/framehook.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Video processing hooks - * Copyright (c) 2000, 2001 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include <errno.h> -#include "config.h" -#include "framehook.h" -#include "avformat.h" - -#ifdef HAVE_VHOOK -#include <dlfcn.h> -#endif - - -typedef struct _FrameHookEntry { - struct _FrameHookEntry *next; - FrameHookConfigureFn Configure; - FrameHookProcessFn Process; - void *ctx; -} FrameHookEntry; - -static FrameHookEntry *first_hook; - -/* Returns 0 on OK */ -int frame_hook_add(int argc, char *argv[]) -{ -#ifdef HAVE_VHOOK - void *loaded; - FrameHookEntry *fhe, **fhep; - - if (argc < 1) { - return ENOENT; - } - - loaded = dlopen(argv[0], RTLD_NOW); - if (!loaded) { - fprintf(stderr, "%s\n", dlerror()); - return -1; - } - - fhe = av_mallocz(sizeof(*fhe)); - if (!fhe) { - return errno; - } - - fhe->Configure = dlsym(loaded, "Configure"); - fhe->Process = dlsym(loaded, "Process"); - - if (!fhe->Process) { - fprintf(stderr, "Failed to find Process entrypoint in %s\n", argv[0]); - return -1; - } - - if (!fhe->Configure && argc > 1) { - fprintf(stderr, "Failed to find Configure entrypoint in %s\n", argv[0]); - return -1; - } - - if (argc > 1 || fhe->Configure) { - if (fhe->Configure(&fhe->ctx, argc, argv)) { - fprintf(stderr, "Failed to Configure %s\n", argv[0]); - return -1; - } - } - - for (fhep = &first_hook; *fhep; fhep = &((*fhep)->next)) { - } - - *fhep = fhe; - - return 0; -#else - fprintf(stderr, "Video hooking not compiled into this version\n"); - return 1; -#endif -} - -void frame_hook_process(AVPicture *pict, enum PixelFormat pix_fmt, int width, int height) -{ - if (first_hook) { - FrameHookEntry *fhe; - INT64 pts = av_gettime(); - - for (fhe = first_hook; fhe; fhe = fhe->next) { - fhe->Process(fhe->ctx, pict, pix_fmt, width, height, pts); - } - } -} diff --git a/libav/framehook.h b/libav/framehook.h deleted file mode 100644 index eb1a51f7e4..0000000000 --- a/libav/framehook.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef _FRAMEHOOK_H -#define _FRAMEHOOK_H - -/* - * Prototypes for interface to .so that implement a video processing hook - */ - -#include "avcodec.h" - -/* Function must be called 'Configure' */ -typedef int (*FrameHookConfigureFn)(void **ctxp, int argc, char *argv[]); - -/* Function must be called 'Process' */ -typedef void (*FrameHookProcessFn)(void *ctx, struct AVPicture *pict, enum PixelFormat pix_fmt, int width, int height, INT64 pts); - -extern int frame_hook_add(int argc, char *argv[]); -extern void frame_hook_process(struct AVPicture *pict, enum PixelFormat pix_fmt, int width, int height); - -#endif diff --git a/libav/gif.c b/libav/gif.c deleted file mode 100644 index 6becf52a49..0000000000 --- a/libav/gif.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - * Animated GIF encoder - * Copyright (c) 2000 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ - -/* - * First version by Francois Revol revol@free.fr - * - * Features and limitations: - * - currently no compression is performed, - * in fact the size of the data is 9/8 the size of the image in 8bpp - * - uses only a global standard palette - * - tested with IE 5.0, Opera for BeOS, NetPositive (BeOS), and Mozilla (BeOS). - * - * Reference documents: - * http://www.goice.co.jp/member/mo/formats/gif.html - * http://astronomy.swin.edu.au/pbourke/dataformats/gif/ - * http://www.dcs.ed.ac.uk/home/mxr/gfx/2d/GIF89a.txt - * - * this url claims to have an LZW algorithm not covered by Unisys patent: - * http://www.msg.net/utility/whirlgif/gifencod.html - * could help reduce the size of the files _a lot_... - * some sites mentions an RLE type compression also. - */ - -#include "avformat.h" - -/* bitstream minipacket size */ -#define GIF_CHUNKS 100 - -/* slows down the decoding (and some browsers doesn't like it) */ -/* #define GIF_ADD_APP_HEADER */ - -typedef struct { - unsigned char r; - unsigned char g; - unsigned char b; -} rgb_triplet; - -/* we use the standard 216 color palette */ - -/* this script was used to create the palette: - * for r in 00 33 66 99 cc ff; do for g in 00 33 66 99 cc ff; do echo -n " "; for b in 00 33 66 99 cc ff; do - * echo -n "{ 0x$r, 0x$g, 0x$b }, "; done; echo ""; done; done - */ - -static const rgb_triplet gif_clut[216] = { - { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x33 }, { 0x00, 0x00, 0x66 }, { 0x00, 0x00, 0x99 }, { 0x00, 0x00, 0xcc }, { 0x00, 0x00, 0xff }, - { 0x00, 0x33, 0x00 }, { 0x00, 0x33, 0x33 }, { 0x00, 0x33, 0x66 }, { 0x00, 0x33, 0x99 }, { 0x00, 0x33, 0xcc }, { 0x00, 0x33, 0xff }, - { 0x00, 0x66, 0x00 }, { 0x00, 0x66, 0x33 }, { 0x00, 0x66, 0x66 }, { 0x00, 0x66, 0x99 }, { 0x00, 0x66, 0xcc }, { 0x00, 0x66, 0xff }, - { 0x00, 0x99, 0x00 }, { 0x00, 0x99, 0x33 }, { 0x00, 0x99, 0x66 }, { 0x00, 0x99, 0x99 }, { 0x00, 0x99, 0xcc }, { 0x00, 0x99, 0xff }, - { 0x00, 0xcc, 0x00 }, { 0x00, 0xcc, 0x33 }, { 0x00, 0xcc, 0x66 }, { 0x00, 0xcc, 0x99 }, { 0x00, 0xcc, 0xcc }, { 0x00, 0xcc, 0xff }, - { 0x00, 0xff, 0x00 }, { 0x00, 0xff, 0x33 }, { 0x00, 0xff, 0x66 }, { 0x00, 0xff, 0x99 }, { 0x00, 0xff, 0xcc }, { 0x00, 0xff, 0xff }, - { 0x33, 0x00, 0x00 }, { 0x33, 0x00, 0x33 }, { 0x33, 0x00, 0x66 }, { 0x33, 0x00, 0x99 }, { 0x33, 0x00, 0xcc }, { 0x33, 0x00, 0xff }, - { 0x33, 0x33, 0x00 }, { 0x33, 0x33, 0x33 }, { 0x33, 0x33, 0x66 }, { 0x33, 0x33, 0x99 }, { 0x33, 0x33, 0xcc }, { 0x33, 0x33, 0xff }, - { 0x33, 0x66, 0x00 }, { 0x33, 0x66, 0x33 }, { 0x33, 0x66, 0x66 }, { 0x33, 0x66, 0x99 }, { 0x33, 0x66, 0xcc }, { 0x33, 0x66, 0xff }, - { 0x33, 0x99, 0x00 }, { 0x33, 0x99, 0x33 }, { 0x33, 0x99, 0x66 }, { 0x33, 0x99, 0x99 }, { 0x33, 0x99, 0xcc }, { 0x33, 0x99, 0xff }, - { 0x33, 0xcc, 0x00 }, { 0x33, 0xcc, 0x33 }, { 0x33, 0xcc, 0x66 }, { 0x33, 0xcc, 0x99 }, { 0x33, 0xcc, 0xcc }, { 0x33, 0xcc, 0xff }, - { 0x33, 0xff, 0x00 }, { 0x33, 0xff, 0x33 }, { 0x33, 0xff, 0x66 }, { 0x33, 0xff, 0x99 }, { 0x33, 0xff, 0xcc }, { 0x33, 0xff, 0xff }, - { 0x66, 0x00, 0x00 }, { 0x66, 0x00, 0x33 }, { 0x66, 0x00, 0x66 }, { 0x66, 0x00, 0x99 }, { 0x66, 0x00, 0xcc }, { 0x66, 0x00, 0xff }, - { 0x66, 0x33, 0x00 }, { 0x66, 0x33, 0x33 }, { 0x66, 0x33, 0x66 }, { 0x66, 0x33, 0x99 }, { 0x66, 0x33, 0xcc }, { 0x66, 0x33, 0xff }, - { 0x66, 0x66, 0x00 }, { 0x66, 0x66, 0x33 }, { 0x66, 0x66, 0x66 }, { 0x66, 0x66, 0x99 }, { 0x66, 0x66, 0xcc }, { 0x66, 0x66, 0xff }, - { 0x66, 0x99, 0x00 }, { 0x66, 0x99, 0x33 }, { 0x66, 0x99, 0x66 }, { 0x66, 0x99, 0x99 }, { 0x66, 0x99, 0xcc }, { 0x66, 0x99, 0xff }, - { 0x66, 0xcc, 0x00 }, { 0x66, 0xcc, 0x33 }, { 0x66, 0xcc, 0x66 }, { 0x66, 0xcc, 0x99 }, { 0x66, 0xcc, 0xcc }, { 0x66, 0xcc, 0xff }, - { 0x66, 0xff, 0x00 }, { 0x66, 0xff, 0x33 }, { 0x66, 0xff, 0x66 }, { 0x66, 0xff, 0x99 }, { 0x66, 0xff, 0xcc }, { 0x66, 0xff, 0xff }, - { 0x99, 0x00, 0x00 }, { 0x99, 0x00, 0x33 }, { 0x99, 0x00, 0x66 }, { 0x99, 0x00, 0x99 }, { 0x99, 0x00, 0xcc }, { 0x99, 0x00, 0xff }, - { 0x99, 0x33, 0x00 }, { 0x99, 0x33, 0x33 }, { 0x99, 0x33, 0x66 }, { 0x99, 0x33, 0x99 }, { 0x99, 0x33, 0xcc }, { 0x99, 0x33, 0xff }, - { 0x99, 0x66, 0x00 }, { 0x99, 0x66, 0x33 }, { 0x99, 0x66, 0x66 }, { 0x99, 0x66, 0x99 }, { 0x99, 0x66, 0xcc }, { 0x99, 0x66, 0xff }, - { 0x99, 0x99, 0x00 }, { 0x99, 0x99, 0x33 }, { 0x99, 0x99, 0x66 }, { 0x99, 0x99, 0x99 }, { 0x99, 0x99, 0xcc }, { 0x99, 0x99, 0xff }, - { 0x99, 0xcc, 0x00 }, { 0x99, 0xcc, 0x33 }, { 0x99, 0xcc, 0x66 }, { 0x99, 0xcc, 0x99 }, { 0x99, 0xcc, 0xcc }, { 0x99, 0xcc, 0xff }, - { 0x99, 0xff, 0x00 }, { 0x99, 0xff, 0x33 }, { 0x99, 0xff, 0x66 }, { 0x99, 0xff, 0x99 }, { 0x99, 0xff, 0xcc }, { 0x99, 0xff, 0xff }, - { 0xcc, 0x00, 0x00 }, { 0xcc, 0x00, 0x33 }, { 0xcc, 0x00, 0x66 }, { 0xcc, 0x00, 0x99 }, { 0xcc, 0x00, 0xcc }, { 0xcc, 0x00, 0xff }, - { 0xcc, 0x33, 0x00 }, { 0xcc, 0x33, 0x33 }, { 0xcc, 0x33, 0x66 }, { 0xcc, 0x33, 0x99 }, { 0xcc, 0x33, 0xcc }, { 0xcc, 0x33, 0xff }, - { 0xcc, 0x66, 0x00 }, { 0xcc, 0x66, 0x33 }, { 0xcc, 0x66, 0x66 }, { 0xcc, 0x66, 0x99 }, { 0xcc, 0x66, 0xcc }, { 0xcc, 0x66, 0xff }, - { 0xcc, 0x99, 0x00 }, { 0xcc, 0x99, 0x33 }, { 0xcc, 0x99, 0x66 }, { 0xcc, 0x99, 0x99 }, { 0xcc, 0x99, 0xcc }, { 0xcc, 0x99, 0xff }, - { 0xcc, 0xcc, 0x00 }, { 0xcc, 0xcc, 0x33 }, { 0xcc, 0xcc, 0x66 }, { 0xcc, 0xcc, 0x99 }, { 0xcc, 0xcc, 0xcc }, { 0xcc, 0xcc, 0xff }, - { 0xcc, 0xff, 0x00 }, { 0xcc, 0xff, 0x33 }, { 0xcc, 0xff, 0x66 }, { 0xcc, 0xff, 0x99 }, { 0xcc, 0xff, 0xcc }, { 0xcc, 0xff, 0xff }, - { 0xff, 0x00, 0x00 }, { 0xff, 0x00, 0x33 }, { 0xff, 0x00, 0x66 }, { 0xff, 0x00, 0x99 }, { 0xff, 0x00, 0xcc }, { 0xff, 0x00, 0xff }, - { 0xff, 0x33, 0x00 }, { 0xff, 0x33, 0x33 }, { 0xff, 0x33, 0x66 }, { 0xff, 0x33, 0x99 }, { 0xff, 0x33, 0xcc }, { 0xff, 0x33, 0xff }, - { 0xff, 0x66, 0x00 }, { 0xff, 0x66, 0x33 }, { 0xff, 0x66, 0x66 }, { 0xff, 0x66, 0x99 }, { 0xff, 0x66, 0xcc }, { 0xff, 0x66, 0xff }, - { 0xff, 0x99, 0x00 }, { 0xff, 0x99, 0x33 }, { 0xff, 0x99, 0x66 }, { 0xff, 0x99, 0x99 }, { 0xff, 0x99, 0xcc }, { 0xff, 0x99, 0xff }, - { 0xff, 0xcc, 0x00 }, { 0xff, 0xcc, 0x33 }, { 0xff, 0xcc, 0x66 }, { 0xff, 0xcc, 0x99 }, { 0xff, 0xcc, 0xcc }, { 0xff, 0xcc, 0xff }, - { 0xff, 0xff, 0x00 }, { 0xff, 0xff, 0x33 }, { 0xff, 0xff, 0x66 }, { 0xff, 0xff, 0x99 }, { 0xff, 0xff, 0xcc }, { 0xff, 0xff, 0xff }, -}; - -/* The GIF format uses reversed order for bitstreams... */ -/* at least they don't use PDP_ENDIAN :) */ -/* so we 'extend' PutBitContext. hmmm, OOP :) */ -/* seems this thing changed slightly since I wrote it... */ - -#ifdef ALT_BITSTREAM_WRITER -# error no ALT_BITSTREAM_WRITER support for now -#endif - -static void gif_put_bits_rev(PutBitContext *s, int n, unsigned int value) -{ - unsigned int bit_buf; - int bit_cnt; - -#ifdef STATS - st_out_bit_counts[st_current_index] += n; -#endif - // printf("put_bits=%d %x\n", n, value); - assert(n == 32 || value < (1U << n)); - - bit_buf = s->bit_buf; - bit_cnt = 32 - s->bit_left; /* XXX:lazyness... was = s->bit_cnt; */ - - // printf("n=%d value=%x cnt=%d buf=%x\n", n, value, bit_cnt, bit_buf); - /* XXX: optimize */ - if (n < (32-bit_cnt)) { - bit_buf |= value << (bit_cnt); - bit_cnt+=n; - } else { - bit_buf |= value << (bit_cnt); - - *s->buf_ptr = bit_buf & 0xff; - s->buf_ptr[1] = (bit_buf >> 8) & 0xff; - s->buf_ptr[2] = (bit_buf >> 16) & 0xff; - s->buf_ptr[3] = (bit_buf >> 24) & 0xff; - - //printf("bitbuf = %08x\n", bit_buf); - s->buf_ptr+=4; - if (s->buf_ptr >= s->buf_end) - puts("bit buffer overflow !!"); // should never happen ! who got rid of the callback ??? -// flush_buffer_rev(s); - bit_cnt=bit_cnt + n - 32; - if (bit_cnt == 0) { - bit_buf = 0; - } else { - bit_buf = value >> (n - bit_cnt); - } - } - - s->bit_buf = bit_buf; - s->bit_left = 32 - bit_cnt; -} - -/* pad the end of the output stream with zeros */ -static void gif_flush_put_bits_rev(PutBitContext *s) -{ - while (s->bit_left < 32) { - /* XXX: should test end of buffer */ - *s->buf_ptr++=s->bit_buf & 0xff; - s->bit_buf>>=8; - s->bit_left+=8; - } -// flush_buffer_rev(s); - s->bit_left=32; - s->bit_buf=0; -} - -/* !RevPutBitContext */ - -typedef struct { - UINT8 buffer[100]; /* data chunks */ - INT64 time, file_time; -} GIFContext; - -static int gif_write_header(AVFormatContext *s) -{ - GIFContext *gif = s->priv_data; - ByteIOContext *pb = &s->pb; - AVCodecContext *enc, *video_enc; - int i, width, height, rate; - -/* XXX: do we reject audio streams or just ignore them ? - if(s->nb_streams > 1) - return -1; -*/ - gif->time = 0; - gif->file_time = 0; - - video_enc = NULL; - for(i=0;i<s->nb_streams;i++) { - enc = &s->streams[i]->codec; - if (enc->codec_type != CODEC_TYPE_AUDIO) - video_enc = enc; - } - - if (!video_enc) { - av_free(gif); - return -1; - } else { - width = video_enc->width; - height = video_enc->height; - rate = video_enc->frame_rate; - } - - /* XXX: is it allowed ? seems to work so far... */ - video_enc->pix_fmt = PIX_FMT_RGB24; - - /* GIF header */ - - put_tag(pb, "GIF"); - put_tag(pb, "89a"); - put_le16(pb, width); - put_le16(pb, height); - - put_byte(pb, 0xf7); /* flags: global clut, 256 entries */ - put_byte(pb, 0x1f); /* background color index */ - put_byte(pb, 0); /* aspect ratio */ - - /* the global palette */ - - put_buffer(pb, (unsigned char *)gif_clut, 216*3); - for(i=0;i<((256-216)*3);i++) - put_byte(pb, 0); - - /* application extension header */ - /* XXX: not really sure what to put in here... */ -#ifdef GIF_ADD_APP_HEADER - put_byte(pb, 0x21); - put_byte(pb, 0xff); - put_byte(pb, 0x0b); - put_tag(pb, "NETSCAPE2.0"); - put_byte(pb, 0x03); - put_byte(pb, 0x01); - put_byte(pb, 0x00); - put_byte(pb, 0x00); -#endif - - put_flush_packet(&s->pb); - return 0; -} - -/* this is maybe slow, but allows for extensions */ -static inline unsigned char gif_clut_index(rgb_triplet *clut, UINT8 r, UINT8 g, UINT8 b) -{ - return ((((r)/47)%6)*6*6+(((g)/47)%6)*6+(((b)/47)%6)); -} - -/* chunk writer callback */ -/* !!! XXX:deprecated -static void gif_put_chunk(void *pbctx, UINT8 *buffer, int count) -{ - ByteIOContext *pb = (ByteIOContext *)pbctx; - put_byte(pb, (UINT8)count); - put_buffer(pb, buffer, count); -} -*/ - -static int gif_write_video(AVFormatContext *s, - AVCodecContext *enc, UINT8 *buf, int size) -{ - ByteIOContext *pb = &s->pb; - GIFContext *gif = s->priv_data; - int i, left, jiffies; - INT64 delay; - PutBitContext p; - UINT8 buffer[200]; /* 100 * 9 / 8 = 113 */ - - - /* graphic control extension block */ - put_byte(pb, 0x21); - put_byte(pb, 0xf9); - put_byte(pb, 0x04); /* block size */ - put_byte(pb, 0x04); /* flags */ - - /* 1 jiffy is 1/70 s */ - /* the delay_time field indicates the number of jiffies - 1 */ - delay = gif->file_time - gif->time; - - /* XXX: should use delay, in order to be more accurate */ - /* instead of using the same rounded value each time */ - /* XXX: don't even remember if I really use it for now */ - jiffies = (70*FRAME_RATE_BASE/enc->frame_rate) - 1; - - put_le16(pb, jiffies); - - put_byte(pb, 0x1f); /* transparent color index */ - put_byte(pb, 0x00); - - /* image block */ - - put_byte(pb, 0x2c); - put_le16(pb, 0); - put_le16(pb, 0); - put_le16(pb, enc->width); - put_le16(pb, enc->height); - put_byte(pb, 0x00); /* flags */ - /* no local clut */ - - put_byte(pb, 0x08); - - left=size/3; - - init_put_bits(&p, buffer, 130, NULL, NULL); - -/* - * the thing here is the bitstream is written as little packets, with a size byte before - * but it's still the same bitstream between packets (no flush !) - */ - - while(left>0) { - - gif_put_bits_rev(&p, 9, 0x0100); /* clear code */ - - for(i=0;i<GIF_CHUNKS;i++) { - gif_put_bits_rev(&p, 9, gif_clut_index(NULL, *buf, buf[1], buf[2])); - buf+=3; - } - - if(left<=GIF_CHUNKS) { - gif_put_bits_rev(&p, 9, 0x101); /* end of stream */ - gif_flush_put_bits_rev(&p); - } - if(pbBufPtr(&p) - p.buf > 0) { - put_byte(pb, pbBufPtr(&p) - p.buf); /* byte count of the packet */ - put_buffer(pb, p.buf, pbBufPtr(&p) - p.buf); /* the actual buffer */ - p.data_out_size += pbBufPtr(&p) - p.buf; - p.buf_ptr = p.buf; /* dequeue the bytes off the bitstream */ - } - if(left<=GIF_CHUNKS) { - put_byte(pb, 0x00); /* end of image block */ - } - - left-=GIF_CHUNKS; - } - - put_flush_packet(&s->pb); - return 0; -} - -static int gif_write_packet(AVFormatContext *s, int stream_index, - UINT8 *buf, int size, int force_pts) -{ - AVCodecContext *codec = &s->streams[stream_index]->codec; - if (codec->codec_type == CODEC_TYPE_AUDIO) - return 0; /* just ignore audio */ - else - return gif_write_video(s, codec, buf, size); -} - -static int gif_write_trailer(AVFormatContext *s) -{ - ByteIOContext *pb = &s->pb; - - put_byte(pb, 0x3b); - put_flush_packet(&s->pb); - return 0; -} - -static AVOutputFormat gif_oformat = { - "gif", - "GIF Animation", - "image/gif", - "gif", - sizeof(GIFContext), - CODEC_ID_NONE, - CODEC_ID_RAWVIDEO, - gif_write_header, - gif_write_packet, - gif_write_trailer, -}; - -int gif_init(void) -{ - av_register_output_format(&gif_oformat); - return 0; -} diff --git a/libav/grab.c b/libav/grab.c deleted file mode 100644 index 8173bac369..0000000000 --- a/libav/grab.c +++ /dev/null @@ -1,829 +0,0 @@ -/* - * Linux video grab interface - * Copyright (c) 2000,2001 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" -#include <linux/videodev.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <sys/time.h> -#include <time.h> - -typedef struct { - int fd; - int frame_format; /* see VIDEO_PALETTE_xxx */ - int use_mmap; - int width, height; - int frame_rate; - INT64 time_frame; - int frame_size; - struct video_capability video_cap; - struct video_audio audio_saved; - UINT8 *video_buf; - struct video_mbuf gb_buffers; - struct video_mmap gb_buf; - int gb_frame; - - /* ATI All In Wonder specific stuff */ - /* XXX: remove and merge in libavcodec/imgconvert.c */ - int aiw_enabled; - int deint; - int halfw; - UINT8 *src_mem; - UINT8 *lum_m4_mem; -} VideoData; - -static int aiw_init(VideoData *s); -static int aiw_read_picture(VideoData *s, uint8_t *data); -static int aiw_close(VideoData *s); - -const char *v4l_device = "/dev/video"; - -static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap) -{ - VideoData *s = s1->priv_data; - AVStream *st; - int width, height; - int video_fd, frame_size; - int ret, frame_rate; - int desired_palette; - struct video_audio audio; - - if (!ap || ap->width <= 0 || ap->height <= 0 || ap->frame_rate <= 0) - return -1; - - width = ap->width; - height = ap->height; - frame_rate = ap->frame_rate; - - st = av_new_stream(s1, 0); - if (!st) - return -ENOMEM; - - s->width = width; - s->height = height; - s->frame_rate = frame_rate; - - video_fd = open(v4l_device, O_RDWR); - if (video_fd < 0) { - perror(v4l_device); - goto fail; - } - - if (ioctl(video_fd,VIDIOCGCAP, &s->video_cap) < 0) { - perror("VIDIOCGCAP"); - goto fail; - } - - if (!(s->video_cap.type & VID_TYPE_CAPTURE)) { - fprintf(stderr, "Fatal: grab device does not handle capture\n"); - goto fail; - } - - desired_palette = -1; - if (st->codec.pix_fmt == PIX_FMT_YUV420P) { - desired_palette = VIDEO_PALETTE_YUV420P; - } else if (st->codec.pix_fmt == PIX_FMT_YUV422) { - desired_palette = VIDEO_PALETTE_YUV422; - } else if (st->codec.pix_fmt == PIX_FMT_BGR24) { - desired_palette = VIDEO_PALETTE_RGB24; - } - - /* unmute audio */ - audio.audio = 0; - ioctl(video_fd, VIDIOCGAUDIO, &audio); - memcpy(&s->audio_saved, &audio, sizeof(audio)); - audio.flags &= ~VIDEO_AUDIO_MUTE; - ioctl(video_fd, VIDIOCSAUDIO, &audio); - - ret = ioctl(video_fd,VIDIOCGMBUF,&s->gb_buffers); - if (ret < 0) { - /* try to use read based access */ - struct video_window win; - struct video_picture pict; - int val; - - win.x = 0; - win.y = 0; - win.width = width; - win.height = height; - win.chromakey = -1; - win.flags = 0; - - ioctl(video_fd, VIDIOCSWIN, &win); - - ioctl(video_fd, VIDIOCGPICT, &pict); -#if 0 - printf("v4l: colour=%d hue=%d brightness=%d constrast=%d whiteness=%d\n", - pict.colour, - pict.hue, - pict.brightness, - pict.contrast, - pict.whiteness); -#endif - /* try to choose a suitable video format */ - pict.palette = desired_palette; - if (desired_palette == -1 || (ret = ioctl(video_fd, VIDIOCSPICT, &pict)) < 0) { - pict.palette=VIDEO_PALETTE_YUV420P; - ret = ioctl(video_fd, VIDIOCSPICT, &pict); - if (ret < 0) { - pict.palette=VIDEO_PALETTE_YUV422; - ret = ioctl(video_fd, VIDIOCSPICT, &pict); - if (ret < 0) { - pict.palette=VIDEO_PALETTE_RGB24; - ret = ioctl(video_fd, VIDIOCSPICT, &pict); - if (ret < 0) - goto fail1; - } - } - } - - s->frame_format = pict.palette; - - val = 1; - ioctl(video_fd, VIDIOCCAPTURE, &val); - - s->time_frame = av_gettime(); - s->use_mmap = 0; - - /* ATI All In Wonder automatic activation */ - if (!strcmp(s->video_cap.name, "Km")) { - if (aiw_init(s) < 0) - goto fail; - s->aiw_enabled = 1; - /* force 420P format because convertion from YUV422 to YUV420P - is done in this driver (ugly) */ - s->frame_format = VIDEO_PALETTE_YUV420P; - } - } else { - s->video_buf = mmap(0,s->gb_buffers.size,PROT_READ|PROT_WRITE,MAP_SHARED,video_fd,0); - if ((unsigned char*)-1 == s->video_buf) { - perror("mmap"); - goto fail; - } - s->gb_frame = 0; - s->time_frame = av_gettime(); - - /* start to grab the first frame */ - s->gb_buf.frame = s->gb_frame % s->gb_buffers.frames; - s->gb_buf.height = height; - s->gb_buf.width = width; - s->gb_buf.format = desired_palette; - - if (desired_palette == -1 || (ret = ioctl(video_fd, VIDIOCMCAPTURE, &s->gb_buf)) < 0) { - s->gb_buf.format = VIDEO_PALETTE_YUV420P; - - ret = ioctl(video_fd, VIDIOCMCAPTURE, &s->gb_buf); - if (ret < 0 && errno != EAGAIN) { - /* try YUV422 */ - s->gb_buf.format = VIDEO_PALETTE_YUV422; - - ret = ioctl(video_fd, VIDIOCMCAPTURE, &s->gb_buf); - if (ret < 0 && errno != EAGAIN) { - /* try RGB24 */ - s->gb_buf.format = VIDEO_PALETTE_RGB24; - ret = ioctl(video_fd, VIDIOCMCAPTURE, &s->gb_buf); - } - } - } - if (ret < 0) { - if (errno != EAGAIN) { - fail1: - fprintf(stderr, "Fatal: grab device does not support suitable format\n"); - } else { - fprintf(stderr,"Fatal: grab device does not receive any video signal\n"); - } - goto fail; - } - s->frame_format = s->gb_buf.format; - s->use_mmap = 1; - } - - switch(s->frame_format) { - case VIDEO_PALETTE_YUV420P: - frame_size = (width * height * 3) / 2; - st->codec.pix_fmt = PIX_FMT_YUV420P; - break; - case VIDEO_PALETTE_YUV422: - frame_size = width * height * 2; - st->codec.pix_fmt = PIX_FMT_YUV422; - break; - case VIDEO_PALETTE_RGB24: - frame_size = width * height * 3; - st->codec.pix_fmt = PIX_FMT_BGR24; /* NOTE: v4l uses BGR24, not RGB24 ! */ - break; - default: - goto fail; - } - s->fd = video_fd; - s->frame_size = frame_size; - - st->codec.codec_type = CODEC_TYPE_VIDEO; - st->codec.codec_id = CODEC_ID_RAWVIDEO; - st->codec.width = width; - st->codec.height = height; - st->codec.frame_rate = frame_rate; - - av_set_pts_info(s1, 48, 1, 1000000); /* 48 bits pts in us */ - - return 0; - fail: - if (video_fd >= 0) - close(video_fd); - av_free(st); - return -EIO; -} - -static int v4l_mm_read_picture(VideoData *s, UINT8 *buf) -{ - UINT8 *ptr; - - /* Setup to capture the next frame */ - s->gb_buf.frame = (s->gb_frame + 1) % s->gb_buffers.frames; - if (ioctl(s->fd, VIDIOCMCAPTURE, &s->gb_buf) < 0) { - if (errno == EAGAIN) - fprintf(stderr,"Cannot Sync\n"); - else - perror("VIDIOCMCAPTURE"); - return -EIO; - } - - while (ioctl(s->fd, VIDIOCSYNC, &s->gb_frame) < 0 && - (errno == EAGAIN || errno == EINTR)); - - ptr = s->video_buf + s->gb_buffers.offsets[s->gb_frame]; - memcpy(buf, ptr, s->frame_size); - - /* This is now the grabbing frame */ - s->gb_frame = s->gb_buf.frame; - - return s->frame_size; -} - -static int grab_read_packet(AVFormatContext *s1, AVPacket *pkt) -{ - VideoData *s = s1->priv_data; - INT64 curtime, delay; - struct timespec ts; - INT64 per_frame = (INT64_C(1000000) * FRAME_RATE_BASE) / s->frame_rate; - - /* Calculate the time of the next frame */ - s->time_frame += per_frame; - - /* wait based on the frame rate */ - for(;;) { - curtime = av_gettime(); - delay = s->time_frame - curtime; - if (delay <= 0) { - if (delay < -per_frame) { - /* printf("grabbing is %d frames late (dropping)\n", (int) -(delay / 16666)); */ - s->time_frame += per_frame; - } - break; - } - ts.tv_sec = delay / 1000000; - ts.tv_nsec = (delay % 1000000) * 1000; - nanosleep(&ts, NULL); - } - - if (av_new_packet(pkt, s->frame_size) < 0) - return -EIO; - - pkt->pts = curtime & ((1LL << 48) - 1); - - /* read one frame */ - if (s->aiw_enabled) { - return aiw_read_picture(s, pkt->data); - } else if (s->use_mmap) { - return v4l_mm_read_picture(s, pkt->data); - } else { - if (read(s->fd, pkt->data, pkt->size) != pkt->size) - return -EIO; - return s->frame_size; - } -} - -static int grab_read_close(AVFormatContext *s1) -{ - VideoData *s = s1->priv_data; - - if (s->aiw_enabled) - aiw_close(s); - - if (s->use_mmap) - munmap(s->video_buf, s->gb_buffers.size); - - /* mute audio. we must force it because the BTTV driver does not - return its state correctly */ - s->audio_saved.flags |= VIDEO_AUDIO_MUTE; - ioctl(s->fd, VIDIOCSAUDIO, &s->audio_saved); - - close(s->fd); - return 0; -} - -static AVInputFormat video_grab_device_format = { - "video_grab_device", - "video grab", - sizeof(VideoData), - NULL, - grab_read_header, - grab_read_packet, - grab_read_close, - .flags = AVFMT_NOFILE, -}; - -/* All in Wonder specific stuff */ -/* XXX: remove and merge in libavcodec/imgconvert.c */ - -static int aiw_init(VideoData *s) -{ - int width, height; - - width = s->width; - height = s->height; - - if ((width == s->video_cap.maxwidth && height == s->video_cap.maxheight) || - (width == s->video_cap.maxwidth && height == s->video_cap.maxheight*2) || - (width == s->video_cap.maxwidth/2 && height == s->video_cap.maxheight)) { - - s->deint=0; - s->halfw=0; - if (height == s->video_cap.maxheight*2) s->deint=1; - if (width == s->video_cap.maxwidth/2) s->halfw=1; - } else { - fprintf(stderr,"\nIncorrect Grab Size Supplied - Supported Sizes Are:\n"); - fprintf(stderr," %dx%d %dx%d %dx%d\n\n", - s->video_cap.maxwidth,s->video_cap.maxheight, - s->video_cap.maxwidth,s->video_cap.maxheight*2, - s->video_cap.maxwidth/2,s->video_cap.maxheight); - goto fail; - } - - if (s->halfw == 0) { - s->src_mem = av_malloc(s->width*2); - } else { - s->src_mem = av_malloc(s->width*4); - } - if (!s->src_mem) goto fail; - - s->lum_m4_mem = av_malloc(s->width); - if (!s->lum_m4_mem) - goto fail; - return 0; - fail: - av_freep(&s->src_mem); - av_freep(&s->lum_m4_mem); - return -1; -} - -#ifdef HAVE_MMX -#include "../libavcodec/i386/mmx.h" - -#define LINE_WITH_UV \ - movq_m2r(ptr[0],mm0); \ - movq_m2r(ptr[8],mm1); \ - movq_r2r(mm0, mm4); \ - punpcklbw_r2r(mm1,mm0); \ - punpckhbw_r2r(mm1,mm4); \ - movq_r2r(mm0,mm5); \ - punpcklbw_r2r(mm4,mm0); \ - punpckhbw_r2r(mm4,mm5); \ - movq_r2r(mm0,mm1); \ - punpcklbw_r2r(mm5,mm1); \ - movq_r2m(mm1,lum[0]); \ - movq_m2r(ptr[16],mm2); \ - movq_m2r(ptr[24],mm1); \ - movq_r2r(mm2,mm4); \ - punpcklbw_r2r(mm1,mm2); \ - punpckhbw_r2r(mm1,mm4); \ - movq_r2r(mm2,mm3); \ - punpcklbw_r2r(mm4,mm2); \ - punpckhbw_r2r(mm4,mm3); \ - movq_r2r(mm2,mm1); \ - punpcklbw_r2r(mm3,mm1); \ - movq_r2m(mm1,lum[8]); \ - punpckhdq_r2r(mm2,mm0); \ - punpckhdq_r2r(mm3,mm5); \ - movq_r2m(mm0,cb[0]); \ - movq_r2m(mm5,cr[0]); - -#define LINE_NO_UV \ - movq_m2r(ptr[0],mm0);\ - movq_m2r(ptr[8],mm1);\ - movq_r2r(mm0, mm4);\ - punpcklbw_r2r(mm1,mm0); \ - punpckhbw_r2r(mm1,mm4);\ - movq_r2r(mm0,mm5);\ - punpcklbw_r2r(mm4,mm0);\ - punpckhbw_r2r(mm4,mm5);\ - movq_r2r(mm0,mm1);\ - punpcklbw_r2r(mm5,mm1);\ - movq_r2m(mm1,lum[0]);\ - movq_m2r(ptr[16],mm2);\ - movq_m2r(ptr[24],mm1);\ - movq_r2r(mm2,mm4);\ - punpcklbw_r2r(mm1,mm2);\ - punpckhbw_r2r(mm1,mm4);\ - movq_r2r(mm2,mm3);\ - punpcklbw_r2r(mm4,mm2);\ - punpckhbw_r2r(mm4,mm3);\ - movq_r2r(mm2,mm1);\ - punpcklbw_r2r(mm3,mm1);\ - movq_r2m(mm1,lum[8]); - -#define LINE_WITHUV_AVG \ - movq_m2r(ptr[0], mm0);\ - movq_m2r(ptr[8], mm1);\ - movq_r2r(mm0, mm4);\ - punpcklbw_r2r(mm1,mm0);\ - punpckhbw_r2r(mm1,mm4);\ - movq_r2r(mm0,mm5);\ - punpcklbw_r2r(mm4,mm0);\ - punpckhbw_r2r(mm4,mm5);\ - movq_r2r(mm0,mm1);\ - movq_r2r(mm5,mm2);\ - punpcklbw_r2r(mm7,mm1);\ - punpcklbw_r2r(mm7,mm2);\ - paddw_r2r(mm6,mm1);\ - paddw_r2r(mm2,mm1);\ - psraw_i2r(1,mm1);\ - packuswb_r2r(mm7,mm1);\ - movd_r2m(mm1,lum[0]);\ - movq_m2r(ptr[16],mm2);\ - movq_m2r(ptr[24],mm1);\ - movq_r2r(mm2,mm4);\ - punpcklbw_r2r(mm1,mm2);\ - punpckhbw_r2r(mm1,mm4);\ - movq_r2r(mm2,mm3);\ - punpcklbw_r2r(mm4,mm2);\ - punpckhbw_r2r(mm4,mm3);\ - movq_r2r(mm2,mm1);\ - movq_r2r(mm3,mm4);\ - punpcklbw_r2r(mm7,mm1);\ - punpcklbw_r2r(mm7,mm4);\ - paddw_r2r(mm6,mm1);\ - paddw_r2r(mm4,mm1);\ - psraw_i2r(1,mm1);\ - packuswb_r2r(mm7,mm1);\ - movd_r2m(mm1,lum[4]);\ - punpckhbw_r2r(mm7,mm0);\ - punpckhbw_r2r(mm7,mm2);\ - paddw_r2r(mm6,mm0);\ - paddw_r2r(mm2,mm0);\ - psraw_i2r(1,mm0);\ - packuswb_r2r(mm7,mm0);\ - punpckhbw_r2r(mm7,mm5);\ - punpckhbw_r2r(mm7,mm3);\ - paddw_r2r(mm6,mm5);\ - paddw_r2r(mm3,mm5);\ - psraw_i2r(1,mm5);\ - packuswb_r2r(mm7,mm5);\ - movd_r2m(mm0,cb[0]);\ - movd_r2m(mm5,cr[0]); - -#define LINE_NOUV_AVG \ - movq_m2r(ptr[0],mm0);\ - movq_m2r(ptr[8],mm1);\ - pand_r2r(mm5,mm0);\ - pand_r2r(mm5,mm1);\ - pmaddwd_r2r(mm6,mm0);\ - pmaddwd_r2r(mm6,mm1);\ - packssdw_r2r(mm1,mm0);\ - paddw_r2r(mm6,mm0);\ - psraw_i2r(1,mm0);\ - movq_m2r(ptr[16],mm2);\ - movq_m2r(ptr[24],mm3);\ - pand_r2r(mm5,mm2);\ - pand_r2r(mm5,mm3);\ - pmaddwd_r2r(mm6,mm2);\ - pmaddwd_r2r(mm6,mm3);\ - packssdw_r2r(mm3,mm2);\ - paddw_r2r(mm6,mm2);\ - psraw_i2r(1,mm2);\ - packuswb_r2r(mm2,mm0);\ - movq_r2m(mm0,lum[0]); - -#define DEINT_LINE_LUM(ptroff) \ - movd_m2r(lum_m4[(ptroff)],mm0);\ - movd_m2r(lum_m3[(ptroff)],mm1);\ - movd_m2r(lum_m2[(ptroff)],mm2);\ - movd_m2r(lum_m1[(ptroff)],mm3);\ - movd_m2r(lum[(ptroff)],mm4);\ - punpcklbw_r2r(mm7,mm0);\ - movd_r2m(mm2,lum_m4[(ptroff)]);\ - punpcklbw_r2r(mm7,mm1);\ - punpcklbw_r2r(mm7,mm2);\ - punpcklbw_r2r(mm7,mm3);\ - punpcklbw_r2r(mm7,mm4);\ - psllw_i2r(2,mm1);\ - psllw_i2r(1,mm2);\ - paddw_r2r(mm6,mm1);\ - psllw_i2r(2,mm3);\ - paddw_r2r(mm2,mm1);\ - paddw_r2r(mm4,mm0);\ - paddw_r2r(mm3,mm1);\ - psubusw_r2r(mm0,mm1);\ - psrlw_i2r(3,mm1);\ - packuswb_r2r(mm7,mm1);\ - movd_r2m(mm1,lum_m2[(ptroff)]); - -#else -#include "../libavcodec/dsputil.h" - -#define LINE_WITH_UV \ - lum[0]=ptr[0];lum[1]=ptr[2];lum[2]=ptr[4];lum[3]=ptr[6];\ - cb[0]=ptr[1];cb[1]=ptr[5];\ - cr[0]=ptr[3];cr[1]=ptr[7];\ - lum[4]=ptr[8];lum[5]=ptr[10];lum[6]=ptr[12];lum[7]=ptr[14];\ - cb[2]=ptr[9];cb[3]=ptr[13];\ - cr[2]=ptr[11];cr[3]=ptr[15];\ - lum[8]=ptr[16];lum[9]=ptr[18];lum[10]=ptr[20];lum[11]=ptr[22];\ - cb[4]=ptr[17];cb[5]=ptr[21];\ - cr[4]=ptr[19];cr[5]=ptr[23];\ - lum[12]=ptr[24];lum[13]=ptr[26];lum[14]=ptr[28];lum[15]=ptr[30];\ - cb[6]=ptr[25];cb[7]=ptr[29];\ - cr[6]=ptr[27];cr[7]=ptr[31]; - -#define LINE_NO_UV \ - lum[0]=ptr[0];lum[1]=ptr[2];lum[2]=ptr[4];lum[3]=ptr[6];\ - lum[4]=ptr[8];lum[5]=ptr[10];lum[6]=ptr[12];lum[7]=ptr[14];\ - lum[8]=ptr[16];lum[9]=ptr[18];lum[10]=ptr[20];lum[11]=ptr[22];\ - lum[12]=ptr[24];lum[13]=ptr[26];lum[14]=ptr[28];lum[15]=ptr[30]; - -#define LINE_WITHUV_AVG \ - sum=(ptr[0]+ptr[2]+1) >> 1;lum[0]=sum; \ - sum=(ptr[4]+ptr[6]+1) >> 1;lum[1]=sum; \ - sum=(ptr[1]+ptr[5]+1) >> 1;cb[0]=sum; \ - sum=(ptr[3]+ptr[7]+1) >> 1;cr[0]=sum; \ - sum=(ptr[8]+ptr[10]+1) >> 1;lum[2]=sum; \ - sum=(ptr[12]+ptr[14]+1) >> 1;lum[3]=sum; \ - sum=(ptr[9]+ptr[13]+1) >> 1;cb[1]=sum; \ - sum=(ptr[11]+ptr[15]+1) >> 1;cr[1]=sum; \ - sum=(ptr[16]+ptr[18]+1) >> 1;lum[4]=sum; \ - sum=(ptr[20]+ptr[22]+1) >> 1;lum[5]=sum; \ - sum=(ptr[17]+ptr[21]+1) >> 1;cb[2]=sum; \ - sum=(ptr[19]+ptr[23]+1) >> 1;cr[2]=sum; \ - sum=(ptr[24]+ptr[26]+1) >> 1;lum[6]=sum; \ - sum=(ptr[28]+ptr[30]+1) >> 1;lum[7]=sum; \ - sum=(ptr[25]+ptr[29]+1) >> 1;cb[3]=sum; \ - sum=(ptr[27]+ptr[31]+1) >> 1;cr[3]=sum; - -#define LINE_NOUV_AVG \ - sum=(ptr[0]+ptr[2]+1) >> 1;lum[0]=sum; \ - sum=(ptr[4]+ptr[6]+1) >> 1;lum[1]=sum; \ - sum=(ptr[8]+ptr[10]+1) >> 1;lum[2]=sum; \ - sum=(ptr[12]+ptr[14]+1) >> 1;lum[3]=sum; \ - sum=(ptr[16]+ptr[18]+1) >> 1;lum[4]=sum; \ - sum=(ptr[20]+ptr[22]+1) >> 1;lum[5]=sum; \ - sum=(ptr[24]+ptr[26]+1) >> 1;lum[6]=sum; \ - sum=(ptr[28]+ptr[30]+1) >> 1;lum[7]=sum; - -#define DEINT_LINE_LUM(ptroff) \ - sum=(-lum_m4[(ptroff)]+(lum_m3[(ptroff)]<<2)+(lum_m2[(ptroff)]<<1)+(lum_m1[(ptroff)]<<2)-lum[(ptroff)]); \ - lum_m4[(ptroff)]=lum_m2[(ptroff)];\ - lum_m2[(ptroff)]=cm[(sum+4)>>3];\ - sum=(-lum_m4[(ptroff)+1]+(lum_m3[(ptroff)+1]<<2)+(lum_m2[(ptroff)+1]<<1)+(lum_m1[(ptroff)+1]<<2)-lum[(ptroff)+1]); \ - lum_m4[(ptroff)+1]=lum_m2[(ptroff)+1];\ - lum_m2[(ptroff)+1]=cm[(sum+4)>>3];\ - sum=(-lum_m4[(ptroff)+2]+(lum_m3[(ptroff)+2]<<2)+(lum_m2[(ptroff)+2]<<1)+(lum_m1[(ptroff)+2]<<2)-lum[(ptroff)+2]); \ - lum_m4[(ptroff)+2]=lum_m2[(ptroff)+2];\ - lum_m2[(ptroff)+2]=cm[(sum+4)>>3];\ - sum=(-lum_m4[(ptroff)+3]+(lum_m3[(ptroff)+3]<<2)+(lum_m2[(ptroff)+3]<<1)+(lum_m1[(ptroff)+3]<<2)-lum[(ptroff)+3]); \ - lum_m4[(ptroff)+3]=lum_m2[(ptroff)+3];\ - lum_m2[(ptroff)+3]=cm[(sum+4)>>3]; - -#endif - - -/* Read two fields separately. */ -static int aiw_read_picture(VideoData *s, uint8_t *data) -{ - UINT8 *ptr, *lum, *cb, *cr; - int h; -#ifndef HAVE_MMX - int sum; -#endif - UINT8* src = s->src_mem; - UINT8 *ptrend = &src[s->width*2]; - lum=data; - cb=&lum[s->width*s->height]; - cr=&cb[(s->width*s->height)/4]; - if (s->deint == 0 && s->halfw == 0) { - while (read(s->fd,src,s->width*2) < 0) { - usleep(100); - } - for (h = 0; h < s->height-2; h+=2) { - for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16, cb+=8, cr+=8) { - LINE_WITH_UV - } - read(s->fd,src,s->width*2); - for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16) { - LINE_NO_UV - } - read(s->fd,src,s->width*2); - } - /* - * Do last two lines - */ - for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16, cb+=8, cr+=8) { - LINE_WITH_UV - } - read(s->fd,src,s->width*2); - for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16) { - LINE_NO_UV - } - /* drop second field */ - while (read(s->fd,src,s->width*2) < 0) { - usleep(100); - } - for (h = 0; h < s->height - 1; h++) { - read(s->fd,src,s->width*2); - } - } else if (s->halfw == 1) { -#ifdef HAVE_MMX - mmx_t rounder; - mmx_t masker; - rounder.uw[0]=1; - rounder.uw[1]=1; - rounder.uw[2]=1; - rounder.uw[3]=1; - masker.ub[0]=0xff; - masker.ub[1]=0; - masker.ub[2]=0xff; - masker.ub[3]=0; - masker.ub[4]=0xff; - masker.ub[5]=0; - masker.ub[6]=0xff; - masker.ub[7]=0; - pxor_r2r(mm7,mm7); - movq_m2r(rounder,mm6); -#endif - while (read(s->fd,src,s->width*4) < 0) { - usleep(100); - } - ptrend = &src[s->width*4]; - for (h = 0; h < s->height-2; h+=2) { - for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=8, cb+=4, cr+=4) { - LINE_WITHUV_AVG - } - read(s->fd,src,s->width*4); -#ifdef HAVE_MMX - movq_m2r(masker,mm5); -#endif - for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=8) { - LINE_NOUV_AVG - } - read(s->fd,src,s->width*4); - } - /* - * Do last two lines - */ - for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=8, cb+=4, cr+=4) { - LINE_WITHUV_AVG - } - read(s->fd,src,s->width*4); -#ifdef HAVE_MMX - movq_m2r(masker,mm5); -#endif - for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=8) { - LINE_NOUV_AVG - } - /* drop second field */ - while (read(s->fd,src,s->width*4) < 0) { - usleep(100); - } - for (h = 0; h < s->height - 1; h++) { - read(s->fd,src,s->width*4); - } - } else { - UINT8 *lum_m1, *lum_m2, *lum_m3, *lum_m4; -#ifdef HAVE_MMX - mmx_t rounder; - rounder.uw[0]=4; - rounder.uw[1]=4; - rounder.uw[2]=4; - rounder.uw[3]=4; - movq_m2r(rounder,mm6); - pxor_r2r(mm7,mm7); -#else - UINT8 *cm = cropTbl + MAX_NEG_CROP; -#endif - - /* read two fields and deinterlace them */ - while (read(s->fd,src,s->width*2) < 0) { - usleep(100); - } - for (h = 0; h < (s->height/2)-2; h+=2) { - for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16, cb+=8, cr+=8) { - LINE_WITH_UV - } - read(s->fd,src,s->width*2); - /* skip a luminance line - will be filled in later */ - lum += s->width; - for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16, cb+=8, cr+=8) { - LINE_WITH_UV - } - /* skip a luminance line - will be filled in later */ - lum += s->width; - read(s->fd,src,s->width*2); - } - /* - * Do last two lines - */ - for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16, cb+=8, cr+=8) { - LINE_WITH_UV - } - /* skip a luminance line - will be filled in later */ - lum += s->width; - read(s->fd,src,s->width*2); - for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16, cb+=8, cr+=8) { - LINE_WITH_UV - } - /* - * - * SECOND FIELD - * - */ - lum=&data[s->width]; - while (read(s->fd,src,s->width*2) < 0) { - usleep(10); - } - /* First (and last) two lines not interlaced */ - for (h = 0; h < 2; h++) { - for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16) { - LINE_NO_UV - } - read(s->fd,src,s->width*2); - /* skip a luminance line */ - lum += s->width; - } - lum_m1=&lum[-s->width]; - lum_m2=&lum_m1[-s->width]; - lum_m3=&lum_m2[-s->width]; - memmove(s->lum_m4_mem,&lum_m3[-s->width],s->width); - for (; h < (s->height/2)-1; h++) { - lum_m4=s->lum_m4_mem; - for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16,lum_m1+=16,lum_m2+=16,lum_m3+=16,lum_m4+=16) { - LINE_NO_UV - - DEINT_LINE_LUM(0) - DEINT_LINE_LUM(4) - DEINT_LINE_LUM(8) - DEINT_LINE_LUM(12) - } - read(s->fd,src,s->width*2); - /* skip a luminance line */ - lum += s->width; - lum_m1 += s->width; - lum_m2 += s->width; - lum_m3 += s->width; - // lum_m4 += s->width; - } - /* - * Do last line - */ - lum_m4=s->lum_m4_mem; - for (ptr = &src[0]; ptr < ptrend; ptr+=32, lum+=16, lum_m1+=16, lum_m2+=16, lum_m3+=16, lum_m4+=16) { - LINE_NO_UV - - DEINT_LINE_LUM(0) - DEINT_LINE_LUM(4) - DEINT_LINE_LUM(8) - DEINT_LINE_LUM(12) - } - } -#ifdef HAVE_MMX - emms(); -#endif - return s->frame_size; -} - -static int aiw_close(VideoData *s) -{ - av_freep(&s->lum_m4_mem); - av_freep(&s->src_mem); - return 0; -} - -int video_grab_init(void) -{ - av_register_input_format(&video_grab_device_format); - return 0; -} diff --git a/libav/http.c b/libav/http.c deleted file mode 100644 index 7271a6da81..0000000000 --- a/libav/http.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * HTTP protocol for ffmpeg client - * Copyright (c) 2000, 2001 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" -#include <unistd.h> -#include <ctype.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#ifndef __BEOS__ -# include <arpa/inet.h> -#else -# include "barpainet.h" -#endif -#include <netdb.h> - - -/* XXX: POST protocol is not completly implemented because ffmpeg use - only a subset of it */ - -//#define DEBUG - -/* used for protocol handling */ -#define BUFFER_SIZE 1024 -#define URL_SIZE 4096 - -typedef struct { - URLContext *hd; - unsigned char buffer[BUFFER_SIZE], *buf_ptr, *buf_end; - int line_count; - int http_code; - char location[URL_SIZE]; -} HTTPContext; - -static int http_connect(URLContext *h, const char *path, const char *hoststr); -static int http_write(URLContext *h, UINT8 *buf, int size); - - -/* return non zero if error */ -static int http_open(URLContext *h, const char *uri, int flags) -{ - const char *path, *proxy_path; - char hostname[1024], hoststr[1024]; - char path1[1024]; - char buf[1024]; - int port, use_proxy, err; - HTTPContext *s; - URLContext *hd = NULL; - - h->is_streamed = 1; - - s = av_malloc(sizeof(HTTPContext)); - if (!s) { - return -ENOMEM; - } - h->priv_data = s; - - proxy_path = getenv("http_proxy"); - use_proxy = (proxy_path != NULL) && !getenv("no_proxy") && - strstart(proxy_path, "http://", NULL); - - /* fill the dest addr */ - redo: - /* needed in any case to build the host string */ - url_split(NULL, 0, hostname, sizeof(hostname), &port, - path1, sizeof(path1), uri); - if (port > 0) { - snprintf(hoststr, sizeof(hoststr), "%s:%d", hostname, port); - } else { - pstrcpy(hoststr, sizeof(hoststr), hostname); - } - - if (use_proxy) { - url_split(NULL, 0, hostname, sizeof(hostname), &port, - NULL, 0, proxy_path); - path = uri; - } else { - if (path1[0] == '\0') - path = "/"; - else - path = path1; - } - if (port < 0) - port = 80; - - snprintf(buf, sizeof(buf), "tcp://%s:%d", hostname, port); - err = url_open(&hd, buf, URL_RDWR); - if (err < 0) - goto fail; - - s->hd = hd; - if (http_connect(h, path, hoststr) < 0) - goto fail; - if (s->http_code == 303 && s->location[0] != '\0') { - /* url moved, get next */ - uri = s->location; - url_close(hd); - goto redo; - } - return 0; - fail: - if (hd) - url_close(hd); - av_free(s); - return -EIO; -} - -static int http_getc(HTTPContext *s) -{ - int len; - if (s->buf_ptr >= s->buf_end) { - len = url_read(s->hd, s->buffer, BUFFER_SIZE); - if (len < 0) { - return -EIO; - } else if (len == 0) { - return -1; - } else { - s->buf_ptr = s->buffer; - s->buf_end = s->buffer + len; - } - } - return *s->buf_ptr++; -} - -static int process_line(HTTPContext *s, char *line, int line_count) -{ - char *tag, *p; - - /* end of header */ - if (line[0] == '\0') - return 0; - - p = line; - if (line_count == 0) { - while (!isspace(*p) && *p != '\0') - p++; - while (isspace(*p)) - p++; - s->http_code = strtol(p, NULL, 10); -#ifdef DEBUG - printf("http_code=%d\n", s->http_code); -#endif - } else { - while (*p != '\0' && *p != ':') - p++; - if (*p != ':') - return 1; - - *p = '\0'; - tag = line; - p++; - while (isspace(*p)) - p++; - if (!strcmp(tag, "Location")) { - strcpy(s->location, p); - } - } - return 1; -} - -static int http_connect(URLContext *h, const char *path, const char *hoststr) -{ - HTTPContext *s = h->priv_data; - int post, err, ch; - char line[1024], *q; - - - /* send http header */ - post = h->flags & URL_WRONLY; - - snprintf(s->buffer, sizeof(s->buffer), - "%s %s HTTP/1.0\n" - "User-Agent: FFmpeg %s\n" - "Accept: */*\n" - "Host: %s\n" - "\n", - post ? "POST" : "GET", - path, - FFMPEG_VERSION, - hoststr); - - if (http_write(h, s->buffer, strlen(s->buffer)) < 0) - return -EIO; - - /* init input buffer */ - s->buf_ptr = s->buffer; - s->buf_end = s->buffer; - s->line_count = 0; - s->location[0] = '\0'; - if (post) { - sleep(1); - return 0; - } - - /* wait for header */ - q = line; - for(;;) { - ch = http_getc(s); - if (ch < 0) - return -EIO; - if (ch == '\n') { - /* process line */ - if (q > line && q[-1] == '\r') - q--; - *q = '\0'; -#ifdef DEBUG - printf("header='%s'\n", line); -#endif - err = process_line(s, line, s->line_count); - if (err < 0) - return err; - if (err == 0) - return 0; - s->line_count++; - q = line; - } else { - if ((q - line) < sizeof(line) - 1) - *q++ = ch; - } - } -} - - -static int http_read(URLContext *h, UINT8 *buf, int size) -{ - HTTPContext *s = h->priv_data; - int size1, len; - - size1 = size; - while (size > 0) { - /* read bytes from input buffer first */ - len = s->buf_end - s->buf_ptr; - if (len > 0) { - if (len > size) - len = size; - memcpy(buf, s->buf_ptr, len); - s->buf_ptr += len; - } else { - len = url_read (s->hd, buf, size); - if (len < 0) { - return len; - } else if (len == 0) { - break; - } - } - size -= len; - buf += len; - } - return size1 - size; -} - -/* used only when posting data */ -static int http_write(URLContext *h, UINT8 *buf, int size) -{ - HTTPContext *s = h->priv_data; - return url_write(s->hd, buf, size); -} - -static int http_close(URLContext *h) -{ - HTTPContext *s = h->priv_data; - url_close(s->hd); - av_free(s); - return 0; -} - -URLProtocol http_protocol = { - "http", - http_open, - http_read, - http_write, - NULL, /* seek */ - http_close, -}; - diff --git a/libav/img.c b/libav/img.c deleted file mode 100644 index 305cbb08f2..0000000000 --- a/libav/img.c +++ /dev/null @@ -1,945 +0,0 @@ -/* - * Image format - * 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" - -extern AVInputFormat pgm_iformat; -extern AVOutputFormat pgm_oformat; -extern AVInputFormat pgmyuv_iformat; -extern AVOutputFormat pgmyuv_oformat; -extern AVInputFormat ppm_iformat; -extern AVOutputFormat ppm_oformat; -extern AVInputFormat imgyuv_iformat; -extern AVOutputFormat imgyuv_oformat; -extern AVInputFormat pgmpipe_iformat; -extern AVOutputFormat pgmpipe_oformat; -extern AVInputFormat pgmyuvpipe_iformat; -extern AVOutputFormat pgmyuvpipe_oformat; -extern AVInputFormat ppmpipe_iformat; -extern AVOutputFormat ppmpipe_oformat; -extern AVOutputFormat yuv4mpegpipe_oformat; - -#define IMGFMT_YUV 1 -#define IMGFMT_PGMYUV 2 -#define IMGFMT_PGM 3 -#define IMGFMT_PPM 4 -#define IMGFMT_YUV4MPEG 5 - -#define Y4M_MAGIC "YUV4MPEG2" -#define Y4M_FRAME_MAGIC "FRAME" -#define Y4M_LINE_MAX 256 - -typedef struct { - int width; - int height; - int img_number; - int img_size; - int img_fmt; - int is_pipe; - int header_written; - char path[1024]; -} VideoData; - -static inline int pnm_space(int c) -{ - return (c==' ' || c=='\n' || c=='\r' || c=='\t'); -} - -static void pnm_get(ByteIOContext *f, char *str, int buf_size) -{ - char *s; - int c; - - do { - c=get_byte(f); - if (c=='#') { - do { - c=get_byte(f); - } while (c!='\n'); - c=get_byte(f); - } - } while (pnm_space(c)); - - s=str; - do { - if (url_feof(f)) - break; - if ((s - str) < buf_size - 1) - *s++=c; - c=get_byte(f); - } while (!pnm_space(c)); - *s = '\0'; -} - -static int pgm_read(VideoData *s, ByteIOContext *f, UINT8 *buf, int size, int is_yuv) -{ - int width, height, i; - char buf1[32]; - UINT8 *picture[3]; - - width = s->width; - height = s->height; - - pnm_get(f, buf1, sizeof(buf1)); - if (strcmp(buf1, "P5")) { - return -EIO; - } - pnm_get(f, buf1, sizeof(buf1)); - pnm_get(f, buf1, sizeof(buf1)); - pnm_get(f, buf1, sizeof(buf1)); - - picture[0] = buf; - picture[1] = buf + width * height; - picture[2] = buf + width * height + (width * height / 4); - get_buffer(f, picture[0], width * height); - - height>>=1; - width>>=1; - if (is_yuv) { - for(i=0;i<height;i++) { - get_buffer(f, picture[1] + i * width, width); - get_buffer(f, picture[2] + i * width, width); - } - } else { - for(i=0;i<height;i++) { - memset(picture[1] + i * width, 128, width); - memset(picture[2] + i * width, 128, width); - } - } - return 0; -} - -static int ppm_read(VideoData *s, ByteIOContext *f, UINT8 *buf, int size) -{ - int width, height; - char buf1[32]; - UINT8 *picture[3]; - - width = s->width; - height = s->height; - - pnm_get(f, buf1, sizeof(buf1)); - if (strcmp(buf1, "P6")) { - return -EIO; - } - - pnm_get(f, buf1, sizeof(buf1)); - pnm_get(f, buf1, sizeof(buf1)); - pnm_get(f, buf1, sizeof(buf1)); - - picture[0] = buf; - get_buffer(f, picture[0], width * height*3); - - return 0; - -} - -static int yuv_read(VideoData *s, const char *filename, UINT8 *buf, int size1) -{ - ByteIOContext pb1, *pb = &pb1; - char fname[1024], *p; - int size; - - size = s->width * s->height; - - strcpy(fname, filename); - p = strrchr(fname, '.'); - if (!p || p[1] != 'Y') - return -EIO; - - if (url_fopen(pb, fname, URL_RDONLY) < 0) - return -EIO; - - get_buffer(pb, buf, size); - url_fclose(pb); - - p[1] = 'U'; - if (url_fopen(pb, fname, URL_RDONLY) < 0) - return -EIO; - - get_buffer(pb, buf + size, size / 4); - url_fclose(pb); - - p[1] = 'V'; - if (url_fopen(pb, fname, URL_RDONLY) < 0) - return -EIO; - - get_buffer(pb, buf + size + (size / 4), size / 4); - url_fclose(pb); - return 0; -} - -static int img_read_packet(AVFormatContext *s1, AVPacket *pkt) -{ - VideoData *s = s1->priv_data; - char filename[1024]; - int ret; - ByteIOContext f1, *f; - -/* - This if-statement destroys pipes - I do not see why it is necessary - if (get_frame_filename(filename, sizeof(filename), - s->path, s->img_number) < 0) - return -EIO; -*/ - get_frame_filename(filename, sizeof(filename), - s->path, s->img_number); - if (!s->is_pipe) { - f = &f1; - if (url_fopen(f, filename, URL_RDONLY) < 0) - return -EIO; - } else { - f = &s1->pb; - if (url_feof(f)) - return -EIO; - } - - av_new_packet(pkt, s->img_size); - pkt->stream_index = 0; - - switch(s->img_fmt) { - case IMGFMT_PGMYUV: - ret = pgm_read(s, f, pkt->data, pkt->size, 1); - break; - case IMGFMT_PGM: - ret = pgm_read(s, f, pkt->data, pkt->size, 0); - break; - case IMGFMT_YUV: - ret = yuv_read(s, filename, pkt->data, pkt->size); - break; - case IMGFMT_PPM: - ret = ppm_read(s, f, pkt->data, pkt->size); - break; - default: - return -EIO; - } - - if (!s->is_pipe) { - url_fclose(f); - } - - if (ret < 0) { - av_free_packet(pkt); - return -EIO; /* signal EOF */ - } else { - pkt->pts = ((INT64)s->img_number * s1->pts_den * FRAME_RATE_BASE) / (s1->streams[0]->codec.frame_rate * s1->pts_num); - s->img_number++; - return 0; - } -} - -static int sizes[][2] = { - { 640, 480 }, - { 720, 480 }, - { 720, 576 }, - { 352, 288 }, - { 352, 240 }, - { 160, 128 }, - { 512, 384 }, - { 640, 352 }, - { 640, 240 }, -}; - -static int infer_size(int *width_ptr, int *height_ptr, int size) -{ - int i; - - for(i=0;i<sizeof(sizes)/sizeof(sizes[0]);i++) { - if ((sizes[i][0] * sizes[i][1]) == size) { - *width_ptr = sizes[i][0]; - *height_ptr = sizes[i][1]; - return 0; - } - } - return -1; -} - -static int img_read_header(AVFormatContext *s1, AVFormatParameters *ap) -{ - VideoData *s = s1->priv_data; - int i, h; - char buf[1024]; - char buf1[32]; - ByteIOContext pb1, *f = &pb1; - AVStream *st; - - st = av_new_stream(s1, 0); - if (!st) { - av_free(s); - return -ENOMEM; - } - - strcpy(s->path, s1->filename); - s->img_number = 0; - - /* find format */ - if (s1->iformat->flags & AVFMT_NOFILE) - s->is_pipe = 0; - else - s->is_pipe = 1; - - if (s1->iformat == &pgmyuvpipe_iformat || - s1->iformat == &pgmyuv_iformat) - s->img_fmt = IMGFMT_PGMYUV; - else if (s1->iformat == &pgmpipe_iformat || - s1->iformat == &pgm_iformat) - s->img_fmt = IMGFMT_PGM; - else if (s1->iformat == &imgyuv_iformat) - s->img_fmt = IMGFMT_YUV; - else if (s1->iformat == &ppmpipe_iformat || - s1->iformat == &ppm_iformat) - s->img_fmt = IMGFMT_PPM; - else - goto fail; - - if (!s->is_pipe) { - /* try to find the first image */ - for(i=0;i<5;i++) { - if (get_frame_filename(buf, sizeof(buf), s->path, s->img_number) < 0) - goto fail; - if (url_fopen(f, buf, URL_RDONLY) >= 0) - break; - s->img_number++; - } - if (i == 5) - goto fail; - } else { - f = &s1->pb; - } - - /* find the image size */ - /* XXX: use generic file format guessing, as mpeg */ - switch(s->img_fmt) { - case IMGFMT_PGM: - case IMGFMT_PGMYUV: - case IMGFMT_PPM: - pnm_get(f, buf1, sizeof(buf1)); - pnm_get(f, buf1, sizeof(buf1)); - s->width = atoi(buf1); - pnm_get(f, buf1, sizeof(buf1)); - h = atoi(buf1); - if (s->img_fmt == IMGFMT_PGMYUV) - h = (h * 2) / 3; - s->height = h; - if (s->width <= 0 || - s->height <= 0 || - (s->width % 2) != 0 || - (s->height % 2) != 0) { - goto fail1; - } - break; - case IMGFMT_YUV: - /* infer size by using the file size. */ - { - int img_size; - URLContext *h; - - /* XXX: hack hack */ - h = url_fileno(f); - img_size = url_seek(h, 0, SEEK_END); - if (infer_size(&s->width, &s->height, img_size) < 0) { - goto fail1; - } - } - break; - } - - - if (!s->is_pipe) { - url_fclose(f); - } else { - url_fseek(f, 0, SEEK_SET); - } - - - st->codec.codec_type = CODEC_TYPE_VIDEO; - st->codec.codec_id = CODEC_ID_RAWVIDEO; - st->codec.width = s->width; - st->codec.height = s->height; - if (s->img_fmt == IMGFMT_PPM) { - st->codec.pix_fmt = PIX_FMT_RGB24; - s->img_size = (s->width * s->height * 3); - } else { - st->codec.pix_fmt = PIX_FMT_YUV420P; - s->img_size = (s->width * s->height * 3) / 2; - } - if (!ap || !ap->frame_rate) - st->codec.frame_rate = 25 * FRAME_RATE_BASE; - else - st->codec.frame_rate = ap->frame_rate; - - return 0; - fail1: - if (!s->is_pipe) - url_fclose(f); - fail: - av_free(s); - return -EIO; -} - -static int img_read_close(AVFormatContext *s1) -{ - return 0; -} - -/******************************************************/ -/* image output */ - -static int pgm_save(AVPicture *picture, int width, int height, ByteIOContext *pb, int is_yuv) -{ - int i, h; - char buf[100]; - UINT8 *ptr, *ptr1, *ptr2; - - h = height; - if (is_yuv) - h = (height * 3) / 2; - snprintf(buf, sizeof(buf), - "P5\n%d %d\n%d\n", - width, h, 255); - put_buffer(pb, buf, strlen(buf)); - - ptr = picture->data[0]; - for(i=0;i<height;i++) { - put_buffer(pb, ptr, width); - ptr += picture->linesize[0]; - } - - if (is_yuv) { - height >>= 1; - width >>= 1; - ptr1 = picture->data[1]; - ptr2 = picture->data[2]; - for(i=0;i<height;i++) { - put_buffer(pb, ptr1, width); - put_buffer(pb, ptr2, width); - ptr1 += picture->linesize[1]; - ptr2 += picture->linesize[2]; - } - } - put_flush_packet(pb); - return 0; -} - -static int ppm_save(AVPicture *picture, int width, int height, ByteIOContext *pb) -{ - int i; - char buf[100]; - UINT8 *ptr; - - snprintf(buf, sizeof(buf), - "P6\n%d %d\n%d\n", - width, height, 255); - put_buffer(pb, buf, strlen(buf)); - - ptr = picture->data[0]; - for(i=0;i<height;i++) { - put_buffer(pb, ptr, width * 3); - ptr += picture->linesize[0]; - } - - put_flush_packet(pb); - return 0; -} - -static int yuv_save(AVPicture *picture, int width, int height, const char *filename) -{ - ByteIOContext pb1, *pb = &pb1; - char fname[1024], *p; - int i, j; - UINT8 *ptr; - static char *ext = "YUV"; - - strcpy(fname, filename); - p = strrchr(fname, '.'); - if (!p || p[1] != 'Y') - return -EIO; - - for(i=0;i<3;i++) { - if (i == 1) { - width >>= 1; - height >>= 1; - } - - p[1] = ext[i]; - if (url_fopen(pb, fname, URL_WRONLY) < 0) - return -EIO; - - ptr = picture->data[i]; - for(j=0;j<height;j++) { - put_buffer(pb, ptr, width); - ptr += picture->linesize[i]; - } - put_flush_packet(pb); - url_fclose(pb); - } - return 0; -} - -static int yuv4mpeg_save(AVPicture *picture, int width, int height, ByteIOContext *pb, int need_stream_header, - int is_yuv, int raten, int rated, int aspectn, int aspectd) -{ - int i, n, m; - char buf[Y4M_LINE_MAX+1], buf1[20]; - UINT8 *ptr, *ptr1, *ptr2; - - /* construct stream header, if this is the first frame */ - if(need_stream_header) { - n = snprintf(buf, sizeof(buf), "%s W%d H%d F%d:%d I%s A%d:%d\n", - Y4M_MAGIC, - width, - height, - raten, rated, - "p", /* ffmpeg seems to only output progressive video */ - aspectn, aspectd); - if (n < 0) { - fprintf(stderr, "Error. YUV4MPEG stream header write failed.\n"); - } else { - fprintf(stderr, "YUV4MPEG stream header written. FPS is %d\n", raten); - put_buffer(pb, buf, strlen(buf)); - } - } - - /* construct frame header */ - m = snprintf(buf1, sizeof(buf1), "%s \n", Y4M_FRAME_MAGIC); - if (m < 0) { - fprintf(stderr, "Error. YUV4MPEG frame header write failed.\n"); - } else { - /* fprintf(stderr, "YUV4MPEG frame header written.\n"); */ - put_buffer(pb, buf1, strlen(buf1)); - } - - ptr = picture->data[0]; - for(i=0;i<height;i++) { - put_buffer(pb, ptr, width); - ptr += picture->linesize[0]; - } - - if (is_yuv) { - height >>= 1; - width >>= 1; - ptr1 = picture->data[1]; - ptr2 = picture->data[2]; - for(i=0;i<height;i++) { /* Cb */ - put_buffer(pb, ptr1, width); - ptr1 += picture->linesize[1]; - } - for(i=0;i<height;i++) { /* Cr */ - put_buffer(pb, ptr2, width); - ptr2 += picture->linesize[2]; - } - } - put_flush_packet(pb); - return 0; -} - -static int img_write_header(AVFormatContext *s) -{ - VideoData *img = s->priv_data; - - img->img_number = 1; - strcpy(img->path, s->filename); - - /* find format */ - if (s->oformat->flags & AVFMT_NOFILE) - img->is_pipe = 0; - else - img->is_pipe = 1; - - if (s->oformat == &pgmyuvpipe_oformat || - s->oformat == &pgmyuv_oformat) { - img->img_fmt = IMGFMT_PGMYUV; - } else if (s->oformat == &pgmpipe_oformat || - s->oformat == &pgm_oformat) { - img->img_fmt = IMGFMT_PGM; - } else if (s->oformat == &imgyuv_oformat) { - img->img_fmt = IMGFMT_YUV; - } else if (s->oformat == &ppmpipe_oformat || - s->oformat == &ppm_oformat) { - img->img_fmt = IMGFMT_PPM; - } else if (s->oformat == &yuv4mpegpipe_oformat) { - img->img_fmt = IMGFMT_YUV4MPEG; - img->header_written = 0; - } else { - goto fail; - } - return 0; - fail: - av_free(img); - return -EIO; -} - -static int img_write_packet(AVFormatContext *s, int stream_index, - UINT8 *buf, int size, int force_pts) -{ - VideoData *img = s->priv_data; - AVStream *st = s->streams[stream_index]; - ByteIOContext pb1, *pb; - AVPicture picture; - int width, height, need_stream_header, ret, size1, raten, rated, aspectn, aspectd, fps, fps1; - char filename[1024]; - - width = st->codec.width; - height = st->codec.height; - - if (img->img_number == 1) { - need_stream_header = 1; - } else { - need_stream_header = 0; - } - - fps = st->codec.frame_rate; - fps1 = (((float)fps / FRAME_RATE_BASE) * 1000); - - /* Sorry about this messy code, but mpeg2enc is very picky about - * the framerates it accepts. */ - switch(fps1) { - case 23976: - raten = 24000; /* turn the framerate into a ratio */ - rated = 1001; - break; - case 29970: - raten = 30000; - rated = 1001; - break; - case 25000: - raten = 25; - rated = 1; - break; - case 30000: - raten = 30; - rated = 1; - break; - case 24000: - raten = 24; - rated = 1; - break; - case 50000: - raten = 50; - rated = 1; - break; - case 59940: - raten = 60000; - rated = 1001; - break; - case 60000: - raten = 60; - rated = 1; - break; - default: - raten = fps1; /* this setting should work, but often doesn't */ - rated = 1000; - break; - } - - aspectn = 1; - aspectd = 1; /* ffmpeg always uses a 1:1 aspect ratio */ - - switch(st->codec.pix_fmt) { - case PIX_FMT_YUV420P: - size1 = (width * height * 3) / 2; - if (size != size1) - return -EIO; - - picture.data[0] = buf; - picture.data[1] = picture.data[0] + width * height; - picture.data[2] = picture.data[1] + (width * height) / 4; - picture.linesize[0] = width; - picture.linesize[1] = width >> 1; - picture.linesize[2] = width >> 1; - break; - case PIX_FMT_RGB24: - size1 = (width * height * 3); - if (size != size1) - return -EIO; - picture.data[0] = buf; - picture.linesize[0] = width * 3; - break; - default: - return -EIO; - } - -/* - This if-statement destroys pipes - I do not see why it is necessary - if (get_frame_filename(filename, sizeof(filename), - img->path, img->img_number) < 0) - return -EIO; -*/ - get_frame_filename(filename, sizeof(filename), - img->path, img->img_number); - if (!img->is_pipe) { - pb = &pb1; - if (url_fopen(pb, filename, URL_WRONLY) < 0) - return -EIO; - } else { - pb = &s->pb; - } - switch(img->img_fmt) { - case IMGFMT_PGMYUV: - ret = pgm_save(&picture, width, height, pb, 1); - break; - case IMGFMT_PGM: - ret = pgm_save(&picture, width, height, pb, 0); - break; - case IMGFMT_YUV: - ret = yuv_save(&picture, width, height, filename); - break; - case IMGFMT_PPM: - ret = ppm_save(&picture, width, height, pb); - break; - case IMGFMT_YUV4MPEG: - ret = yuv4mpeg_save(&picture, width, height, pb, - need_stream_header, 1, raten, rated, aspectn, aspectd); - break; - } - if (!img->is_pipe) { - url_fclose(pb); - } - - img->img_number++; - return 0; -} - -static int img_write_trailer(AVFormatContext *s) -{ - return 0; -} - -static AVInputFormat pgm_iformat = { - "pgm", - "pgm image format", - sizeof(VideoData), - NULL, - img_read_header, - img_read_packet, - img_read_close, - NULL, - AVFMT_NOFILE | AVFMT_NEEDNUMBER, - .extensions = "pgm", -}; - -static AVOutputFormat pgm_oformat = { - "pgm", - "pgm image format", - "", - "pgm", - sizeof(VideoData), - CODEC_ID_NONE, - CODEC_ID_RAWVIDEO, - img_write_header, - img_write_packet, - img_write_trailer, - AVFMT_NOFILE | AVFMT_NEEDNUMBER, -}; - -static AVInputFormat pgmyuv_iformat = { - "pgmyuv", - "pgm with YUV content image format", - sizeof(VideoData), - NULL, /* no probe */ - img_read_header, - img_read_packet, - img_read_close, - NULL, - AVFMT_NOFILE | AVFMT_NEEDNUMBER, -}; - -static AVOutputFormat pgmyuv_oformat = { - "pgmyuv", - "pgm with YUV content image format", - "", - "pgm", - sizeof(VideoData), - CODEC_ID_NONE, - CODEC_ID_RAWVIDEO, - img_write_header, - img_write_packet, - img_write_trailer, - AVFMT_NOFILE | AVFMT_NEEDNUMBER, -}; - -static AVInputFormat ppm_iformat = { - "ppm", - "ppm image format", - sizeof(VideoData), - NULL, - img_read_header, - img_read_packet, - img_read_close, - NULL, - AVFMT_NOFILE | AVFMT_NEEDNUMBER | AVFMT_RGB24, - .extensions = "ppm", -}; - -static AVOutputFormat ppm_oformat = { - "ppm", - "ppm image format", - "", - "ppm", - sizeof(VideoData), - CODEC_ID_NONE, - CODEC_ID_RAWVIDEO, - img_write_header, - img_write_packet, - img_write_trailer, - AVFMT_NOFILE | AVFMT_NEEDNUMBER | AVFMT_RGB24, -}; - -static AVInputFormat imgyuv_iformat = { - ".Y.U.V", - ".Y.U.V format", - sizeof(VideoData), - NULL, - img_read_header, - img_read_packet, - img_read_close, - NULL, - AVFMT_NOFILE | AVFMT_NEEDNUMBER, - .extensions = "Y", -}; - -static AVOutputFormat imgyuv_oformat = { - ".Y.U.V", - ".Y.U.V format", - "", - "Y", - sizeof(VideoData), - CODEC_ID_NONE, - CODEC_ID_RAWVIDEO, - img_write_header, - img_write_packet, - img_write_trailer, - AVFMT_NOFILE | AVFMT_NEEDNUMBER, -}; - -static AVInputFormat pgmpipe_iformat = { - "pgmpipe", - "PGM pipe format", - sizeof(VideoData), - NULL, /* no probe */ - img_read_header, - img_read_packet, - img_read_close, - NULL, -}; - -static AVOutputFormat pgmpipe_oformat = { - "pgmpipe", - "PGM pipe format", - "", - "pgm", - sizeof(VideoData), - CODEC_ID_NONE, - CODEC_ID_RAWVIDEO, - img_write_header, - img_write_packet, - img_write_trailer, -}; - -static AVInputFormat pgmyuvpipe_iformat = { - "pgmyuvpipe", - "PGM YUV pipe format", - sizeof(VideoData), - NULL, /* no probe */ - img_read_header, - img_read_packet, - img_read_close, - NULL, -}; - -static AVOutputFormat pgmyuvpipe_oformat = { - "pgmyuvpipe", - "PGM YUV pipe format", - "", - "pgm", - sizeof(VideoData), - CODEC_ID_NONE, - CODEC_ID_RAWVIDEO, - img_write_header, - img_write_packet, - img_write_trailer, -}; - -static AVInputFormat ppmpipe_iformat = { - "ppmpipe", - "PPM pipe format", - sizeof(VideoData), - NULL, /* no probe */ - img_read_header, - img_read_packet, - img_read_close, - NULL, - .flags = AVFMT_RGB24, -}; - -static AVOutputFormat ppmpipe_oformat = { - "ppmpipe", - "PPM pipe format", - "", - "ppm", - sizeof(VideoData), - CODEC_ID_NONE, - CODEC_ID_RAWVIDEO, - img_write_header, - img_write_packet, - img_write_trailer, - .flags = AVFMT_RGB24, -}; - - -static AVOutputFormat yuv4mpegpipe_oformat = { - "yuv4mpegpipe", - "YUV4MPEG pipe format", - "", - "yuv4mpeg", - sizeof(VideoData), - CODEC_ID_NONE, - CODEC_ID_RAWVIDEO, - img_write_header, - img_write_packet, - img_write_trailer, -}; - - -int img_init(void) -{ - av_register_input_format(&pgm_iformat); - av_register_output_format(&pgm_oformat); - - av_register_input_format(&pgmyuv_iformat); - av_register_output_format(&pgmyuv_oformat); - - av_register_input_format(&ppm_iformat); - av_register_output_format(&ppm_oformat); - - av_register_input_format(&imgyuv_iformat); - av_register_output_format(&imgyuv_oformat); - - av_register_input_format(&pgmpipe_iformat); - av_register_output_format(&pgmpipe_oformat); - - av_register_input_format(&pgmyuvpipe_iformat); - av_register_output_format(&pgmyuvpipe_oformat); - - av_register_input_format(&ppmpipe_iformat); - av_register_output_format(&ppmpipe_oformat); - - av_register_output_format(&yuv4mpegpipe_oformat); - - return 0; -} diff --git a/libav/jpeg.c b/libav/jpeg.c deleted file mode 100644 index 6a19db6d67..0000000000 --- a/libav/jpeg.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - * JPEG based formats - * Copyright (c) 2000, 2001 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" - -/* Multipart JPEG */ - -#define BOUNDARY_TAG "ffserver" - -static int mpjpeg_write_header(AVFormatContext *s) -{ - UINT8 buf1[256]; - - snprintf(buf1, sizeof(buf1), "--%s\n", BOUNDARY_TAG); - put_buffer(&s->pb, buf1, strlen(buf1)); - put_flush_packet(&s->pb); - return 0; -} - -static int mpjpeg_write_packet(AVFormatContext *s, int stream_index, - UINT8 *buf, int size, int force_pts) -{ - UINT8 buf1[256]; - - snprintf(buf1, sizeof(buf1), "Content-type: image/jpeg\n\n"); - put_buffer(&s->pb, buf1, strlen(buf1)); - put_buffer(&s->pb, buf, size); - - snprintf(buf1, sizeof(buf1), "\n--%s\n", BOUNDARY_TAG); - put_buffer(&s->pb, buf1, strlen(buf1)); - put_flush_packet(&s->pb); - return 0; -} - -static int mpjpeg_write_trailer(AVFormatContext *s) -{ - return 0; -} - -static AVOutputFormat mpjpeg_format = { - "mpjpeg", - "Mime multipart JPEG format", - "multipart/x-mixed-replace;boundary=" BOUNDARY_TAG, - "mjpg", - 0, - CODEC_ID_NONE, - CODEC_ID_MJPEG, - mpjpeg_write_header, - mpjpeg_write_packet, - mpjpeg_write_trailer, -}; - - -/*************************************/ -/* single frame JPEG */ - -static int single_jpeg_write_header(AVFormatContext *s) -{ - return 0; -} - -static int single_jpeg_write_packet(AVFormatContext *s, int stream_index, - UINT8 *buf, int size, int force_pts) -{ - put_buffer(&s->pb, buf, size); - put_flush_packet(&s->pb); - return 1; /* no more data can be sent */ -} - -static int single_jpeg_write_trailer(AVFormatContext *s) -{ - return 0; -} - -static AVOutputFormat single_jpeg_format = { - "singlejpeg", - "single JPEG image", - "image/jpeg", - NULL, /* note: no extension to favorize jpeg multiple images match */ - 0, - CODEC_ID_NONE, - CODEC_ID_MJPEG, - single_jpeg_write_header, - single_jpeg_write_packet, - single_jpeg_write_trailer, -}; - -/*************************************/ -/* multiple jpeg images */ - -typedef struct JpegContext { - char path[1024]; - int img_number; -} JpegContext; - -static int jpeg_write_header(AVFormatContext *s1) -{ - JpegContext *s; - - s = av_mallocz(sizeof(JpegContext)); - if (!s) - return -1; - s1->priv_data = s; - pstrcpy(s->path, sizeof(s->path), s1->filename); - s->img_number = 1; - return 0; -} - -static int jpeg_write_packet(AVFormatContext *s1, int stream_index, - UINT8 *buf, int size, int force_pts) -{ - JpegContext *s = s1->priv_data; - char filename[1024]; - ByteIOContext f1, *pb = &f1; - - if (get_frame_filename(filename, sizeof(filename), - s->path, s->img_number) < 0) - return -EIO; - if (url_fopen(pb, filename, URL_WRONLY) < 0) - return -EIO; - - put_buffer(pb, buf, size); - put_flush_packet(pb); - - url_fclose(pb); - s->img_number++; - - return 0; -} - -static int jpeg_write_trailer(AVFormatContext *s1) -{ - return 0; -} - -/***/ - -static int jpeg_read_header(AVFormatContext *s1, AVFormatParameters *ap) -{ - JpegContext *s; - int i; - char buf[1024]; - ByteIOContext pb1, *f = &pb1; - AVStream *st; - - s = av_mallocz(sizeof(JpegContext)); - if (!s) - return -1; - s1->priv_data = s; - pstrcpy(s->path, sizeof(s->path), s1->filename); - - s1->nb_streams = 1; - st = av_mallocz(sizeof(AVStream)); - if (!st) { - av_free(s); - return -ENOMEM; - } - s1->streams[0] = st; - s->img_number = 0; - - /* try to find the first image */ - for(i=0;i<5;i++) { - if (get_frame_filename(buf, sizeof(buf), s->path, s->img_number) < 0) - goto fail; - if (url_fopen(f, buf, URL_RDONLY) >= 0) - break; - s->img_number++; - } - if (i == 5) - goto fail; - url_fclose(f); - st->codec.codec_type = CODEC_TYPE_VIDEO; - st->codec.codec_id = CODEC_ID_MJPEG; - - if (!ap || !ap->frame_rate) - st->codec.frame_rate = 25 * FRAME_RATE_BASE; - else - st->codec.frame_rate = ap->frame_rate; - return 0; - fail: - av_free(s); - return -EIO; -} - -static int jpeg_read_packet(AVFormatContext *s1, AVPacket *pkt) -{ - JpegContext *s = s1->priv_data; - char filename[1024]; - int size; - ByteIOContext f1, *f = &f1; - - if (get_frame_filename(filename, sizeof(filename), - s->path, s->img_number) < 0) - return -EIO; - - f = &f1; - if (url_fopen(f, filename, URL_RDONLY) < 0) - return -EIO; - - size = url_seek(url_fileno(f), 0, SEEK_END); - url_seek(url_fileno(f), 0, SEEK_SET); - - av_new_packet(pkt, size); - pkt->stream_index = 0; - get_buffer(f, pkt->data, size); - - url_fclose(f); - s->img_number++; - return 0; -} - -static int jpeg_read_close(AVFormatContext *s1) -{ - return 0; -} - -static AVInputFormat jpeg_iformat = { - "jpeg", - "JPEG image", - sizeof(JpegContext), - NULL, - jpeg_read_header, - jpeg_read_packet, - jpeg_read_close, - NULL, - .flags = AVFMT_NOFILE | AVFMT_NEEDNUMBER, - .extensions = "jpg,jpeg", -}; - -static AVOutputFormat jpeg_oformat = { - "jpeg", - "JPEG image", - "image/jpeg", - "jpg,jpeg", - sizeof(JpegContext), - CODEC_ID_NONE, - CODEC_ID_MJPEG, - jpeg_write_header, - jpeg_write_packet, - jpeg_write_trailer, - .flags = AVFMT_NOFILE | AVFMT_NEEDNUMBER, -}; - -int jpeg_init(void) -{ - av_register_output_format(&mpjpeg_format); - av_register_output_format(&single_jpeg_format); - av_register_input_format(&jpeg_iformat); - av_register_output_format(&jpeg_oformat); - return 0; -} diff --git a/libav/mov.c b/libav/mov.c deleted file mode 100644 index 91c7155b08..0000000000 --- a/libav/mov.c +++ /dev/null @@ -1,1347 +0,0 @@ -/* - * MOV decoder. - * Copyright (c) 2001 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" -#include "avi.h" - -#ifdef CONFIG_ZLIB -#include <zlib.h> -#endif - -/* - * First version by Francois Revol revol@free.fr - * - * Features and limitations: - * - reads most of the QT files I have (at least the structure), - * the exceptions are .mov with zlib compressed headers ('cmov' section). It shouldn't be hard to implement. - * FIXED, Francois Revol, 07/17/2002 - * - ffmpeg has nearly none of the usual QuickTime codecs, - * although I succesfully dumped raw and mp3 audio tracks off .mov files. - * Sample QuickTime files with mp3 audio can be found at: http://www.3ivx.com/showcase.html - * - .mp4 parsing is still hazardous, although the format really is QuickTime with some minor changes - * (to make .mov parser crash maybe ?), despite what they say in the MPEG FAQ at - * http://mpeg.telecomitalialab.com/faq.htm - * - the code is quite ugly... maybe I won't do it recursive next time :-) - * - * Funny I didn't know about http://sourceforge.net/projects/qt-ffmpeg/ - * when coding this :) (it's a writer anyway) - * - * Reference documents: - * http://www.geocities.com/xhelmboyx/quicktime/formats/qtm-layout.txt - * Apple: - * http://developer.apple.com/techpubs/quicktime/qtdevdocs/QTFF/qtff.html - * http://developer.apple.com/techpubs/quicktime/qtdevdocs/PDF/QTFileFormat.pdf - * QuickTime is a trademark of Apple (AFAIK :)) - */ - -//#define DEBUG - -/* allows chunk splitting - should work now... */ -/* in case you can't read a file, try commenting */ -#define MOV_SPLIT_CHUNKS - -#ifdef DEBUG -/* - * XXX: static sux, even more in a multithreaded environment... - * Avoid them. This is here just to help debugging. - */ -static int debug_indent = 0; -void print_atom(const char *str, UINT32 type, UINT64 offset, UINT64 size) -{ - unsigned int tag, i; - tag = (unsigned int) type; - i=debug_indent; - if(tag == 0) tag = MKTAG('N', 'U', 'L', 'L'); - while(i--) - printf("|"); - printf("parse:"); - printf(" %s: tag=%c%c%c%c offset=0x%x size=0x%x\n", - str, tag & 0xff, - (tag >> 8) & 0xff, - (tag >> 16) & 0xff, - (tag >> 24) & 0xff, - (unsigned int)offset, - (unsigned int)size); -} -#endif - -/* some streams in QT (and in MP4 mostly) aren't either video nor audio */ -/* so we first list them as this, then clean up the list of streams we give back, */ -/* getting rid of these */ -#define CODEC_TYPE_MOV_OTHER 2 - -static const CodecTag mov_video_tags[] = { -/* { CODEC_ID_, MKTAG('c', 'v', 'i', 'd') }, *//* Cinepak */ -/* { CODEC_ID_JPEG, MKTAG('j', 'p', 'e', 'g') }, *//* JPEG */ -/* { CODEC_ID_H263, MKTAG('r', 'a', 'w', ' ') }, *//* Uncompressed RGB */ -/* { CODEC_ID_H263, MKTAG('Y', 'u', 'v', '2') }, *//* Uncompressed YUV422 */ -/* Graphics */ -/* Animation */ -/* Apple video */ -/* Kodak Photo CD */ - { CODEC_ID_MJPEG, MKTAG('j', 'p', 'e', 'g') }, /* PhotoJPEG */ - { CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'e', 'g') }, /* MPEG */ - { CODEC_ID_MJPEG, MKTAG('m', 'j', 'p', 'a') }, /* Motion-JPEG (format A) */ - { CODEC_ID_MJPEG, MKTAG('m', 'j', 'p', 'b') }, /* Motion-JPEG (format B) */ -/* { CODEC_ID_GIF, MKTAG('g', 'i', 'f', ' ') }, *//* embedded gif files as frames (usually one "click to play movie" frame) */ -/* Sorenson video */ - { CODEC_ID_SVQ1, MKTAG('S', 'V', 'Q', '1') }, /* Sorenson Video v1 */ - { CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', '1') }, /* Sorenson Video v1 */ - { CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', 'i') }, /* Sorenson Video v1 (from QT specs)*/ - { CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') }, - { CODEC_ID_MPEG4, MKTAG('D', 'I', 'V', 'X') }, /* OpenDiVX *//* sample files at http://heroinewarrior.com/xmovie.php3 use this tag */ -/* { CODEC_ID_, MKTAG('I', 'V', '5', '0') }, *//* Indeo 5.0 */ - { CODEC_ID_H263, MKTAG('h', '2', '6', '3') }, /* H263 */ - { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', ' ') }, /* DV NTSC */ - { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', 'p') }, /* DV PAL */ - { 0, 0 }, -}; - -static const CodecTag mov_audio_tags[] = { -/* { CODEC_ID_PCM_S16BE, MKTAG('N', 'O', 'N', 'E') }, *//* uncompressed */ - { CODEC_ID_PCM_S16BE, MKTAG('t', 'w', 'o', 's') }, /* 16 bits */ - { CODEC_ID_PCM_S8, MKTAG('t', 'w', 'o', 's') }, /* 8 bits */ - { CODEC_ID_PCM_U8, 0x20776172 }, /* 8 bits unsigned */ - { CODEC_ID_PCM_S16LE, MKTAG('s', 'o', 'w', 't') }, /* */ - { CODEC_ID_PCM_MULAW, MKTAG('u', 'l', 'a', 'w') }, /* */ - { CODEC_ID_PCM_ALAW, MKTAG('a', 'l', 'a', 'w') }, /* */ - { CODEC_ID_ADPCM_IMA_QT, MKTAG('i', 'm', 'a', '4') }, /* IMA-4 ADPCM */ - { CODEC_ID_MACE3, MKTAG('M', 'A', 'C', '3') }, /* Macintosh Audio Compression and Expansion 3:1 */ - { CODEC_ID_MACE6, MKTAG('M', 'A', 'C', '6') }, /* Macintosh Audio Compression and Expansion 6:1 */ - - { CODEC_ID_MP2, MKTAG('.', 'm', 'p', '3') }, /* MPEG layer 3 */ /* sample files at http://www.3ivx.com/showcase.html use this tag */ - { CODEC_ID_MP2, 0x6D730055 }, /* MPEG layer 3 */ - { CODEC_ID_MP2, 0x5500736D }, /* MPEG layer 3 *//* XXX: check endianness */ -/* { CODEC_ID_OGG_VORBIS, MKTAG('O', 'g', 'g', 'S') }, *//* sample files at http://heroinewarrior.com/xmovie.php3 use this tag */ -/* MP4 tags */ -/* { CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') }, *//* MPEG 4 AAC or audio ? */ - /* The standard for mpeg4 audio is still not normalised AFAIK anyway */ - { 0, 0 }, -}; - -/* the QuickTime file format is quite convoluted... - * it has lots of index tables, each indexing something in another one... - * Here we just use what is needed to read the chunks - */ - -typedef struct MOV_sample_to_chunk_tbl { - long first; - long count; - long id; -} MOV_sample_to_chunk_tbl; - -typedef struct MOVStreamContext { - int ffindex; /* the ffmpeg stream id */ - int is_ff_stream; /* Is this stream presented to ffmpeg ? i.e. is this an audio or video stream ? */ - long next_chunk; - long chunk_count; - INT64 *chunk_offsets; - long sample_to_chunk_sz; - MOV_sample_to_chunk_tbl *sample_to_chunk; - long sample_to_chunk_index; - long sample_size; - long sample_count; - long *sample_sizes; - long time_scale; - long current_sample; - long left_in_chunk; /* how many samples before next chunk */ - /* specific MPEG4 header which is added at the beginning of the stream */ - int header_len; - uint8_t *header_data; -} MOVStreamContext; - -typedef struct MOVContext { - int mp4; /* set to 1 as soon as we are sure that the file is an .mp4 file (even some header parsing depends on this) */ - AVFormatContext *fc; - long time_scale; - int found_moov; /* when both 'moov' and 'mdat' sections has been found */ - int found_mdat; /* we suppose we have enough data to read the file */ - INT64 mdat_size; - INT64 mdat_offset; - int total_streams; - /* some streams listed here aren't presented to the ffmpeg API, since they aren't either video nor audio - * but we need the info to be able to skip data from those streams in the 'mdat' section - */ - MOVStreamContext *streams[MAX_STREAMS]; - - INT64 next_chunk_offset; - int partial; /* != 0 : there is still to read in the current chunk (=id of the stream + 1) */ -} MOVContext; - - -struct MOVParseTableEntry; - -/* XXX: it's the first time I make a recursive parser I think... sorry if it's ugly :P */ - -/* those functions parse an atom */ -/* return code: - 1: found what I wanted, exit - 0: continue to parse next atom - -1: error occured, exit - */ -typedef int (*mov_parse_function)(const struct MOVParseTableEntry *parse_table, - ByteIOContext *pb, - UINT32 atom_type, - INT64 atom_offset, /* after the size and type field (and eventually the extended size) */ - INT64 atom_size, /* total size (excluding the size and type fields) */ - void *param); - -/* links atom IDs to parse functions */ -typedef struct MOVParseTableEntry { - UINT32 type; - mov_parse_function func; -} MOVParseTableEntry; - -static int parse_leaf(const MOVParseTableEntry *parse_table, ByteIOContext *pb, UINT32 atom_type, INT64 atom_offset, INT64 atom_size, void *param) -{ -#ifdef DEBUG - print_atom("leaf", atom_type, atom_offset, atom_size); -#endif - if(atom_size>1) - url_fskip(pb, atom_size); -/* url_seek(pb, atom_offset+atom_size, SEEK_SET); */ - return 0; -} - - -static int parse_default(const MOVParseTableEntry *parse_table, ByteIOContext *pb, UINT32 atom_type, INT64 atom_offset, INT64 atom_size, void *param) -{ - UINT32 type, foo=0; - UINT64 offset, size; - UINT64 total_size = 0; - int i; - int err = 0; - foo=0; -#ifdef DEBUG - print_atom("default", atom_type, atom_offset, atom_size); - debug_indent++; -#endif - - offset = atom_offset; - - if(atom_size < 0) - atom_size = 0x0FFFFFFFFFFFFFFF; - while((total_size < atom_size) && !url_feof(pb) && !err) { - size=atom_size; - type=0L; - if(atom_size >= 8) { - size = get_be32(pb); - type = get_le32(pb); - } - total_size += 8; - offset+=8; -// printf("type: %08lx sz: %08lx", type, size); - if(size == 1) { /* 64 bit extended size */ - size = get_be64(pb); - offset+=8; - total_size+=8; - size-=8; - } - if(size == 0) - size = atom_size - total_size; - size-=8; - for(i=0; parse_table[i].type != 0L && parse_table[i].type != type; i++); - -// printf(" i=%ld\n", i); - if (parse_table[i].type == 0) { /* skip leaf atoms data */ -// url_seek(pb, atom_offset+atom_size, SEEK_SET); -#ifdef DEBUG - print_atom("unknown", type, offset, size); -#endif - url_fskip(pb, size); - } else - err = (parse_table[i].func)(parse_table, pb, type, offset, size, param); - - offset+=size; - total_size+=size; - } - -#ifdef DEBUG - debug_indent--; -#endif - return err; -} - -static int parse_mvhd(const MOVParseTableEntry *parse_table, ByteIOContext *pb, UINT32 atom_type, INT64 atom_offset, INT64 atom_size, void *param) -{ - MOVContext *c; -#ifdef DEBUG - print_atom("mvhd", atom_type, atom_offset, atom_size); -#endif - c = (MOVContext *)param; - - get_byte(pb); /* version */ - get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ - - get_be32(pb); /* creation time */ - get_be32(pb); /* modification time */ - c->time_scale = get_be32(pb); /* time scale */ -#ifdef DEBUG - printf("time scale = %li\n", c->time_scale); -#endif - get_be32(pb); /* duration */ - get_be32(pb); /* preferred scale */ - - get_be16(pb); /* preferred volume */ - - url_fskip(pb, 10); /* reserved */ - - url_fskip(pb, 36); /* display matrix */ - - get_be32(pb); /* preview time */ - get_be32(pb); /* preview duration */ - get_be32(pb); /* poster time */ - get_be32(pb); /* selection time */ - get_be32(pb); /* selection duration */ - get_be32(pb); /* current time */ - get_be32(pb); /* next track ID */ - - return 0; -} - -/* this atom should contain all header atoms */ -static int parse_moov(const MOVParseTableEntry *parse_table, ByteIOContext *pb, UINT32 atom_type, INT64 atom_offset, INT64 atom_size, void *param) -{ - int err; - MOVContext *c; -#ifdef DEBUG - print_atom("moov", atom_type, atom_offset, atom_size); -#endif - c = (MOVContext *)param; - - err = parse_default(parse_table, pb, atom_type, atom_offset, atom_size, param); - /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */ - /* so we don't parse the whole file if over a network */ - c->found_moov=1; - if(c->found_mdat) - return 1; /* found both, just go */ - return 0; /* now go for mdat */ -} - -/* this atom contains actual media data */ -static int parse_mdat(const MOVParseTableEntry *parse_table, ByteIOContext *pb, UINT32 atom_type, INT64 atom_offset, INT64 atom_size, void *param) -{ - MOVContext *c; -#ifdef DEBUG - print_atom("mdat", atom_type, atom_offset, atom_size); -#endif - c = (MOVContext *)param; - - if(atom_size == 0) /* wrong one (MP4) */ - return 0; - c->found_mdat=1; - c->mdat_offset = atom_offset; - c->mdat_size = atom_size; - if(c->found_moov) - return 1; /* found both, just go */ - url_fskip(pb, atom_size); - return 0; /* now go for moov */ -} - -/* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */ -/* like the files created with Adobe Premiere 5.0, for samples see */ -/* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */ -static int parse_wide(const MOVParseTableEntry *parse_table, ByteIOContext *pb, UINT32 atom_type, INT64 atom_offset, INT64 atom_size, void *param) -{ - int err; - UINT32 type; -#ifdef DEBUG - print_atom("wide", atom_type, atom_offset, atom_size); - debug_indent++; -#endif - if (atom_size < 8) - return 0; /* continue */ - if (get_be32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */ - url_fskip(pb, atom_size - 4); - return 0; - } - type = get_le32(pb); - if (type != MKTAG('m', 'd', 'a', 't')) { - url_fskip(pb, atom_size - 8); - return 0; - } - err = parse_mdat(parse_table, pb, type, atom_offset + 8, atom_size - 8, param); -#ifdef DEBUG - debug_indent--; -#endif - return err; -} - -static int parse_trak(const MOVParseTableEntry *parse_table, ByteIOContext *pb, UINT32 atom_type, INT64 atom_offset, INT64 atom_size, void *param) -{ - MOVContext *c; - AVStream *st; - MOVStreamContext *sc; -#ifdef DEBUG - print_atom("trak", atom_type, atom_offset, atom_size); -#endif - - c = (MOVContext *)param; - st = av_new_stream(c->fc, c->fc->nb_streams); - if (!st) return -2; - sc = av_malloc(sizeof(MOVStreamContext)); - sc->sample_to_chunk_index = -1; - st->priv_data = sc; - st->codec.codec_type = CODEC_TYPE_MOV_OTHER; - c->streams[c->fc->nb_streams-1] = sc; - return parse_default(parse_table, pb, atom_type, atom_offset, atom_size, param); -} - -static int parse_tkhd(const MOVParseTableEntry *parse_table, ByteIOContext *pb, UINT32 atom_type, INT64 atom_offset, INT64 atom_size, void *param) -{ - MOVContext *c; - AVStream *st; -#ifdef DEBUG - print_atom("tkhd", atom_type, atom_offset, atom_size); -#endif - - c = (MOVContext *)param; - st = c->fc->streams[c->fc->nb_streams-1]; - - get_byte(pb); /* version */ - - get_byte(pb); get_byte(pb); - get_byte(pb); /* flags */ - /* - MOV_TRACK_ENABLED 0x0001 - MOV_TRACK_IN_MOVIE 0x0002 - MOV_TRACK_IN_PREVIEW 0x0004 - MOV_TRACK_IN_POSTER 0x0008 - */ - - get_be32(pb); /* creation time */ - get_be32(pb); /* modification time */ - st->id = (int)get_be32(pb); /* track id (NOT 0 !)*/ - get_be32(pb); /* reserved */ - get_be32(pb); /* duration */ - get_be32(pb); /* reserved */ - get_be32(pb); /* reserved */ - - get_be16(pb); /* layer */ - get_be16(pb); /* alternate group */ - get_be16(pb); /* volume */ - get_be16(pb); /* reserved */ - - url_fskip(pb, 36); /* display matrix */ - - /* those are fixed-point */ - st->codec.width = get_be32(pb) >> 16; /* track width */ - st->codec.height = get_be32(pb) >> 16; /* track height */ - - return 0; -} - -static int parse_mdhd(const MOVParseTableEntry *parse_table, ByteIOContext *pb, UINT32 atom_type, INT64 atom_offset, INT64 atom_size, void *param) -{ - MOVContext *c; - AVStream *st; -#ifdef DEBUG - print_atom("mdhd", atom_type, atom_offset, atom_size); -#endif - - c = (MOVContext *)param; - st = c->fc->streams[c->fc->nb_streams-1]; - - get_byte(pb); /* version */ - - get_byte(pb); get_byte(pb); - get_byte(pb); /* flags */ - - get_be32(pb); /* creation time */ - get_be32(pb); /* modification time */ - - c->streams[c->total_streams]->time_scale = get_be32(pb); - -#ifdef DEBUG - printf("track[%i].time_scale = %li\n", c->fc->nb_streams-1, c->streams[c->total_streams]->time_scale); /* time scale */ -#endif - get_be32(pb); /* duration */ - - get_be16(pb); /* language */ - get_be16(pb); /* quality */ - - return 0; -} - -static int parse_hdlr(const MOVParseTableEntry *parse_table, ByteIOContext *pb, UINT32 atom_type, INT64 atom_offset, INT64 atom_size, void *param) -{ - MOVContext *c; - int len = 0; - char *buf; - UINT32 type; - AVStream *st; - UINT32 ctype; -#ifdef DEBUG - print_atom("hdlr", atom_type, atom_offset, atom_size); -#endif - c = (MOVContext *)param; - st = c->fc->streams[c->fc->nb_streams-1]; - - get_byte(pb); /* version */ - get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ - - /* component type */ - ctype = get_le32(pb); - type = get_le32(pb); /* component subtype */ - -#ifdef DEBUG - printf("ctype= %c%c%c%c (0x%08lx)\n", *((char *)&ctype), ((char *)&ctype)[1], ((char *)&ctype)[2], ((char *)&ctype)[3], (long) ctype); - printf("stype= %c%c%c%c\n", *((char *)&type), ((char *)&type)[1], ((char *)&type)[2], ((char *)&type)[3]); -#endif -#ifdef DEBUG -/* XXX: yeah this is ugly... */ - if(ctype == MKTAG('m', 'h', 'l', 'r')) { /* MOV */ - if(type == MKTAG('v', 'i', 'd', 'e')) - puts("hdlr: vide"); - else if(type == MKTAG('s', 'o', 'u', 'n')) - puts("hdlr: soun"); - } else if(ctype == 0) { /* MP4 */ - if(type == MKTAG('v', 'i', 'd', 'e')) - puts("hdlr: vide"); - else if(type == MKTAG('s', 'o', 'u', 'n')) - puts("hdlr: soun"); - else if(type == MKTAG('o', 'd', 's', 'm')) - puts("hdlr: odsm"); - else if(type == MKTAG('s', 'd', 's', 'm')) - puts("hdlr: sdsm"); - } else puts("hdlr: meta"); -#endif - - if(ctype == MKTAG('m', 'h', 'l', 'r')) { /* MOV */ - /* helps parsing the string hereafter... */ - c->mp4 = 0; - if(type == MKTAG('v', 'i', 'd', 'e')) - st->codec.codec_type = CODEC_TYPE_VIDEO; - else if(type == MKTAG('s', 'o', 'u', 'n')) - st->codec.codec_type = CODEC_TYPE_AUDIO; - } else if(ctype == 0) { /* MP4 */ - /* helps parsing the string hereafter... */ - c->mp4 = 1; - if(type == MKTAG('v', 'i', 'd', 'e')) - st->codec.codec_type = CODEC_TYPE_VIDEO; - else if(type == MKTAG('s', 'o', 'u', 'n')) - st->codec.codec_type = CODEC_TYPE_AUDIO; - } - get_be32(pb); /* component manufacture */ - get_be32(pb); /* component flags */ - get_be32(pb); /* component flags mask */ - - if(atom_size <= 24) - return 0; /* nothing left to read */ - /* XXX: MP4 uses a C string, not a pascal one */ - /* component name */ - - if(c->mp4) { - /* .mp4: C string */ - while(get_byte(pb) && (++len < (atom_size - 24))); - } else { - /* .mov: PASCAL string */ - len = get_byte(pb); - buf = av_malloc(len+1); - get_buffer(pb, buf, len); - buf[len] = '\0'; -#ifdef DEBUG - printf("**buf='%s'\n", buf); -#endif - av_free(buf); - } -#if 0 - len = get_byte(pb); - /* XXX: use a better heuristic */ - if(len < 32) { - /* assume that it is a Pascal like string */ - buf = av_malloc(len+1); - get_buffer(pb, buf, len); - buf[len] = '\0'; -#ifdef DEBUG - printf("**buf='%s'\n", buf); -#endif - av_free(buf); - } else { - /* MP4 string */ - for(;;) { - if (len == 0) - break; - len = get_byte(pb); - } - } -#endif - - return 0; -} - -static int mp4_read_descr_len(ByteIOContext *pb) -{ - int c, len, count; - - len = 0; - count = 0; - for(;;) { - c = get_byte(pb); - len = (len << 7) | (c & 0x7f); - if ((c & 0x80) == 0) - break; - if (++count == 4) - break; - } - return len; -} - -static int mp4_read_descr(ByteIOContext *pb, int *tag) -{ - int len; - *tag = get_byte(pb); - len = mp4_read_descr_len(pb); -#ifdef DEBUG - printf("MPEG4 description: tag=0x%02x len=%d\n", *tag, len); -#endif - return len; -} - -static int parse_stsd(const MOVParseTableEntry *parse_table, ByteIOContext *pb, UINT32 atom_type, INT64 atom_offset, INT64 atom_size, void *param) -{ - MOVContext *c; - int entries, size, samp_sz, frames_per_sample, id; - UINT32 format; - AVStream *st; - MOVStreamContext *sc; -#ifdef DEBUG - print_atom("stsd", atom_type, atom_offset, atom_size); -#endif - c = (MOVContext *)param; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = (MOVStreamContext *)st->priv_data; - - get_byte(pb); /* version */ - get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ - - entries = get_be32(pb); - - while(entries--) { - size = get_be32(pb); /* size */ - format = get_le32(pb); /* data format */ - - get_be32(pb); /* reserved */ - get_be16(pb); /* reserved */ - get_be16(pb); /* index */ - - /* for MPEG4: set codec type by looking for it */ - id = codec_get_id(mov_video_tags, format); - if (id >= 0) { - AVCodec *codec; - codec = avcodec_find_decoder(id); - if (codec) - st->codec.codec_type = codec->type; - } -#ifdef DEBUG - printf("size=%d 4CC= %c%c%c%c codec_type=%d\n", - size, - (format >> 0) & 0xff, - (format >> 8) & 0xff, - (format >> 16) & 0xff, - (format >> 24) & 0xff, - st->codec.codec_type); -#endif - if(st->codec.codec_type==CODEC_TYPE_VIDEO) { - st->codec.codec_tag = format; - st->codec.codec_id = codec_get_id(mov_video_tags, format); - get_be16(pb); /* version */ - get_be16(pb); /* revision level */ - get_be32(pb); /* vendor */ - get_be32(pb); /* temporal quality */ - get_be32(pb); /* spacial quality */ - st->codec.width = get_be16(pb); /* width */ - st->codec.height = get_be16(pb); /* height */ -#if 1 - if (st->codec.codec_id == CODEC_ID_MPEG4) { - /* in some MPEG4 the width/height are not correct, so - we ignore this info */ - st->codec.width = 0; - st->codec.height = 0; - } -#endif - get_be32(pb); /* horiz resolution */ - get_be32(pb); /* vert resolution */ - get_be32(pb); /* data size, always 0 */ - frames_per_sample = get_be16(pb); /* frame per samples */ -#ifdef DEBUG - printf("frames/samples = %d\n", frames_per_sample); -#endif - url_fskip(pb, 32); /* codec name */ - - get_be16(pb); /* depth */ - get_be16(pb); /* colortable id */ - - st->codec.frame_rate = 25 * FRAME_RATE_BASE; - - size -= (16+8*4+2+32+2*2); - while (size >= 8) { - int atom_size, atom_type; - INT64 start_pos; - - atom_size = get_be32(pb); - atom_type = get_le32(pb); - size -= 8; -#ifdef DEBUG - printf("VIDEO: atom_type=%c%c%c%c atom_size=%d size_left=%d\n", - (atom_type >> 0) & 0xff, - (atom_type >> 8) & 0xff, - (atom_type >> 16) & 0xff, - (atom_type >> 24) & 0xff, - atom_size, size); -#endif - start_pos = url_ftell(pb); - - switch(atom_type) { - case MKTAG('e', 's', 'd', 's'): - { - int tag, len; - /* Well, broken but suffisant for some MP4 streams */ - get_be32(pb); /* version + flags */ - len = mp4_read_descr(pb, &tag); - if (tag == 0x03) { - /* MP4ESDescrTag */ - get_be16(pb); /* ID */ - get_byte(pb); /* priority */ - len = mp4_read_descr(pb, &tag); - if (tag != 0x04) - goto fail; - /* MP4DecConfigDescrTag */ - get_byte(pb); /* objectTypeId */ - get_be32(pb); /* streamType + buffer size */ - get_be32(pb); /* max bit rate */ - get_be32(pb); /* avg bit rate */ - len = mp4_read_descr(pb, &tag); - if (tag != 0x05) - goto fail; - /* MP4DecSpecificDescrTag */ -#ifdef DEBUG - printf("Specific MPEG4 header len=%d\n", len); -#endif - sc->header_data = av_mallocz(len); - if (sc->header_data) { - get_buffer(pb, sc->header_data, len); - sc->header_len = len; - } - } - /* in any case, skip garbage */ - } - break; - default: - break; - } - fail: - url_fskip(pb, (atom_size - 8) - - ((url_ftell(pb) - start_pos))); - size -= atom_size - 8; - } - if (size > 0) { - /* unknown extension */ - url_fskip(pb, size); - } - } else { - st->codec.codec_tag = format; - - get_be16(pb); /* version */ - get_be16(pb); /* revision level */ - get_be32(pb); /* vendor */ - - st->codec.channels = get_be16(pb);/* channel count */ - samp_sz = get_be16(pb); /* sample size */ -#ifdef DEBUG - if(samp_sz != 16) - puts("!!! stsd: audio sample size is not 16 bit !"); -#endif - st->codec.codec_id = codec_get_id(mov_audio_tags, format); - /* handle specific s8 codec */ - if (st->codec.codec_id == CODEC_ID_PCM_S16BE && samp_sz == 8) - st->codec.codec_id = CODEC_ID_PCM_S8; - - get_be16(pb); /* compression id = 0*/ - get_be16(pb); /* packet size = 0 */ - - st->codec.sample_rate = ((get_be32(pb) >> 16)); - st->codec.bit_rate = 0; -#if 0 - - get_be16(pb); get_be16(pb); /* */ - get_be16(pb); /* */ - get_be16(pb); /* */ - get_be16(pb); /* */ - get_be16(pb); /* */ -#endif - if(size > 16) - url_fskip(pb, size-(16+20)); - } - } -/* - if(len) { - buf = av_malloc(len+1); - get_buffer(pb, buf, len); - buf[len] = '\0'; - puts(buf); - av_free(buf); - } -*/ - return 0; -} - -static int parse_stco(const MOVParseTableEntry *parse_table, ByteIOContext *pb, UINT32 atom_type, INT64 atom_offset, INT64 atom_size, void *param) -{ - MOVContext *c; - int entries, i; - AVStream *st; - MOVStreamContext *sc; -#ifdef DEBUG - print_atom("stco", atom_type, atom_offset, atom_size); -#endif - c = (MOVContext *)param; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = (MOVStreamContext *)st->priv_data; - - get_byte(pb); /* version */ - get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ - - entries = get_be32(pb); - sc->chunk_count = entries; - sc->chunk_offsets = av_malloc(entries * sizeof(INT64)); - if(atom_type == MKTAG('s', 't', 'c', 'o')) { - for(i=0; i<entries; i++) { - sc->chunk_offsets[i] = get_be32(pb); - } - } else if(atom_type == MKTAG('c', 'o', '6', '4')) { - for(i=0; i<entries; i++) { - sc->chunk_offsets[i] = get_be64(pb); - } - } else - return -1; -#ifdef DEBUG -/* - for(i=0; i<entries; i++) { - printf("chunk offset=0x%Lx\n", sc->chunk_offsets[i]); - } -*/ -#endif - return 0; -} - -static int parse_stsc(const MOVParseTableEntry *parse_table, ByteIOContext *pb, UINT32 atom_type, INT64 atom_offset, INT64 atom_size, void *param) -{ - MOVContext *c; - int entries, i; - AVStream *st; - MOVStreamContext *sc; -#ifdef DEBUG - print_atom("stsc", atom_type, atom_offset, atom_size); -#endif - c = (MOVContext *)param; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = (MOVStreamContext *)st->priv_data; - - get_byte(pb); /* version */ - get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ - - entries = get_be32(pb); -#ifdef DEBUG -printf("track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries); -#endif - sc->sample_to_chunk_sz = entries; - sc->sample_to_chunk = av_malloc(entries * sizeof(MOV_sample_to_chunk_tbl)); - for(i=0; i<entries; i++) { - sc->sample_to_chunk[i].first = get_be32(pb); - sc->sample_to_chunk[i].count = get_be32(pb); - sc->sample_to_chunk[i].id = get_be32(pb); -#ifdef DEBUG -/* printf("sample_to_chunk first=%ld count=%ld, id=%ld\n", sc->sample_to_chunk[i].first, sc->sample_to_chunk[i].count, sc->sample_to_chunk[i].id); */ -#endif - } - return 0; -} - -static int parse_stsz(const MOVParseTableEntry *parse_table, ByteIOContext *pb, UINT32 atom_type, INT64 atom_offset, INT64 atom_size, void *param) -{ - MOVContext *c; - int entries, i; - AVStream *st; - MOVStreamContext *sc; -#ifdef DEBUG - print_atom("stsz", atom_type, atom_offset, atom_size); -#endif - c = (MOVContext *)param; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = (MOVStreamContext *)st->priv_data; - - get_byte(pb); /* version */ - get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ - - sc->sample_size = get_be32(pb); - entries = get_be32(pb); - sc->sample_count = entries; -#ifdef DEBUG - printf("sample_size = %ld sample_count = %ld\n", sc->sample_size, sc->sample_count); -#endif - if(sc->sample_size) - return 0; /* there isn't any table following */ - sc->sample_sizes = av_malloc(entries * sizeof(long)); - for(i=0; i<entries; i++) { - sc->sample_sizes[i] = get_be32(pb); -#ifdef DEBUG -/* printf("sample_sizes[]=%ld\n", sc->sample_sizes[i]); */ -#endif - } - return 0; -} - -static int parse_stts(const MOVParseTableEntry *parse_table, ByteIOContext *pb, UINT32 atom_type, INT64 atom_offset, INT64 atom_size, void *param) -{ - MOVContext *c; - int entries, i; - AVStream *st; - MOVStreamContext *sc; -#ifdef DEBUG - print_atom("stts", atom_type, atom_offset, atom_size); -#endif - c = (MOVContext *)param; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = (MOVStreamContext *)st->priv_data; - - get_byte(pb); /* version */ - get_byte(pb); get_byte(pb); get_byte(pb); /* flags */ - entries = get_be32(pb); -#ifdef DEBUG -printf("track[%i].stts.entries = %i\n", c->fc->nb_streams-1, entries); -#endif - for(i=0; i<entries; i++) { - int sample_duration; - - get_be32(pb); - sample_duration = get_be32(pb); - - if (!i && st->codec.codec_type==CODEC_TYPE_VIDEO) { - st->codec.frame_rate = FRAME_RATE_BASE * c->streams[c->total_streams]->time_scale; - if (sample_duration) - st->codec.frame_rate /= sample_duration; -#ifdef DEBUG - printf("VIDEO FRAME RATE= %i (sd= %i)\n", st->codec.frame_rate, sample_duration); -#endif - } - } - return 0; -} - -#ifdef CONFIG_ZLIB -static int null_read_packet(void *opaque, UINT8 *buf, int buf_size) -{ - return -1; -} - -static int parse_cmov(const MOVParseTableEntry *parse_table, ByteIOContext *pb, UINT32 atom_type, INT64 atom_offset, INT64 atom_size, void *param) -{ - MOVContext *c; - ByteIOContext ctx; - char *cmov_data; - unsigned char *moov_data; /* uncompressed data */ - long cmov_len, moov_len; - int ret; -#ifdef DEBUG - print_atom("cmov", atom_type, atom_offset, atom_size); -#endif - c = (MOVContext *)param; - - get_be32(pb); /* dcom atom */ - if (get_le32(pb) != MKTAG( 'd', 'c', 'o', 'm' )) - return -1; - if (get_le32(pb) != MKTAG( 'z', 'l', 'i', 'b' )) { - puts("unknown compression for cmov atom !"); - return -1; - } - get_be32(pb); /* cmvd atom */ - if (get_le32(pb) != MKTAG( 'c', 'm', 'v', 'd' )) - return -1; - moov_len = get_be32(pb); /* uncompressed size */ - cmov_len = atom_size - 6 * 4; - - cmov_data = av_malloc(cmov_len); - if (!cmov_data) - return -1; - moov_data = av_malloc(moov_len); - if (!moov_data) { - av_free(cmov_data); - return -1; - } - get_buffer(pb, cmov_data, cmov_len); - if(uncompress (moov_data, &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK) - return -1; - if(init_put_byte(&ctx, moov_data, moov_len, 0, NULL, null_read_packet, NULL, NULL) != 0) - return -1; - ctx.buf_end = ctx.buffer + moov_len; - ret = parse_default(parse_table, &ctx, MKTAG( 'm', 'o', 'o', 'v' ), 0, moov_len, param); - av_free(moov_data); - av_free(cmov_data); - return ret; -} -#endif - -static const MOVParseTableEntry mov_default_parse_table[] = { -/* mp4 atoms */ -{ MKTAG( 'm', 'p', '4', 'a' ), parse_default }, -{ MKTAG( 'c', 'o', '6', '4' ), parse_stco }, -{ MKTAG( 's', 't', 'c', 'o' ), parse_stco }, -{ MKTAG( 'c', 'r', 'h', 'd' ), parse_default }, -{ MKTAG( 'c', 't', 't', 's' ), parse_leaf }, -{ MKTAG( 'c', 'p', 'r', 't' ), parse_default }, -{ MKTAG( 'u', 'r', 'l', ' ' ), parse_leaf }, -{ MKTAG( 'u', 'r', 'n', ' ' ), parse_leaf }, -{ MKTAG( 'd', 'i', 'n', 'f' ), parse_default }, -{ MKTAG( 'd', 'r', 'e', 'f' ), parse_leaf }, -{ MKTAG( 's', 't', 'd', 'p' ), parse_default }, -{ MKTAG( 'e', 's', 'd', 's' ), parse_default }, -{ MKTAG( 'e', 'd', 't', 's' ), parse_default }, -{ MKTAG( 'e', 'l', 's', 't' ), parse_leaf }, -{ MKTAG( 'u', 'u', 'i', 'd' ), parse_default }, -{ MKTAG( 'f', 'r', 'e', 'e' ), parse_leaf }, -{ MKTAG( 'h', 'd', 'l', 'r' ), parse_hdlr }, -{ MKTAG( 'h', 'm', 'h', 'd' ), parse_leaf }, -{ MKTAG( 'h', 'i', 'n', 't' ), parse_leaf }, -{ MKTAG( 'n', 'm', 'h', 'd' ), parse_leaf }, -{ MKTAG( 'm', 'p', '4', 's' ), parse_default }, -{ MKTAG( 'm', 'd', 'i', 'a' ), parse_default }, -{ MKTAG( 'm', 'd', 'a', 't' ), parse_mdat }, -{ MKTAG( 'm', 'd', 'h', 'd' ), parse_mdhd }, -{ MKTAG( 'm', 'i', 'n', 'f' ), parse_default }, -{ MKTAG( 'm', 'o', 'o', 'v' ), parse_moov }, -{ MKTAG( 'm', 'v', 'h', 'd' ), parse_mvhd }, -{ MKTAG( 'i', 'o', 'd', 's' ), parse_leaf }, -{ MKTAG( 'o', 'd', 'h', 'd' ), parse_default }, -{ MKTAG( 'm', 'p', 'o', 'd' ), parse_leaf }, -{ MKTAG( 's', 't', 's', 'd' ), parse_stsd }, -{ MKTAG( 's', 't', 's', 'z' ), parse_stsz }, -{ MKTAG( 's', 't', 'b', 'l' ), parse_default }, -{ MKTAG( 's', 't', 's', 'c' ), parse_stsc }, -{ MKTAG( 's', 'd', 'h', 'd' ), parse_default }, -{ MKTAG( 's', 't', 's', 'h' ), parse_default }, -{ MKTAG( 's', 'k', 'i', 'p' ), parse_default }, -{ MKTAG( 's', 'm', 'h', 'd' ), parse_leaf }, -{ MKTAG( 'd', 'p', 'n', 'd' ), parse_leaf }, -{ MKTAG( 's', 't', 's', 's' ), parse_leaf }, -{ MKTAG( 's', 't', 't', 's' ), parse_stts }, -{ MKTAG( 't', 'r', 'a', 'k' ), parse_trak }, -{ MKTAG( 't', 'k', 'h', 'd' ), parse_tkhd }, -{ MKTAG( 't', 'r', 'e', 'f' ), parse_default }, /* not really */ -{ MKTAG( 'u', 'd', 't', 'a' ), parse_leaf }, -{ MKTAG( 'v', 'm', 'h', 'd' ), parse_leaf }, -{ MKTAG( 'm', 'p', '4', 'v' ), parse_default }, -/* extra mp4 */ -{ MKTAG( 'M', 'D', 'E', 'S' ), parse_leaf }, -/* QT atoms */ -{ MKTAG( 'c', 'h', 'a', 'p' ), parse_leaf }, -{ MKTAG( 'c', 'l', 'i', 'p' ), parse_default }, -{ MKTAG( 'c', 'r', 'g', 'n' ), parse_leaf }, -{ MKTAG( 'k', 'm', 'a', 't' ), parse_leaf }, -{ MKTAG( 'm', 'a', 't', 't' ), parse_default }, -{ MKTAG( 'r', 'd', 'r', 'f' ), parse_leaf }, -{ MKTAG( 'r', 'm', 'd', 'a' ), parse_default }, -{ MKTAG( 'r', 'm', 'd', 'r' ), parse_leaf }, -//{ MKTAG( 'r', 'm', 'q', 'u' ), parse_leaf }, -{ MKTAG( 'r', 'm', 'r', 'a' ), parse_default }, -{ MKTAG( 's', 'c', 'p', 't' ), parse_leaf }, -{ MKTAG( 's', 'y', 'n', 'c' ), parse_leaf }, -{ MKTAG( 's', 's', 'r', 'c' ), parse_leaf }, -{ MKTAG( 't', 'c', 'm', 'd' ), parse_leaf }, -{ MKTAG( 'w', 'i', 'd', 'e' ), parse_wide }, /* place holder */ -#ifdef CONFIG_ZLIB -{ MKTAG( 'c', 'm', 'o', 'v' ), parse_cmov }, -#else -{ MKTAG( 'c', 'm', 'o', 'v' ), parse_leaf }, -#endif -{ 0L, parse_leaf } -}; - -static void mov_free_stream_context(MOVStreamContext *sc) -{ - if(sc) { - av_free(sc->chunk_offsets); - av_free(sc->sample_to_chunk); - av_free(sc->header_data); - av_free(sc); - } -} - -static uint32_t to_tag(uint8_t *buf) -{ - return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); -} - -static uint32_t to_be32(uint8_t *buf) -{ - return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; -} - -/* XXX: is it suffisant ? */ -static int mov_probe(AVProbeData *p) -{ - unsigned int offset; - uint32_t tag; - - /* check file header */ - if (p->buf_size <= 12) - return 0; - offset = 0; - for(;;) { - /* ignore invalid offset */ - if ((offset + 8) > (unsigned int)p->buf_size) - return 0; - tag = to_tag(p->buf + offset + 4); - switch(tag) { - case MKTAG( 'm', 'o', 'o', 'v' ): - case MKTAG( 'w', 'i', 'd', 'e' ): - case MKTAG( 'f', 'r', 'e', 'e' ): - case MKTAG( 'm', 'd', 'a', 't'): - return AVPROBE_SCORE_MAX; - case MKTAG( 'f', 't', 'y', 'p' ): - case MKTAG( 's', 'k', 'i', 'p' ): - offset = to_be32(p->buf) + offset; - break; - default: - /* unrecognized tag */ - return 0; - } - } - return 0; -} - -static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - MOVContext *mov = s->priv_data; - ByteIOContext *pb = &s->pb; - int i, j, nb, err; - INT64 size; - - mov->fc = s; -#if 0 - /* XXX: I think we should auto detect */ - if(s->iformat->name[1] == 'p') - mov->mp4 = 1; -#endif - if(!url_is_streamed(pb)) /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */ - size = url_filesize(url_fileno(pb)); - else - size = 0x7FFFFFFFFFFFFFFF; - -#ifdef DEBUG - printf("filesz=%Ld\n", size); -#endif - - /* check MOV header */ - err = parse_default(mov_default_parse_table, pb, 0L, 0LL, size, mov); - if(err<0 || (!mov->found_moov || !mov->found_mdat)) { - puts("header not found !!!"); - exit(1); - } -#ifdef DEBUG - printf("on_parse_exit_offset=%d\n", (int) url_ftell(pb)); -#endif - /* some cleanup : make sure we are on the mdat atom */ - if(!url_is_streamed(pb) && (url_ftell(pb) != mov->mdat_offset)) - url_fseek(pb, mov->mdat_offset, SEEK_SET); - - mov->next_chunk_offset = mov->mdat_offset; /* initialise reading */ - -#ifdef DEBUG - printf("mdat_reset_offset=%d\n", (int) url_ftell(pb)); -#endif - -#ifdef DEBUG - printf("streams= %d\n", s->nb_streams); -#endif - mov->total_streams = nb = s->nb_streams; - -#if 1 - for(i=0; i<s->nb_streams;) { - if(s->streams[i]->codec.codec_type == CODEC_TYPE_MOV_OTHER) {/* not audio, not video, delete */ - av_free(s->streams[i]); - for(j=i+1; j<s->nb_streams; j++) - s->streams[j-1] = s->streams[j]; - s->nb_streams--; - } else - i++; - } - for(i=0; i<s->nb_streams;i++) { - MOVStreamContext *sc; - sc = (MOVStreamContext *)s->streams[i]->priv_data; - sc->ffindex = i; - sc->is_ff_stream = 1; - } -#endif -#ifdef DEBUG - printf("real streams= %d\n", s->nb_streams); -#endif - return 0; -} - -/* Yes, this is ugly... I didn't write the specs of QT :p */ -/* XXX:remove useless commented code sometime */ -static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - MOVContext *mov = s->priv_data; - MOVStreamContext *sc; - INT64 offset = 0x0FFFFFFFFFFFFFFF; - int i; - int st_id = 0, size; - size = 0x0FFFFFFF; - -#ifdef MOV_SPLIT_CHUNKS - if (mov->partial) { - - int idx; - - st_id = mov->partial - 1; - idx = mov->streams[st_id]->sample_to_chunk_index; - if (idx < 0) return 0; - size = mov->streams[st_id]->sample_sizes[mov->streams[st_id]->current_sample]; - - mov->streams[st_id]->current_sample++; - mov->streams[st_id]->left_in_chunk--; - - if(mov->streams[st_id]->left_in_chunk <= 0) - mov->partial = 0; - offset = mov->next_chunk_offset; - /* extract the sample */ - - goto readchunk; - } -#endif - -again: - for(i=0; i<mov->total_streams; i++) { - if((mov->streams[i]->next_chunk < mov->streams[i]->chunk_count) - && (mov->streams[i]->chunk_offsets[mov->streams[i]->next_chunk] < offset)) { - st_id = i; - offset = mov->streams[i]->chunk_offsets[mov->streams[i]->next_chunk]; - } - } - mov->streams[st_id]->next_chunk++; - if(offset==0x0FFFFFFFFFFFFFFF) - return -1; - - if(mov->next_chunk_offset < offset) { /* some meta data */ - url_fskip(&s->pb, (offset - mov->next_chunk_offset)); - mov->next_chunk_offset = offset; - } - -//printf("chunk: [%i] %lli -> %lli\n", st_id, mov->next_chunk_offset, offset); - if(!mov->streams[st_id]->is_ff_stream) { - url_fskip(&s->pb, (offset - mov->next_chunk_offset)); - mov->next_chunk_offset = offset; - offset = 0x0FFFFFFFFFFFFFFF; - goto again; - } - - /* now get the chunk size... */ - - for(i=0; i<mov->total_streams; i++) { - if((mov->streams[i]->next_chunk < mov->streams[i]->chunk_count) - && ((mov->streams[i]->chunk_offsets[mov->streams[i]->next_chunk] - offset) < size)) { - size = mov->streams[i]->chunk_offsets[mov->streams[i]->next_chunk] - offset; - } - } -#ifdef MOV_SPLIT_CHUNKS - /* split chunks into samples */ - if(mov->streams[st_id]->sample_size == 0) { - int idx; - idx = mov->streams[st_id]->sample_to_chunk_index; - if ((idx + 1 < mov->streams[st_id]->sample_to_chunk_sz) - && (mov->streams[st_id]->next_chunk >= mov->streams[st_id]->sample_to_chunk[idx + 1].first)) - idx++; - mov->streams[st_id]->sample_to_chunk_index = idx; - if(idx >= 0 && mov->streams[st_id]->sample_to_chunk[idx].count != 1) { - mov->partial = st_id+1; - /* we'll have to get those samples before next chunk */ - mov->streams[st_id]->left_in_chunk = (mov->streams[st_id]->sample_to_chunk[idx].count) - 1; - size = mov->streams[st_id]->sample_sizes[mov->streams[st_id]->current_sample]; - } - - mov->streams[st_id]->current_sample++; - } -#endif - -readchunk: -//printf("chunk: [%i] %lli -> %lli (%i)\n", st_id, offset, offset + size, size); - if(size == 0x0FFFFFFF) - size = mov->mdat_size + mov->mdat_offset - offset; - if(size < 0) - return -1; - if(size == 0) - return -1; - url_fseek(&s->pb, offset, SEEK_SET); - sc = mov->streams[st_id]; - if (sc->header_len > 0) { - av_new_packet(pkt, size + sc->header_len); - memcpy(pkt->data, sc->header_data, sc->header_len); - get_buffer(&s->pb, pkt->data + sc->header_len, size); - /* free header */ - av_freep(&sc->header_data); - sc->header_len = 0; - } else { - av_new_packet(pkt, size); - get_buffer(&s->pb, pkt->data, pkt->size); - } - pkt->stream_index = sc->ffindex; - -#ifdef DEBUG -/* - printf("Packet (%d, %d, %ld) ", pkt->stream_index, st_id, pkt->size); - for(i=0; i<8; i++) - printf("%02x ", pkt->data[i]); - for(i=0; i<8; i++) - printf("%c ", (pkt->data[i]) & 0x7F); - puts(""); -*/ -#endif - - mov->next_chunk_offset = offset + size; - - return 0; -} - -static int mov_read_close(AVFormatContext *s) -{ - int i; - MOVContext *mov = s->priv_data; - for(i=0; i<mov->total_streams; i++) - mov_free_stream_context(mov->streams[i]); - for(i=0; i<s->nb_streams; i++) - av_freep(&s->streams[i]); - return 0; -} - -static AVInputFormat mov_iformat = { - "mov", - "QuickTime/MPEG4 format", - sizeof(MOVContext), - mov_probe, - mov_read_header, - mov_read_packet, - mov_read_close, -}; - -int mov_init(void) -{ - av_register_input_format(&mov_iformat); - return 0; -} diff --git a/libav/mpeg.c b/libav/mpeg.c deleted file mode 100644 index 748841881d..0000000000 --- a/libav/mpeg.c +++ /dev/null @@ -1,685 +0,0 @@ -/* - * MPEG1/2 mux/demux - * 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" - -#define MAX_PAYLOAD_SIZE 4096 -#define NB_STREAMS 2 - -typedef struct { - UINT8 buffer[MAX_PAYLOAD_SIZE]; - int buffer_ptr; - UINT8 id; - int max_buffer_size; /* in bytes */ - int packet_number; - INT64 start_pts; -} StreamInfo; - -typedef struct { - int packet_size; /* required packet size */ - int packet_data_max_size; /* maximum data size inside a packet */ - int packet_number; - int pack_header_freq; /* frequency (in packets^-1) at which we send pack headers */ - int system_header_freq; - int mux_rate; /* bitrate in units of 50 bytes/s */ - /* stream info */ - int audio_bound; - int video_bound; - int is_mpeg2; - int is_vcd; -} MpegMuxContext; - -#define PACK_START_CODE ((unsigned int)0x000001ba) -#define SYSTEM_HEADER_START_CODE ((unsigned int)0x000001bb) -#define SEQUENCE_END_CODE ((unsigned int)0x000001b7) -#define PACKET_START_CODE_MASK ((unsigned int)0xffffff00) -#define PACKET_START_CODE_PREFIX ((unsigned int)0x00000100) -#define ISO_11172_END_CODE ((unsigned int)0x000001b9) - -/* mpeg2 */ -#define PROGRAM_STREAM_MAP 0x1bc -#define PRIVATE_STREAM_1 0x1bd -#define PADDING_STREAM 0x1be -#define PRIVATE_STREAM_2 0x1bf - - -#define AUDIO_ID 0xc0 -#define VIDEO_ID 0xe0 - -extern AVOutputFormat mpeg1system_mux; -extern AVOutputFormat mpeg1vcd_mux; -extern AVOutputFormat mpeg2vob_mux; - -static int put_pack_header(AVFormatContext *ctx, - UINT8 *buf, INT64 timestamp) -{ - MpegMuxContext *s = ctx->priv_data; - PutBitContext pb; - - init_put_bits(&pb, buf, 128, NULL, NULL); - - put_bits(&pb, 32, PACK_START_CODE); - if (s->is_mpeg2) { - put_bits(&pb, 2, 0x2); - } else { - put_bits(&pb, 4, 0x2); - } - put_bits(&pb, 3, (UINT32)((timestamp >> 30) & 0x07)); - put_bits(&pb, 1, 1); - put_bits(&pb, 15, (UINT32)((timestamp >> 15) & 0x7fff)); - put_bits(&pb, 1, 1); - put_bits(&pb, 15, (UINT32)((timestamp) & 0x7fff)); - put_bits(&pb, 1, 1); - if (s->is_mpeg2) { - /* clock extension */ - put_bits(&pb, 9, 0); - put_bits(&pb, 1, 1); - } - put_bits(&pb, 1, 1); - put_bits(&pb, 22, s->mux_rate); - put_bits(&pb, 1, 1); - if (s->is_mpeg2) { - put_bits(&pb, 5, 0x1f); /* reserved */ - put_bits(&pb, 3, 0); /* stuffing length */ - } - flush_put_bits(&pb); - return pbBufPtr(&pb) - pb.buf; -} - -static int put_system_header(AVFormatContext *ctx, UINT8 *buf) -{ - MpegMuxContext *s = ctx->priv_data; - int size, rate_bound, i, private_stream_coded, id; - PutBitContext pb; - - init_put_bits(&pb, buf, 128, NULL, NULL); - - put_bits(&pb, 32, SYSTEM_HEADER_START_CODE); - put_bits(&pb, 16, 0); - put_bits(&pb, 1, 1); - - rate_bound = s->mux_rate; /* maximum bit rate of the multiplexed stream */ - put_bits(&pb, 22, rate_bound); - put_bits(&pb, 1, 1); /* marker */ - put_bits(&pb, 6, s->audio_bound); - - put_bits(&pb, 1, 1); /* variable bitrate */ - put_bits(&pb, 1, 1); /* non constrainted bit stream */ - - put_bits(&pb, 1, 0); /* audio locked */ - put_bits(&pb, 1, 0); /* video locked */ - put_bits(&pb, 1, 1); /* marker */ - - put_bits(&pb, 5, s->video_bound); - put_bits(&pb, 8, 0xff); /* reserved byte */ - - /* audio stream info */ - private_stream_coded = 0; - for(i=0;i<ctx->nb_streams;i++) { - StreamInfo *stream = ctx->streams[i]->priv_data; - id = stream->id; - if (id < 0xc0) { - /* special case for private streams (AC3 use that) */ - if (private_stream_coded) - continue; - private_stream_coded = 1; - id = 0xbd; - } - put_bits(&pb, 8, id); /* stream ID */ - put_bits(&pb, 2, 3); - if (id < 0xe0) { - /* audio */ - put_bits(&pb, 1, 0); - put_bits(&pb, 13, stream->max_buffer_size / 128); - } else { - /* video */ - put_bits(&pb, 1, 1); - put_bits(&pb, 13, stream->max_buffer_size / 1024); - } - } - flush_put_bits(&pb); - size = pbBufPtr(&pb) - pb.buf; - /* patch packet size */ - buf[4] = (size - 6) >> 8; - buf[5] = (size - 6) & 0xff; - - return size; -} - -static int mpeg_mux_init(AVFormatContext *ctx) -{ - MpegMuxContext *s = ctx->priv_data; - int bitrate, i, mpa_id, mpv_id, ac3_id; - AVStream *st; - StreamInfo *stream; - - s->packet_number = 0; - s->is_vcd = (ctx->oformat == &mpeg1vcd_mux); - s->is_mpeg2 = (ctx->oformat == &mpeg2vob_mux); - - if (s->is_vcd) - s->packet_size = 2324; /* VCD packet size */ - else - s->packet_size = 2048; - - /* startcode(4) + length(2) + flags(1) */ - s->packet_data_max_size = s->packet_size - 7; - s->audio_bound = 0; - s->video_bound = 0; - mpa_id = AUDIO_ID; - ac3_id = 0x80; - mpv_id = VIDEO_ID; - for(i=0;i<ctx->nb_streams;i++) { - st = ctx->streams[i]; - stream = av_mallocz(sizeof(StreamInfo)); - if (!stream) - goto fail; - st->priv_data = stream; - - switch(st->codec.codec_type) { - case CODEC_TYPE_AUDIO: - if (st->codec.codec_id == CODEC_ID_AC3) - stream->id = ac3_id++; - else - stream->id = mpa_id++; - stream->max_buffer_size = 4 * 1024; - s->audio_bound++; - break; - case CODEC_TYPE_VIDEO: - stream->id = mpv_id++; - stream->max_buffer_size = 46 * 1024; - s->video_bound++; - break; - default: - av_abort(); - } - } - - /* we increase slightly the bitrate to take into account the - headers. XXX: compute it exactly */ - bitrate = 2000; - for(i=0;i<ctx->nb_streams;i++) { - st = ctx->streams[i]; - bitrate += st->codec.bit_rate; - } - s->mux_rate = (bitrate + (8 * 50) - 1) / (8 * 50); - - if (s->is_vcd || s->is_mpeg2) - /* every packet */ - s->pack_header_freq = 1; - else - /* every 2 seconds */ - s->pack_header_freq = 2 * bitrate / s->packet_size / 8; - - if (s->is_mpeg2) - /* every 200 packets. Need to look at the spec. */ - s->system_header_freq = s->pack_header_freq * 40; - else if (s->is_vcd) - /* every 40 packets, this is my invention */ - s->system_header_freq = s->pack_header_freq * 40; - else - s->system_header_freq = s->pack_header_freq * 5; - - for(i=0;i<ctx->nb_streams;i++) { - stream = ctx->streams[i]->priv_data; - stream->buffer_ptr = 0; - stream->packet_number = 0; - stream->start_pts = -1; - } - return 0; - fail: - for(i=0;i<ctx->nb_streams;i++) { - av_free(ctx->streams[i]->priv_data); - } - return -ENOMEM; -} - -/* flush the packet on stream stream_index */ -static void flush_packet(AVFormatContext *ctx, int stream_index, int last_pkt) -{ - MpegMuxContext *s = ctx->priv_data; - StreamInfo *stream = ctx->streams[stream_index]->priv_data; - UINT8 *buf_ptr; - int size, payload_size, startcode, id, len, stuffing_size, i, header_len; - INT64 timestamp; - UINT8 buffer[128]; - int last = last_pkt ? 4 : 0; - - id = stream->id; - timestamp = stream->start_pts; - -#if 0 - printf("packet ID=%2x PTS=%0.3f\n", - id, timestamp / 90000.0); -#endif - - buf_ptr = buffer; - if (((s->packet_number % s->pack_header_freq) == 0)) { - /* output pack and systems header if needed */ - size = put_pack_header(ctx, buf_ptr, timestamp); - buf_ptr += size; - if ((s->packet_number % s->system_header_freq) == 0) { - size = put_system_header(ctx, buf_ptr); - buf_ptr += size; - } - } - size = buf_ptr - buffer; - put_buffer(&ctx->pb, buffer, size); - - /* packet header */ - if (s->is_mpeg2) { - header_len = 8; - } else { - header_len = 5; - } - payload_size = s->packet_size - (size + 6 + header_len + last); - if (id < 0xc0) { - startcode = PRIVATE_STREAM_1; - payload_size -= 4; - } else { - startcode = 0x100 + id; - } - stuffing_size = payload_size - stream->buffer_ptr; - if (stuffing_size < 0) - stuffing_size = 0; - - put_be32(&ctx->pb, startcode); - - put_be16(&ctx->pb, payload_size + header_len); - /* stuffing */ - for(i=0;i<stuffing_size;i++) - put_byte(&ctx->pb, 0xff); - - if (s->is_mpeg2) { - put_byte(&ctx->pb, 0x80); /* mpeg2 id */ - put_byte(&ctx->pb, 0x80); /* flags */ - put_byte(&ctx->pb, 0x05); /* header len (only pts is included) */ - } - put_byte(&ctx->pb, - (0x02 << 4) | - (((timestamp >> 30) & 0x07) << 1) | - 1); - put_be16(&ctx->pb, (UINT16)((((timestamp >> 15) & 0x7fff) << 1) | 1)); - put_be16(&ctx->pb, (UINT16)((((timestamp) & 0x7fff) << 1) | 1)); - - if (startcode == PRIVATE_STREAM_1) { - put_byte(&ctx->pb, id); - if (id >= 0x80 && id <= 0xbf) { - /* XXX: need to check AC3 spec */ - put_byte(&ctx->pb, 1); - put_byte(&ctx->pb, 0); - put_byte(&ctx->pb, 2); - } - } - - if (last_pkt) { - put_be32(&ctx->pb, ISO_11172_END_CODE); - } - /* output data */ - put_buffer(&ctx->pb, stream->buffer, payload_size - stuffing_size); - put_flush_packet(&ctx->pb); - - /* preserve remaining data */ - len = stream->buffer_ptr - payload_size; - if (len < 0) - len = 0; - memmove(stream->buffer, stream->buffer + stream->buffer_ptr - len, len); - stream->buffer_ptr = len; - - s->packet_number++; - stream->packet_number++; - stream->start_pts = -1; -} - -static int mpeg_mux_write_packet(AVFormatContext *ctx, int stream_index, - UINT8 *buf, int size, int pts) -{ - MpegMuxContext *s = ctx->priv_data; - AVStream *st = ctx->streams[stream_index]; - StreamInfo *stream = st->priv_data; - int len; - - while (size > 0) { - /* set pts */ - if (stream->start_pts == -1) { - stream->start_pts = pts; - } - len = s->packet_data_max_size - stream->buffer_ptr; - if (len > size) - len = size; - memcpy(stream->buffer + stream->buffer_ptr, buf, len); - stream->buffer_ptr += len; - buf += len; - size -= len; - while (stream->buffer_ptr >= s->packet_data_max_size) { - /* output the packet */ - if (stream->start_pts == -1) - stream->start_pts = pts; - flush_packet(ctx, stream_index, 0); - } - } - return 0; -} - -static int mpeg_mux_end(AVFormatContext *ctx) -{ - StreamInfo *stream; - int i; - - /* flush each packet */ - for(i=0;i<ctx->nb_streams;i++) { - stream = ctx->streams[i]->priv_data; - if (stream->buffer_ptr > 0) { - if (i == (ctx->nb_streams - 1)) - flush_packet(ctx, i, 1); - else - flush_packet(ctx, i, 0); - } - } - - /* write the end header */ - //put_be32(&ctx->pb, ISO_11172_END_CODE); - //put_flush_packet(&ctx->pb); - return 0; -} - -/*********************************************/ -/* demux code */ - -#define MAX_SYNC_SIZE 100000 - -static int mpegps_probe(AVProbeData *p) -{ - int code, c, i; - code = 0xff; - - /* we search the first start code. If it is a packet start code, - then we decide it is mpeg ps. We do not send highest value to - give a chance to mpegts */ - for(i=0;i<p->buf_size;i++) { - c = p->buf[i]; - code = (code << 8) | c; - if ((code & 0xffffff00) == 0x100) { - if (code == PACK_START_CODE || - code == SYSTEM_HEADER_START_CODE || - (code >= 0x1e0 && code <= 0x1ef) || - (code >= 0x1c0 && code <= 0x1df) || - code == PRIVATE_STREAM_2 || - code == PROGRAM_STREAM_MAP || - code == PRIVATE_STREAM_1 || - code == PADDING_STREAM) - return AVPROBE_SCORE_MAX - 1; - else - return 0; - } - } - return 0; -} - - -typedef struct MpegDemuxContext { - int header_state; -} MpegDemuxContext; - -static int find_start_code(ByteIOContext *pb, int *size_ptr, - UINT32 *header_state) -{ - unsigned int state, v; - int val, n; - - state = *header_state; - n = *size_ptr; - while (n > 0) { - if (url_feof(pb)) - break; - v = get_byte(pb); - n--; - if (state == 0x000001) { - state = ((state << 8) | v) & 0xffffff; - val = state; - goto found; - } - state = ((state << 8) | v) & 0xffffff; - } - val = -1; - found: - *header_state = state; - *size_ptr = n; - return val; -} - -static int mpegps_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - MpegDemuxContext *m = s->priv_data; - m->header_state = 0xff; - /* no need to do more */ - return 0; -} - -static INT64 get_pts(ByteIOContext *pb, int c) -{ - INT64 pts; - int val; - - if (c < 0) - c = get_byte(pb); - pts = (INT64)((c >> 1) & 0x07) << 30; - val = get_be16(pb); - pts |= (INT64)(val >> 1) << 15; - val = get_be16(pb); - pts |= (INT64)(val >> 1); - return pts; -} - -static int mpegps_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - MpegDemuxContext *m = s->priv_data; - AVStream *st; - int len, size, startcode, i, c, flags, header_len, type, codec_id; - INT64 pts, dts; - - /* next start code (should be immediately after) */ - redo: - m->header_state = 0xff; - size = MAX_SYNC_SIZE; - startcode = find_start_code(&s->pb, &size, &m->header_state); - //printf("startcode=%x pos=0x%Lx\n", startcode, url_ftell(&s->pb)); - if (startcode < 0) - return -EIO; - if (startcode == PACK_START_CODE) - goto redo; - if (startcode == SYSTEM_HEADER_START_CODE) - goto redo; - if (startcode == PADDING_STREAM || - startcode == PRIVATE_STREAM_2) { - /* skip them */ - len = get_be16(&s->pb); - url_fskip(&s->pb, len); - goto redo; - } - /* find matching stream */ - if (!((startcode >= 0x1c0 && startcode <= 0x1df) || - (startcode >= 0x1e0 && startcode <= 0x1ef) || - (startcode == 0x1bd))) - goto redo; - - len = get_be16(&s->pb); - pts = AV_NOPTS_VALUE; - dts = AV_NOPTS_VALUE; - /* stuffing */ - for(;;) { - c = get_byte(&s->pb); - len--; - /* XXX: for mpeg1, should test only bit 7 */ - if (c != 0xff) - break; - } - if ((c & 0xc0) == 0x40) { - /* buffer scale & size */ - get_byte(&s->pb); - c = get_byte(&s->pb); - len -= 2; - } - if ((c & 0xf0) == 0x20) { - pts = get_pts(&s->pb, c); - len -= 4; - } else if ((c & 0xf0) == 0x30) { - pts = get_pts(&s->pb, c); - dts = get_pts(&s->pb, -1); - len -= 9; - } else if ((c & 0xc0) == 0x80) { - /* mpeg 2 PES */ - if ((c & 0x30) != 0) { - fprintf(stderr, "Encrypted multiplex not handled\n"); - return -EIO; - } - flags = get_byte(&s->pb); - header_len = get_byte(&s->pb); - len -= 2; - if (header_len > len) - goto redo; - if ((flags & 0xc0) == 0x80) { - pts = get_pts(&s->pb, -1); - header_len -= 5; - len -= 5; - } if ((flags & 0xc0) == 0xc0) { - pts = get_pts(&s->pb, -1); - dts = get_pts(&s->pb, -1); - header_len -= 10; - len -= 10; - } - len -= header_len; - while (header_len > 0) { - get_byte(&s->pb); - header_len--; - } - } - if (startcode == 0x1bd) { - startcode = get_byte(&s->pb); - len--; - if (startcode >= 0x80 && startcode <= 0xbf) { - /* audio: skip header */ - get_byte(&s->pb); - get_byte(&s->pb); - get_byte(&s->pb); - len -= 3; - } - } - - /* now find stream */ - for(i=0;i<s->nb_streams;i++) { - st = s->streams[i]; - if (st->id == startcode) - goto found; - } - if (startcode >= 0x1e0 && startcode <= 0x1ef) { - type = CODEC_TYPE_VIDEO; - codec_id = CODEC_ID_MPEG1VIDEO; - } else if (startcode >= 0x1c0 && startcode <= 0x1df) { - type = CODEC_TYPE_AUDIO; - codec_id = CODEC_ID_MP2; - } else if (startcode >= 0x80 && startcode <= 0x9f) { - type = CODEC_TYPE_AUDIO; - codec_id = CODEC_ID_AC3; - } else { - skip: - /* skip packet */ - url_fskip(&s->pb, len); - goto redo; - } - /* no stream found: add a new stream */ - st = av_new_stream(s, startcode); - if (!st) - goto skip; - st->codec.codec_type = type; - st->codec.codec_id = codec_id; - found: - av_new_packet(pkt, len); - //printf("\nRead Packet ID: %x PTS: %f Size: %d", startcode, - // (float)pts/90000, len); - get_buffer(&s->pb, pkt->data, pkt->size); - pkt->pts = pts; - pkt->stream_index = st->index; - return 0; -} - -static int mpegps_read_close(AVFormatContext *s) -{ - return 0; -} - -static AVOutputFormat mpeg1system_mux = { - "mpeg", - "MPEG1 System format", - "video/x-mpeg", - "mpg,mpeg", - sizeof(MpegMuxContext), - CODEC_ID_MP2, - CODEC_ID_MPEG1VIDEO, - mpeg_mux_init, - mpeg_mux_write_packet, - mpeg_mux_end, -}; - -static AVOutputFormat mpeg1vcd_mux = { - "vcd", - "MPEG1 System format (VCD)", - "video/x-mpeg", - NULL, - sizeof(MpegMuxContext), - CODEC_ID_MP2, - CODEC_ID_MPEG1VIDEO, - mpeg_mux_init, - mpeg_mux_write_packet, - mpeg_mux_end, -}; - -static AVOutputFormat mpeg2vob_mux = { - "vob", - "MPEG2 PS format (VOB)", - "video/x-mpeg", - "vob", - sizeof(MpegMuxContext), - CODEC_ID_MP2, - CODEC_ID_MPEG1VIDEO, - mpeg_mux_init, - mpeg_mux_write_packet, - mpeg_mux_end, -}; - -static AVInputFormat mpegps_demux = { - "mpeg", - "MPEG PS format", - sizeof(MpegDemuxContext), - mpegps_probe, - mpegps_read_header, - mpegps_read_packet, - mpegps_read_close, - .flags = AVFMT_NOHEADER, -}; - -int mpegps_init(void) -{ - av_register_output_format(&mpeg1system_mux); - av_register_output_format(&mpeg1vcd_mux); - av_register_output_format(&mpeg2vob_mux); - av_register_input_format(&mpegps_demux); - return 0; -} diff --git a/libav/mpegts.c b/libav/mpegts.c deleted file mode 100644 index 2947d960e8..0000000000 --- a/libav/mpegts.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * MPEG2 transport stream (aka DVB) demux - * Copyright (c) 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" - -#define TS_FEC_PACKET_SIZE 204 -#define TS_PACKET_SIZE 188 -#define NB_PID_MAX 8192 - -enum MpegTSState { - MPEGTS_HEADER = 0, - MPEGTS_PESHEADER_FILL, - MPEGTS_PESHEADER_FLAGS, - MPEGTS_PESHEADER_SIZE, - MPEGTS_PESHEADER_READ, - MPEGTS_PAYLOAD, - MPEGTS_SKIP, -}; - -/* enough for PES header + length */ -#define MAX_HEADER_SIZE 6 - -typedef struct MpegTSStream { - int pid; - enum MpegTSState state; - int last_cc; /* last cc code (-1 if first packet) */ - /* used to get the format */ - int header_size; - int payload_size; - int pes_header_size; - AVStream *st; - unsigned char header[MAX_HEADER_SIZE]; -} MpegTSStream; - -typedef struct MpegTSContext { - int raw_packet_size; /* raw packet size, including FEC if present */ - MpegTSStream *pids[NB_PID_MAX]; -} MpegTSContext; - -/* autodetect fec presence. Must have at least 1024 bytes */ -static int get_packet_size(const unsigned char *buf, int size) -{ - int i; - - if (size < (TS_FEC_PACKET_SIZE * 5 + 1)) - return -1; - for(i=0;i<5;i++) { - if (buf[i * TS_PACKET_SIZE] != 0x47) - goto try_fec; - } - return TS_PACKET_SIZE; - try_fec: - for(i=0;i<5;i++) { - if (buf[i * TS_FEC_PACKET_SIZE] != 0x47) - return -1; - } - return TS_FEC_PACKET_SIZE; -} - -static int mpegts_probe(AVProbeData *p) -{ - int size; - size = get_packet_size(p->buf, p->buf_size); - if (size < 0) - return 0; - return AVPROBE_SCORE_MAX; -} - -static int mpegts_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - MpegTSContext *ts = s->priv_data; - ByteIOContext *pb = &s->pb; - unsigned char buf[1024]; - int len; - INT64 pos; - - /* read the first 1024 bytes to get packet size */ - pos = url_ftell(pb); - len = get_buffer(pb, buf, sizeof(buf)); - if (len != sizeof(buf)) - goto fail; - ts->raw_packet_size = get_packet_size(buf, sizeof(buf)); - if (ts->raw_packet_size <= 0) - goto fail; - /* go again to the start */ - url_fseek(pb, pos, SEEK_SET); - return 0; - fail: - return -1; -} - -/* return non zero if a packet could be constructed */ -static int mpegts_push_data(AVFormatContext *s, MpegTSStream *tss, - AVPacket *pkt, - const unsigned char *buf, int buf_size, int is_start) -{ - AVStream *st; - const unsigned char *p; - int len, code, codec_type, codec_id; - - if (is_start) { - tss->state = MPEGTS_HEADER; - tss->header_size = 0; - } - p = buf; - while (buf_size > 0) { - len = buf_size; - switch(tss->state) { - case MPEGTS_HEADER: - if (len > MAX_HEADER_SIZE - tss->header_size) - len = MAX_HEADER_SIZE - tss->header_size; - memcpy(tss->header, p, len); - tss->header_size += len; - p += len; - buf_size -= len; - if (tss->header_size == MAX_HEADER_SIZE) { - /* we got all the PES or section header. We can now - decide */ -#if 0 - av_hex_dump(tss->header, tss->header_size); -#endif - if (tss->header[0] == 0x00 && tss->header[1] == 0x00 && - tss->header[2] == 0x01) { - /* it must be an mpeg2 PES stream */ - /* XXX: add AC3 support */ - code = tss->header[3] | 0x100; - if (!((code >= 0x1c0 && code <= 0x1df) || - (code >= 0x1e0 && code <= 0x1ef))) - goto skip; - if (!tss->st) { - /* allocate stream */ - if (code >= 0x1c0 && code <= 0x1df) { - codec_type = CODEC_TYPE_AUDIO; - codec_id = CODEC_ID_MP2; - } else { - codec_type = CODEC_TYPE_VIDEO; - codec_id = CODEC_ID_MPEG1VIDEO; - } - st = av_new_stream(s, tss->pid); - if (st) { - st->priv_data = tss; - st->codec.codec_type = codec_type; - st->codec.codec_id = codec_id; - tss->st = st; - } - } - tss->state = MPEGTS_PESHEADER_FILL; - tss->payload_size = (tss->header[4] << 8) | tss->header[5]; - if (tss->payload_size == 0) - tss->payload_size = 65536; - } else { - /* otherwise, it should be a table */ - /* skip packet */ - skip: - tss->state = MPEGTS_SKIP; - continue; - } - } - break; - /**********************************************/ - /* PES packing parsing */ - case MPEGTS_PESHEADER_FILL: - /* skip filling */ - code = *p++; - buf_size--; - tss->payload_size--; - if (code != 0xff) { - if ((code & 0xc0) != 0x80) - goto skip; - tss->state = MPEGTS_PESHEADER_FLAGS; - } - break; - case MPEGTS_PESHEADER_FLAGS: - code = *p++; - buf_size--; - tss->payload_size--; - tss->state = MPEGTS_PESHEADER_SIZE; - break; - case MPEGTS_PESHEADER_SIZE: - tss->pes_header_size = *p++; - buf_size--; - tss->payload_size--; - tss->state = MPEGTS_PESHEADER_READ; - break; - case MPEGTS_PESHEADER_READ: - /* currently we do nothing except skipping */ - if (len > tss->pes_header_size) - len = tss->pes_header_size; - p += len; - buf_size -= len; - tss->pes_header_size -= len; - tss->payload_size -= len; - if (tss->pes_header_size == 0) - tss->state = MPEGTS_PAYLOAD; - break; - case MPEGTS_PAYLOAD: - if (len > tss->payload_size) - len = tss->payload_size; - if (len > 0) { - if (tss->st && av_new_packet(pkt, buf_size) == 0) { - memcpy(pkt->data, p, buf_size); - pkt->stream_index = tss->st->index; - return 1; - } - tss->payload_size -= len; - } - buf_size = 0; - break; - case MPEGTS_SKIP: - buf_size = 0; - break; - } - } - return 0; -} - -static int mpegts_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - MpegTSContext *ts = s->priv_data; - MpegTSStream *tss; - ByteIOContext *pb = &s->pb; - unsigned char packet[TS_FEC_PACKET_SIZE]; - int len, pid, cc, cc_ok, afc; - const unsigned char *p; - - for(;;) { - len = get_buffer(pb, packet, ts->raw_packet_size); - if (len != ts->raw_packet_size) - return AVERROR_IO; - /* check paquet sync byte */ - /* XXX: accept to resync ? */ - if (packet[0] != 0x47) - return AVERROR_INVALIDDATA; - - pid = ((packet[1] & 0x1f) << 8) | packet[2]; - tss = ts->pids[pid]; - if (tss == NULL) { - /* if no pid found, then add a pid context */ - tss = av_mallocz(sizeof(MpegTSStream)); - if (!tss) - continue; - ts->pids[pid] = tss; - tss->pid = pid; - tss->last_cc = -1; - // printf("new pid=0x%x\n", pid); - } - - /* continuity check (currently not used) */ - cc = (packet[3] & 0xf); - cc_ok = (tss->last_cc < 0) || ((((tss->last_cc + 1) & 0x0f) == cc)); - tss->last_cc = cc; - - /* skip adaptation field */ - afc = (packet[3] >> 4) & 3; - p = packet + 4; - if (afc == 0) /* reserved value */ - continue; - if (afc == 2) /* adaptation field only */ - continue; - if (afc == 3) { - /* skip adapation field */ - p += p[0] + 1; - } - /* if past the end of packet, ignore */ - if (p >= packet + TS_PACKET_SIZE) - continue; - - if (mpegts_push_data(s, tss, pkt, p, TS_PACKET_SIZE - (p - packet), - packet[1] & 0x40)) - break; - } - return 0; -} - -static int mpegts_read_close(AVFormatContext *s) -{ - MpegTSContext *ts = s->priv_data; - int i; - for(i=0;i<NB_PID_MAX;i++) - av_free(ts->pids[i]); - return 0; -} - -AVInputFormat mpegts_demux = { - "mpegts", - "MPEG2 transport stream format", - sizeof(MpegTSContext), - mpegts_probe, - mpegts_read_header, - mpegts_read_packet, - mpegts_read_close, - .flags = AVFMT_NOHEADER | AVFMT_SHOW_IDS, -}; - -int mpegts_init(void) -{ - av_register_input_format(&mpegts_demux); - return 0; -} diff --git a/libav/ogg.c b/libav/ogg.c deleted file mode 100644 index 7c7c96c61f..0000000000 --- a/libav/ogg.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Ogg bitstream support - * Mark Hills <mark@pogo.org.uk> - * - * Uses libogg, but requires libvorbisenc to construct correct headers - * when containing Vorbis stream -- currently the only format supported - */ - -#include <stdio.h> -#include <time.h> - -#include <ogg/ogg.h> -#include <vorbis/vorbisenc.h> - -#include "avformat.h" -#include "oggvorbis.h" - -#define DECODER_BUFFER_SIZE 4096 - - -typedef struct OggContext { - /* output */ - ogg_stream_state os ; - int header_handled ; - ogg_int64_t base_packet_no ; - ogg_int64_t base_granule_pos ; - - /* input */ - ogg_sync_state oy ; -} OggContext ; - - -static int ogg_write_header(AVFormatContext *avfcontext) { - OggContext *context ; - AVCodecContext *avccontext ; - vorbis_info vi ; - vorbis_dsp_state vd ; - vorbis_comment vc ; - vorbis_block vb ; - ogg_packet header, header_comm, header_code ; - int n ; - - if(!(context = malloc(sizeof(OggContext)))) - return -1 ; - avfcontext->priv_data = context ; - - srand(time(NULL)); - ogg_stream_init(&context->os, rand()); - - for(n = 0 ; n < avfcontext->nb_streams ; n++) { - avccontext = &avfcontext->streams[n]->codec ; - - /* begin vorbis specific code */ - - vorbis_info_init(&vi) ; - - /* code copied from libavcodec/oggvorbis.c */ - - if(oggvorbis_init_encoder(&vi, avccontext) < 0) { - fprintf(stderr, "ogg_write_header: init_encoder failed") ; - return -1 ; - } - - vorbis_analysis_init(&vd, &vi) ; - vorbis_block_init(&vd, &vb) ; - - vorbis_comment_init(&vc) ; - vorbis_comment_add_tag(&vc, "encoder", "ffmpeg") ; - if(*avfcontext->title) - vorbis_comment_add_tag(&vc, "title", avfcontext->title) ; - - vorbis_analysis_headerout(&vd, &vc, &header, - &header_comm, &header_code) ; - ogg_stream_packetin(&context->os, &header) ; - ogg_stream_packetin(&context->os, &header_comm) ; - ogg_stream_packetin(&context->os, &header_code) ; - - vorbis_comment_clear(&vc) ; - - /* end of vorbis specific code */ - - context->header_handled = 0 ; - context->base_packet_no = 0 ; - } - - return 0 ; -} - - -static int ogg_write_packet(AVFormatContext *avfcontext, - int stream_index, - unsigned char *buf, int size, int force_pts) -{ - OggContext *context = avfcontext->priv_data ; - ogg_packet *op ; - ogg_page og ; - int l = 0 ; - - /* flush header packets so audio starts on a new page */ - - if(!context->header_handled) { - while(ogg_stream_flush(&context->os, &og)) { - put_buffer(&avfcontext->pb, og.header, og.header_len) ; - put_buffer(&avfcontext->pb, og.body, og.body_len) ; - put_flush_packet(&avfcontext->pb); - } - context->header_handled = 1 ; - } - - while(l < size) { - op = (ogg_packet*)(buf + l) ; - op->packet = buf + l + sizeof(ogg_packet) ; /* fix data pointer */ - - if(!context->base_packet_no) { /* this is the first packet */ - context->base_packet_no = op->packetno ; - context->base_granule_pos = op->granulepos ; - } - - /* correct the fields in the packet -- essential for streaming */ - - op->packetno -= context->base_packet_no ; - op->granulepos -= context->base_granule_pos ; - - ogg_stream_packetin(&context->os, op) ; - l += sizeof(ogg_packet) + op->bytes ; - - while(ogg_stream_pageout(&context->os, &og)) { - put_buffer(&avfcontext->pb, og.header, og.header_len) ; - put_buffer(&avfcontext->pb, og.body, og.body_len) ; - put_flush_packet(&avfcontext->pb); - } - } - - return 0; -} - - -static int ogg_write_trailer(AVFormatContext *avfcontext) { - OggContext *context = avfcontext->priv_data ; - ogg_page og ; - - while(ogg_stream_flush(&context->os, &og)) { - put_buffer(&avfcontext->pb, og.header, og.header_len) ; - put_buffer(&avfcontext->pb, og.body, og.body_len) ; - put_flush_packet(&avfcontext->pb); - } - - ogg_stream_clear(&context->os) ; - return 0 ; -} - - -static AVOutputFormat ogg_oformat = { - "ogg", - "Ogg Vorbis", - "audio/x-vorbis", - "ogg", - sizeof(OggContext), - CODEC_ID_VORBIS, - 0, - ogg_write_header, - ogg_write_packet, - ogg_write_trailer, -} ; - - -static int next_packet(AVFormatContext *avfcontext, ogg_packet *op) { - OggContext *context = avfcontext->priv_data ; - ogg_page og ; - char *buf ; - - while(ogg_stream_packetout(&context->os, op) != 1) { - - /* while no pages are available, read in more data to the sync */ - while(ogg_sync_pageout(&context->oy, &og) != 1) { - buf = ogg_sync_buffer(&context->oy, DECODER_BUFFER_SIZE) ; - if(get_buffer(&avfcontext->pb, buf, DECODER_BUFFER_SIZE) <= 0) - return 1 ; - ogg_sync_wrote(&context->oy, DECODER_BUFFER_SIZE) ; - } - - /* got a page. Feed it into the stream and get the packet */ - if(ogg_stream_pagein(&context->os, &og) != 0) - return 1 ; - } - - return 0 ; -} - - -static int ogg_read_header(AVFormatContext *avfcontext, AVFormatParameters *ap) -{ - OggContext *context ; - char *buf ; - ogg_page og ; - AVStream *ast ; - - if(!(context = malloc(sizeof(OggContext)))) { - perror("malloc") ; - return -1 ; - } - avfcontext->priv_data = context ; - - ogg_sync_init(&context->oy) ; - buf = ogg_sync_buffer(&context->oy, DECODER_BUFFER_SIZE) ; - - if(get_buffer(&avfcontext->pb, buf, DECODER_BUFFER_SIZE) <= 0) - return -EIO ; - - ogg_sync_wrote(&context->oy, DECODER_BUFFER_SIZE) ; - ogg_sync_pageout(&context->oy, &og) ; - ogg_stream_init(&context->os, ogg_page_serialno(&og)) ; - ogg_stream_pagein(&context->os, &og) ; - - /* currently only one vorbis stream supported */ - - ast = av_new_stream(avfcontext, 0) ; - if(!ast) - return AVERROR_NOMEM ; - - ast->codec.codec_type = CODEC_TYPE_AUDIO ; - ast->codec.codec_id = CODEC_ID_VORBIS ; - - return 0 ; -} - - -static int ogg_read_packet(AVFormatContext *avfcontext, AVPacket *pkt) { - ogg_packet op ; - - if(next_packet(avfcontext, &op)) - return -EIO ; - if(av_new_packet(pkt, sizeof(ogg_packet) + op.bytes) < 0) - return -EIO ; - pkt->stream_index = 0 ; - memcpy(pkt->data, &op, sizeof(ogg_packet)) ; - memcpy(pkt->data + sizeof(ogg_packet), op.packet, op.bytes) ; - - return sizeof(ogg_packet) + op.bytes ; -} - - -static int ogg_read_close(AVFormatContext *avfcontext) { - OggContext *context = avfcontext->priv_data ; - - ogg_stream_clear(&context->os) ; - ogg_sync_clear(&context->oy) ; - - return 0 ; -} - - -static AVInputFormat ogg_iformat = { - "ogg", - "Ogg Vorbis", - sizeof(OggContext), - NULL, - ogg_read_header, - ogg_read_packet, - ogg_read_close, - .extensions = "ogg", -} ; - - -int ogg_init(void) { - av_register_output_format(&ogg_oformat) ; - av_register_input_format(&ogg_iformat); - return 0 ; -} diff --git a/libav/raw.c b/libav/raw.c deleted file mode 100644 index 518206ea56..0000000000 --- a/libav/raw.c +++ /dev/null @@ -1,509 +0,0 @@ -/* - * RAW encoder and decoder - * Copyright (c) 2001 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" - -/* simple formats */ -int raw_write_header(struct AVFormatContext *s) -{ - return 0; -} - -int raw_write_packet(struct AVFormatContext *s, - int stream_index, - unsigned char *buf, int size, int force_pts) -{ - put_buffer(&s->pb, buf, size); - put_flush_packet(&s->pb); - return 0; -} - -int raw_write_trailer(struct AVFormatContext *s) -{ - return 0; -} - -/* raw input */ -static int raw_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - AVStream *st; - int id; - - st = av_new_stream(s, 0); - if (!st) - return AVERROR_NOMEM; - if (ap) { - id = s->iformat->value; - if (id == CODEC_ID_RAWVIDEO) { - st->codec.codec_type = CODEC_TYPE_VIDEO; - } else { - st->codec.codec_type = CODEC_TYPE_AUDIO; - } - st->codec.codec_id = id; - - switch(st->codec.codec_type) { - case CODEC_TYPE_AUDIO: - st->codec.sample_rate = ap->sample_rate; - st->codec.channels = ap->channels; - break; - case CODEC_TYPE_VIDEO: - st->codec.frame_rate = ap->frame_rate; - st->codec.width = ap->width; - st->codec.height = ap->height; - break; - default: - return -1; - } - } else { - return -1; - } - return 0; -} - -#define RAW_PACKET_SIZE 1024 - -int raw_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - int ret, size; - AVStream *st = s->streams[0]; - - size= RAW_PACKET_SIZE; - - if (av_new_packet(pkt, size) < 0) - return -EIO; - - pkt->stream_index = 0; - ret = get_buffer(&s->pb, pkt->data, size); - if (ret <= 0) { - av_free_packet(pkt); - return -EIO; - } - /* note: we need to modify the packet size here to handle the last - packet */ - pkt->size = ret; - return ret; -} - -int raw_read_close(AVFormatContext *s) -{ - return 0; -} - -/* mp3 read */ -static int mp3_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - AVStream *st; - - st = av_new_stream(s, 0); - if (!st) - return AVERROR_NOMEM; - - st->codec.codec_type = CODEC_TYPE_AUDIO; - st->codec.codec_id = CODEC_ID_MP2; - /* the parameters will be extracted from the compressed bitstream */ - return 0; -} - -/* mpeg1/h263 input */ -static int video_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - AVStream *st; - - st = av_new_stream(s, 0); - if (!st) - return AVERROR_NOMEM; - - st->codec.codec_type = CODEC_TYPE_VIDEO; - st->codec.codec_id = s->iformat->value; - /* for mjpeg, specify frame rate */ - /* for mpeg4 specify it too (most mpeg4 streams dont have the fixed_vop_rate set ...)*/ - if (st->codec.codec_id == CODEC_ID_MJPEG || st->codec.codec_id == CODEC_ID_MPEG4) { - if (ap) { - st->codec.frame_rate = ap->frame_rate; - } else { - st->codec.frame_rate = 25 * FRAME_RATE_BASE; - } - } - return 0; -} - -#define SEQ_START_CODE 0x000001b3 -#define GOP_START_CODE 0x000001b8 -#define PICTURE_START_CODE 0x00000100 - -/* XXX: improve that by looking at several start codes */ -static int mpegvideo_probe(AVProbeData *p) -{ - int code, c, i; - code = 0xff; - - /* we search the first start code. If it is a sequence, gop or - picture start code then we decide it is an mpeg video - stream. We do not send highest value to give a chance to mpegts */ - for(i=0;i<p->buf_size;i++) { - c = p->buf[i]; - code = (code << 8) | c; - if ((code & 0xffffff00) == 0x100) { - if (code == SEQ_START_CODE || - code == GOP_START_CODE || - code == PICTURE_START_CODE) - return 50 - 1; - else - return 0; - } - } - return 0; -} - -AVInputFormat mp3_iformat = { - "mp3", - "MPEG audio", - 0, - NULL, - mp3_read_header, - raw_read_packet, - raw_read_close, - .extensions = "mp2,mp3", /* XXX: use probe */ -}; - -AVOutputFormat mp2_oformat = { - "mp2", - "MPEG audio layer 2", - "audio/x-mpeg", - "mp2,mp3", - 0, - CODEC_ID_MP2, - 0, - raw_write_header, - raw_write_packet, - raw_write_trailer, -}; - - -AVInputFormat ac3_iformat = { - "ac3", - "raw ac3", - 0, - NULL, - raw_read_header, - raw_read_packet, - raw_read_close, - .extensions = "ac3", - .value = CODEC_ID_AC3, -}; - -AVOutputFormat ac3_oformat = { - "ac3", - "raw ac3", - "audio/x-ac3", - "ac3", - 0, - CODEC_ID_AC3, - 0, - raw_write_header, - raw_write_packet, - raw_write_trailer, -}; - -AVOutputFormat h263_oformat = { - "h263", - "raw h263", - "video/x-h263", - "h263", - 0, - 0, - CODEC_ID_H263, - raw_write_header, - raw_write_packet, - raw_write_trailer, -}; - -AVInputFormat m4v_iformat = { - "m4v", - "raw MPEG4 video format", - 0, - NULL /*mpegvideo_probe*/, - video_read_header, - raw_read_packet, - raw_read_close, - .extensions = "m4v", //FIXME remove after writing mpeg4_probe - .value = CODEC_ID_MPEG4, -}; - -AVOutputFormat m4v_oformat = { - "m4v", - "raw MPEG4 video format", - NULL, - "m4v", - 0, - CODEC_ID_NONE, - CODEC_ID_MPEG4, - raw_write_header, - raw_write_packet, - raw_write_trailer, -}; - -AVInputFormat mpegvideo_iformat = { - "mpegvideo", - "MPEG video", - 0, - mpegvideo_probe, - video_read_header, - raw_read_packet, - raw_read_close, - .value = CODEC_ID_MPEG1VIDEO, -}; - -AVOutputFormat mpeg1video_oformat = { - "mpeg1video", - "MPEG video", - "video/x-mpeg", - "mpg,mpeg", - 0, - 0, - CODEC_ID_MPEG1VIDEO, - raw_write_header, - raw_write_packet, - raw_write_trailer, -}; - -AVInputFormat mjpeg_iformat = { - "mjpeg", - "MJPEG video", - 0, - NULL, - video_read_header, - raw_read_packet, - raw_read_close, - .extensions = "mjpg,mjpeg", - .value = CODEC_ID_MJPEG, -}; - -AVOutputFormat mjpeg_oformat = { - "mjpeg", - "MJPEG video", - "video/x-mjpeg", - "mjpg,mjpeg", - 0, - 0, - CODEC_ID_MJPEG, - raw_write_header, - raw_write_packet, - raw_write_trailer, -}; - -/* pcm formats */ - -#define PCMDEF(name, long_name, ext, codec) \ -AVInputFormat pcm_ ## name ## _iformat = {\ - #name,\ - long_name,\ - 0,\ - NULL,\ - raw_read_header,\ - raw_read_packet,\ - raw_read_close,\ - .extensions = ext,\ - .value = codec,\ -};\ -\ -AVOutputFormat pcm_ ## name ## _oformat = {\ - #name,\ - long_name,\ - NULL,\ - ext,\ - 0,\ - codec,\ - 0,\ - raw_write_header,\ - raw_write_packet,\ - raw_write_trailer,\ -}; - -#ifdef WORDS_BIGENDIAN -#define BE_DEF(s) s -#define LE_DEF(s) NULL -#else -#define BE_DEF(s) NULL -#define LE_DEF(s) s -#endif - - -PCMDEF(s16le, "pcm signed 16 bit little endian format", - LE_DEF("sw"), CODEC_ID_PCM_S16LE) - -PCMDEF(s16be, "pcm signed 16 bit big endian format", - BE_DEF("sw"), CODEC_ID_PCM_S16BE) - -PCMDEF(u16le, "pcm unsigned 16 bit little endian format", - LE_DEF("uw"), CODEC_ID_PCM_U16LE) - -PCMDEF(u16be, "pcm unsigned 16 bit big endian format", - BE_DEF("uw"), CODEC_ID_PCM_U16BE) - -PCMDEF(s8, "pcm signed 8 bit format", - "sb", CODEC_ID_PCM_S8) - -PCMDEF(u8, "pcm unsigned 8 bit format", - "ub", CODEC_ID_PCM_U8) - -PCMDEF(mulaw, "pcm mu law format", - "ul", CODEC_ID_PCM_MULAW) - -PCMDEF(alaw, "pcm A law format", - "al", CODEC_ID_PCM_ALAW) - -int rawvideo_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - int packet_size, ret, width, height; - AVStream *st = s->streams[0]; - - width = st->codec.width; - height = st->codec.height; - - switch(st->codec.pix_fmt) { - case PIX_FMT_YUV420P: - packet_size = (width * height * 3) / 2; - break; - case PIX_FMT_YUV422: - packet_size = (width * height * 2); - break; - case PIX_FMT_BGR24: - case PIX_FMT_RGB24: - packet_size = (width * height * 3); - break; - default: - av_abort(); - break; - } - - if (av_new_packet(pkt, packet_size) < 0) - return -EIO; - - pkt->stream_index = 0; -#if 0 - /* bypass buffered I/O */ - ret = url_read(url_fileno(&s->pb), pkt->data, pkt->size); -#else - ret = get_buffer(&s->pb, pkt->data, pkt->size); -#endif - if (ret != pkt->size) { - av_free_packet(pkt); - return -EIO; - } else { - return 0; - } -} - -AVInputFormat rawvideo_iformat = { - "rawvideo", - "raw video format", - 0, - NULL, - raw_read_header, - rawvideo_read_packet, - raw_read_close, - .extensions = "yuv", - .value = CODEC_ID_RAWVIDEO, -}; - -AVOutputFormat rawvideo_oformat = { - "rawvideo", - "raw video format", - NULL, - "yuv", - 0, - CODEC_ID_NONE, - CODEC_ID_RAWVIDEO, - raw_write_header, - raw_write_packet, - raw_write_trailer, -}; - -static int null_write_packet(struct AVFormatContext *s, - int stream_index, - unsigned char *buf, int size, int force_pts) -{ - return 0; -} - -AVOutputFormat null_oformat = { - "null", - "null video format", - NULL, - NULL, - 0, -#ifdef WORDS_BIGENDIAN - CODEC_ID_PCM_S16BE, -#else - CODEC_ID_PCM_S16LE, -#endif - CODEC_ID_RAWVIDEO, - raw_write_header, - null_write_packet, - raw_write_trailer, - .flags = AVFMT_NOFILE | AVFMT_RAWPICTURE, -}; - -int raw_init(void) -{ - av_register_input_format(&mp3_iformat); - av_register_output_format(&mp2_oformat); - - av_register_input_format(&ac3_iformat); - av_register_output_format(&ac3_oformat); - - av_register_output_format(&h263_oformat); - - av_register_input_format(&m4v_iformat); - av_register_output_format(&m4v_oformat); - - av_register_input_format(&mpegvideo_iformat); - av_register_output_format(&mpeg1video_oformat); - - av_register_input_format(&mjpeg_iformat); - av_register_output_format(&mjpeg_oformat); - - av_register_input_format(&pcm_s16le_iformat); - av_register_output_format(&pcm_s16le_oformat); - av_register_input_format(&pcm_s16be_iformat); - av_register_output_format(&pcm_s16be_oformat); - av_register_input_format(&pcm_u16le_iformat); - av_register_output_format(&pcm_u16le_oformat); - av_register_input_format(&pcm_u16be_iformat); - av_register_output_format(&pcm_u16be_oformat); - av_register_input_format(&pcm_s8_iformat); - av_register_output_format(&pcm_s8_oformat); - av_register_input_format(&pcm_u8_iformat); - av_register_output_format(&pcm_u8_oformat); - av_register_input_format(&pcm_mulaw_iformat); - av_register_output_format(&pcm_mulaw_oformat); - av_register_input_format(&pcm_alaw_iformat); - av_register_output_format(&pcm_alaw_oformat); - - av_register_input_format(&rawvideo_iformat); - av_register_output_format(&rawvideo_oformat); - - av_register_output_format(&null_oformat); - return 0; -} diff --git a/libav/rm.c b/libav/rm.c deleted file mode 100644 index be90a27c89..0000000000 --- a/libav/rm.c +++ /dev/null @@ -1,773 +0,0 @@ -/* - * "Real" compatible mux and demux. - * Copyright (c) 2000, 2001 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" - -/* in ms */ -#define BUFFER_DURATION 0 - -typedef struct { - int nb_packets; - int packet_total_size; - int packet_max_size; - /* codec related output */ - int bit_rate; - float frame_rate; - int nb_frames; /* current frame number */ - int total_frames; /* total number of frames */ - int num; - AVCodecContext *enc; -} StreamInfo; - -typedef struct { - StreamInfo streams[2]; - StreamInfo *audio_stream, *video_stream; - int data_pos; /* position of the data after the header */ - int nb_packets; -} RMContext; - -static void put_str(ByteIOContext *s, const char *tag) -{ - put_be16(s,strlen(tag)); - while (*tag) { - put_byte(s, *tag++); - } -} - -static void put_str8(ByteIOContext *s, const char *tag) -{ - put_byte(s, strlen(tag)); - while (*tag) { - put_byte(s, *tag++); - } -} - -static void rv10_write_header(AVFormatContext *ctx, - int data_size, int index_pos) -{ - RMContext *rm = ctx->priv_data; - ByteIOContext *s = &ctx->pb; - StreamInfo *stream; - unsigned char *data_offset_ptr, *start_ptr; - const char *desc, *mimetype; - int nb_packets, packet_total_size, packet_max_size, size, packet_avg_size, i; - int bit_rate, v, duration, flags, data_pos; - - start_ptr = s->buf_ptr; - - put_tag(s, ".RMF"); - put_be32(s,18); /* header size */ - put_be16(s,0); - put_be32(s,0); - put_be32(s,4 + ctx->nb_streams); /* num headers */ - - put_tag(s,"PROP"); - put_be32(s, 50); - put_be16(s, 0); - packet_max_size = 0; - packet_total_size = 0; - nb_packets = 0; - bit_rate = 0; - duration = 0; - for(i=0;i<ctx->nb_streams;i++) { - StreamInfo *stream = &rm->streams[i]; - bit_rate += stream->bit_rate; - if (stream->packet_max_size > packet_max_size) - packet_max_size = stream->packet_max_size; - nb_packets += stream->nb_packets; - packet_total_size += stream->packet_total_size; - /* select maximum duration */ - v = (int) (1000.0 * (float)stream->total_frames / stream->frame_rate); - if (v > duration) - duration = v; - } - put_be32(s, bit_rate); /* max bit rate */ - put_be32(s, bit_rate); /* avg bit rate */ - put_be32(s, packet_max_size); /* max packet size */ - if (nb_packets > 0) - packet_avg_size = packet_total_size / nb_packets; - else - packet_avg_size = 0; - put_be32(s, packet_avg_size); /* avg packet size */ - put_be32(s, nb_packets); /* num packets */ - put_be32(s, duration); /* duration */ - put_be32(s, BUFFER_DURATION); /* preroll */ - put_be32(s, index_pos); /* index offset */ - /* computation of data the data offset */ - data_offset_ptr = s->buf_ptr; - put_be32(s, 0); /* data offset : will be patched after */ - put_be16(s, ctx->nb_streams); /* num streams */ - flags = 1 | 2; /* save allowed & perfect play */ - if (url_is_streamed(s)) - flags |= 4; /* live broadcast */ - put_be16(s, flags); - - /* comments */ - - put_tag(s,"CONT"); - size = strlen(ctx->title) + strlen(ctx->author) + strlen(ctx->copyright) + - strlen(ctx->comment) + 4 * 2 + 10; - put_be32(s,size); - put_be16(s,0); - put_str(s, ctx->title); - put_str(s, ctx->author); - put_str(s, ctx->copyright); - put_str(s, ctx->comment); - - for(i=0;i<ctx->nb_streams;i++) { - int codec_data_size; - - stream = &rm->streams[i]; - - if (stream->enc->codec_type == CODEC_TYPE_AUDIO) { - desc = "The Audio Stream"; - mimetype = "audio/x-pn-realaudio"; - codec_data_size = 73; - } else { - desc = "The Video Stream"; - mimetype = "video/x-pn-realvideo"; - codec_data_size = 34; - } - - put_tag(s,"MDPR"); - size = 10 + 9 * 4 + strlen(desc) + strlen(mimetype) + codec_data_size; - put_be32(s, size); - put_be16(s, 0); - - put_be16(s, i); /* stream number */ - put_be32(s, stream->bit_rate); /* max bit rate */ - put_be32(s, stream->bit_rate); /* avg bit rate */ - put_be32(s, stream->packet_max_size); /* max packet size */ - if (stream->nb_packets > 0) - packet_avg_size = stream->packet_total_size / - stream->nb_packets; - else - packet_avg_size = 0; - put_be32(s, packet_avg_size); /* avg packet size */ - put_be32(s, 0); /* start time */ - put_be32(s, BUFFER_DURATION); /* preroll */ - /* duration */ - if (url_is_streamed(s) || !stream->total_frames) - put_be32(s, (int)(3600 * 1000)); - else - put_be32(s, (int)(stream->total_frames * 1000 / stream->frame_rate)); - put_str8(s, desc); - put_str8(s, mimetype); - put_be32(s, codec_data_size); - - if (stream->enc->codec_type == CODEC_TYPE_AUDIO) { - int coded_frame_size, fscode, sample_rate; - sample_rate = stream->enc->sample_rate; - coded_frame_size = (stream->enc->bit_rate * - stream->enc->frame_size) / (8 * sample_rate); - /* audio codec info */ - put_tag(s, ".ra"); - put_byte(s, 0xfd); - put_be32(s, 0x00040000); /* version */ - put_tag(s, ".ra4"); - put_be32(s, 0x01b53530); /* stream length */ - put_be16(s, 4); /* unknown */ - put_be32(s, 0x39); /* header size */ - - switch(sample_rate) { - case 48000: - case 24000: - case 12000: - fscode = 1; - break; - default: - case 44100: - case 22050: - case 11025: - fscode = 2; - break; - case 32000: - case 16000: - case 8000: - fscode = 3; - } - put_be16(s, fscode); /* codec additional info, for AC3, seems - to be a frequency code */ - /* special hack to compensate rounding errors... */ - if (coded_frame_size == 557) - coded_frame_size--; - put_be32(s, coded_frame_size); /* frame length */ - put_be32(s, 0x51540); /* unknown */ - put_be32(s, 0x249f0); /* unknown */ - put_be32(s, 0x249f0); /* unknown */ - put_be16(s, 0x01); - /* frame length : seems to be very important */ - put_be16(s, coded_frame_size); - put_be32(s, 0); /* unknown */ - put_be16(s, stream->enc->sample_rate); /* sample rate */ - put_be32(s, 0x10); /* unknown */ - put_be16(s, stream->enc->channels); - put_str8(s, "Int0"); /* codec name */ - put_str8(s, "dnet"); /* codec name */ - put_be16(s, 0); /* title length */ - put_be16(s, 0); /* author length */ - put_be16(s, 0); /* copyright length */ - put_byte(s, 0); /* end of header */ - } else { - /* video codec info */ - put_be32(s,34); /* size */ - put_tag(s,"VIDORV10"); - put_be16(s, stream->enc->width); - put_be16(s, stream->enc->height); - put_be16(s, (int) stream->frame_rate); /* frames per seconds ? */ - put_be32(s,0); /* unknown meaning */ - put_be16(s, (int) stream->frame_rate); /* unknown meaning */ - put_be32(s,0); /* unknown meaning */ - put_be16(s, 8); /* unknown meaning */ - /* Seems to be the codec version: only use basic H263. The next - versions seems to add a diffential DC coding as in - MPEG... nothing new under the sun */ - put_be32(s,0x10000000); - //put_be32(s,0x10003000); - } - } - - /* patch data offset field */ - data_pos = s->buf_ptr - start_ptr; - rm->data_pos = data_pos; - data_offset_ptr[0] = data_pos >> 24; - data_offset_ptr[1] = data_pos >> 16; - data_offset_ptr[2] = data_pos >> 8; - data_offset_ptr[3] = data_pos; - - /* data stream */ - put_tag(s,"DATA"); - put_be32(s,data_size + 10 + 8); - put_be16(s,0); - - put_be32(s, nb_packets); /* number of packets */ - put_be32(s,0); /* next data header */ -} - -static void write_packet_header(AVFormatContext *ctx, StreamInfo *stream, - int length, int key_frame) -{ - int timestamp; - ByteIOContext *s = &ctx->pb; - - stream->nb_packets++; - stream->packet_total_size += length; - if (length > stream->packet_max_size) - stream->packet_max_size = length; - - put_be16(s,0); /* version */ - put_be16(s,length + 12); - put_be16(s, stream->num); /* stream number */ - timestamp = (1000 * (float)stream->nb_frames) / stream->frame_rate; - put_be32(s, timestamp); /* timestamp */ - put_byte(s, 0); /* reserved */ - put_byte(s, key_frame ? 2 : 0); /* flags */ -} - -static int rm_write_header(AVFormatContext *s) -{ - RMContext *rm = s->priv_data; - StreamInfo *stream; - int n; - AVCodecContext *codec; - - for(n=0;n<s->nb_streams;n++) { - s->streams[n]->id = n; - codec = &s->streams[n]->codec; - stream = &rm->streams[n]; - memset(stream, 0, sizeof(StreamInfo)); - stream->num = n; - stream->bit_rate = codec->bit_rate; - stream->enc = codec; - - switch(codec->codec_type) { - case CODEC_TYPE_AUDIO: - rm->audio_stream = stream; - stream->frame_rate = (float)codec->sample_rate / (float)codec->frame_size; - /* XXX: dummy values */ - stream->packet_max_size = 1024; - stream->nb_packets = 0; - stream->total_frames = stream->nb_packets; - break; - case CODEC_TYPE_VIDEO: - rm->video_stream = stream; - stream->frame_rate = (float)codec->frame_rate / (float)FRAME_RATE_BASE; - /* XXX: dummy values */ - stream->packet_max_size = 4096; - stream->nb_packets = 0; - stream->total_frames = stream->nb_packets; - break; - default: - av_abort(); - } - } - - rv10_write_header(s, 0, 0); - put_flush_packet(&s->pb); - return 0; -} - -static int rm_write_audio(AVFormatContext *s, UINT8 *buf, int size) -{ - UINT8 *buf1; - RMContext *rm = s->priv_data; - ByteIOContext *pb = &s->pb; - StreamInfo *stream = rm->audio_stream; - int i; - - /* XXX: suppress this malloc */ - buf1= (UINT8*) av_malloc( size * sizeof(UINT8) ); - - write_packet_header(s, stream, size, stream->enc->key_frame); - - /* for AC3, the words seems to be reversed */ - for(i=0;i<size;i+=2) { - buf1[i] = buf[i+1]; - buf1[i+1] = buf[i]; - } - put_buffer(pb, buf1, size); - put_flush_packet(pb); - stream->nb_frames++; - av_free(buf1); - return 0; -} - -static int rm_write_video(AVFormatContext *s, UINT8 *buf, int size) -{ - RMContext *rm = s->priv_data; - ByteIOContext *pb = &s->pb; - StreamInfo *stream = rm->video_stream; - int key_frame = stream->enc->key_frame; - - /* XXX: this is incorrect: should be a parameter */ - - /* Well, I spent some time finding the meaning of these bits. I am - not sure I understood everything, but it works !! */ -#if 1 - write_packet_header(s, stream, size + 7, key_frame); - /* bit 7: '1' if final packet of a frame converted in several packets */ - put_byte(pb, 0x81); - /* bit 7: '1' if I frame. bits 6..0 : sequence number in current - frame starting from 1 */ - if (key_frame) { - put_byte(pb, 0x81); - } else { - put_byte(pb, 0x01); - } - put_be16(pb, 0x4000 | (size)); /* total frame size */ - put_be16(pb, 0x4000 | (size)); /* offset from the start or the end */ -#else - /* full frame */ - write_packet_header(s, size + 6); - put_byte(pb, 0xc0); - put_be16(pb, 0x4000 | size); /* total frame size */ - put_be16(pb, 0x4000 + packet_number * 126); /* position in stream */ -#endif - put_byte(pb, stream->nb_frames & 0xff); - - put_buffer(pb, buf, size); - put_flush_packet(pb); - - stream->nb_frames++; - return 0; -} - -static int rm_write_packet(AVFormatContext *s, int stream_index, - UINT8 *buf, int size, int force_pts) -{ - if (s->streams[stream_index]->codec.codec_type == - CODEC_TYPE_AUDIO) - return rm_write_audio(s, buf, size); - else - return rm_write_video(s, buf, size); -} - -static int rm_write_trailer(AVFormatContext *s) -{ - RMContext *rm = s->priv_data; - int data_size, index_pos, i; - ByteIOContext *pb = &s->pb; - - if (!url_is_streamed(&s->pb)) { - /* end of file: finish to write header */ - index_pos = url_fseek(pb, 0, SEEK_CUR); - data_size = index_pos - rm->data_pos; - - /* index */ - put_tag(pb, "INDX"); - put_be32(pb, 10 + 10 * s->nb_streams); - put_be16(pb, 0); - - for(i=0;i<s->nb_streams;i++) { - put_be32(pb, 0); /* zero indices */ - put_be16(pb, i); /* stream number */ - put_be32(pb, 0); /* next index */ - } - /* undocumented end header */ - put_be32(pb, 0); - put_be32(pb, 0); - - url_fseek(pb, 0, SEEK_SET); - for(i=0;i<s->nb_streams;i++) - rm->streams[i].total_frames = rm->streams[i].nb_frames; - rv10_write_header(s, data_size, index_pos); - } else { - /* undocumented end header */ - put_be32(pb, 0); - put_be32(pb, 0); - } - put_flush_packet(pb); - return 0; -} - -/***************************************************/ - -static void get_str(ByteIOContext *pb, char *buf, int buf_size) -{ - int len, i; - char *q; - - len = get_be16(pb); - q = buf; - for(i=0;i<len;i++) { - if (i < buf_size - 1) - *q++ = get_byte(pb); - } - *q = '\0'; -} - -static void get_str8(ByteIOContext *pb, char *buf, int buf_size) -{ - int len, i; - char *q; - - len = get_byte(pb); - q = buf; - for(i=0;i<len;i++) { - if (i < buf_size - 1) - *q++ = get_byte(pb); - } - *q = '\0'; -} - -static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - RMContext *rm = s->priv_data; - AVStream *st; - ByteIOContext *pb = &s->pb; - unsigned int tag, v; - int tag_size, size, codec_data_size, i; - INT64 codec_pos; - unsigned int h263_hack_version; - char buf[128]; - int flags = 0; - - if (get_le32(pb) != MKTAG('.', 'R', 'M', 'F')) - return -EIO; - - get_be32(pb); /* header size */ - get_be16(pb); - get_be32(pb); - get_be32(pb); /* number of headers */ - - for(;;) { - if (url_feof(pb)) - goto fail; - tag = get_le32(pb); - tag_size = get_be32(pb); - get_be16(pb); -#if 0 - printf("tag=%c%c%c%c (%08x) size=%d\n", - (tag) & 0xff, - (tag >> 8) & 0xff, - (tag >> 16) & 0xff, - (tag >> 24) & 0xff, - tag, - tag_size); -#endif - if (tag_size < 10) - goto fail; - switch(tag) { - case MKTAG('P', 'R', 'O', 'P'): - /* file header */ - get_be32(pb); /* max bit rate */ - get_be32(pb); /* avg bit rate */ - get_be32(pb); /* max packet size */ - get_be32(pb); /* avg packet size */ - get_be32(pb); /* nb packets */ - get_be32(pb); /* duration */ - get_be32(pb); /* preroll */ - get_be32(pb); /* index offset */ - get_be32(pb); /* data offset */ - get_be16(pb); /* nb streams */ - flags = get_be16(pb); /* flags */ - break; - case MKTAG('C', 'O', 'N', 'T'): - get_str(pb, s->title, sizeof(s->title)); - get_str(pb, s->author, sizeof(s->author)); - get_str(pb, s->copyright, sizeof(s->copyright)); - get_str(pb, s->comment, sizeof(s->comment)); - break; - case MKTAG('M', 'D', 'P', 'R'): - st = av_mallocz(sizeof(AVStream)); - if (!st) - goto fail; - s->streams[s->nb_streams++] = st; - st->id = get_be16(pb); - get_be32(pb); /* max bit rate */ - st->codec.bit_rate = get_be32(pb); /* bit rate */ - get_be32(pb); /* max packet size */ - get_be32(pb); /* avg packet size */ - get_be32(pb); /* start time */ - get_be32(pb); /* preroll */ - get_be32(pb); /* duration */ - get_str8(pb, buf, sizeof(buf)); /* desc */ - get_str8(pb, buf, sizeof(buf)); /* mimetype */ - codec_data_size = get_be32(pb); - codec_pos = url_ftell(pb); - - v = get_be32(pb); - if (v == MKTAG(0xfd, 'a', 'r', '.')) { - /* ra type header */ - get_be32(pb); /* version */ - get_be32(pb); /* .ra4 */ - get_be32(pb); - get_be16(pb); - get_be32(pb); /* header size */ - get_be16(pb); /* add codec info */ - get_be32(pb); /* coded frame size */ - get_be32(pb); /* ??? */ - get_be32(pb); /* ??? */ - get_be32(pb); /* ??? */ - get_be16(pb); /* 1 */ - get_be16(pb); /* coded frame size */ - get_be32(pb); - st->codec.sample_rate = get_be16(pb); - get_be32(pb); - st->codec.channels = get_be16(pb); - get_str8(pb, buf, sizeof(buf)); /* desc */ - get_str8(pb, buf, sizeof(buf)); /* desc */ - st->codec.codec_type = CODEC_TYPE_AUDIO; - if (!strcmp(buf, "dnet")) { - st->codec.codec_id = CODEC_ID_AC3; - } else { - st->codec.codec_id = CODEC_ID_NONE; - pstrcpy(st->codec.codec_name, sizeof(st->codec.codec_name), - buf); - } - } else { - if (get_le32(pb) != MKTAG('V', 'I', 'D', 'O')) { - fail1: - fprintf(stderr, "Unsupported video codec\n"); - goto fail; - } - st->codec.codec_tag = get_le32(pb); - if (st->codec.codec_tag != MKTAG('R', 'V', '1', '0')) - goto fail1; - st->codec.width = get_be16(pb); - st->codec.height = get_be16(pb); - st->codec.frame_rate = get_be16(pb) * FRAME_RATE_BASE; - st->codec.codec_type = CODEC_TYPE_VIDEO; - get_be32(pb); - get_be16(pb); - get_be32(pb); - get_be16(pb); - /* modification of h263 codec version (!) */ - h263_hack_version = get_be32(pb); - switch(h263_hack_version) { - case 0x10000000: - case 0x10003000: - case 0x10003001: - st->codec.sub_id = h263_hack_version; - st->codec.codec_id = CODEC_ID_RV10; - break; - default: - /* not handled */ - st->codec.codec_id = CODEC_ID_NONE; - break; - } - } - /* skip codec info */ - size = url_ftell(pb) - codec_pos; - url_fskip(pb, codec_data_size - size); - break; - case MKTAG('D', 'A', 'T', 'A'): - goto header_end; - default: - /* unknown tag: skip it */ - url_fskip(pb, tag_size - 10); - break; - } - } - header_end: - rm->nb_packets = get_be32(pb); /* number of packets */ - if (!rm->nb_packets && (flags & 4)) - rm->nb_packets = 3600 * 25; - get_be32(pb); /* next data header */ - return 0; - - fail: - for(i=0;i<s->nb_streams;i++) { - av_free(s->streams[i]); - } - return -EIO; -} - -static int get_num(ByteIOContext *pb, int *len) -{ - int n, n1; - - n = get_be16(pb); - (*len)-=2; - if (n >= 0x4000) { - return n - 0x4000; - } else { - n1 = get_be16(pb); - (*len)-=2; - return (n << 16) | n1; - } -} - -static int rm_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - RMContext *rm = s->priv_data; - ByteIOContext *pb = &s->pb; - AVStream *st; - int len, num, timestamp, i, tmp, j; - UINT8 *ptr; - int flags; - - redo: - if (rm->nb_packets == 0) - return -EIO; - get_be16(pb); - len = get_be16(pb); - if (len < 12) - return -EIO; - num = get_be16(pb); - timestamp = get_be32(pb); - get_byte(pb); /* reserved */ - flags = get_byte(pb); /* flags */ - rm->nb_packets--; - len -= 12; - - st = NULL; - for(i=0;i<s->nb_streams;i++) { - st = s->streams[i]; - if (num == st->id) - break; - } - if (i == s->nb_streams) { - /* skip packet if unknown number */ - url_fskip(pb, len); - goto redo; - } - - if (st->codec.codec_type == CODEC_TYPE_VIDEO) { - int full_frame, h, pic_num; - - h= get_byte(pb); - if ((h & 0xc0) == 0xc0) { - int len2, pos; - full_frame = 1; - len2= get_num(pb, &len); - pos = get_num(pb, &len); - //printf("pos:%d\n",len); - len -= 2; - } else { - int seq, frame_size, pos; - full_frame = 0; - seq = get_byte(pb); - frame_size = get_num(pb, &len); - pos = get_num(pb, &len); - //printf("seq:%d, size:%d, pos:%d\n",seq,frame_size,pos); - len -= 3; - } - /* picture number */ - pic_num= get_byte(pb); - - //XXX/FIXME/HACK, demuxer should be fixed to send complete frames ... - if(st->codec.slice_offset==NULL) st->codec.slice_offset= (int*)malloc(sizeof(int)); - st->codec.slice_count= full_frame; - st->codec.slice_offset[0]= 0; - } - - av_new_packet(pkt, len); - pkt->stream_index = i; - get_buffer(pb, pkt->data, len); - - /* for AC3, needs to swap bytes */ - if (st->codec.codec_id == CODEC_ID_AC3) { - ptr = pkt->data; - for(j=0;j<len;j+=2) { - tmp = ptr[0]; - ptr[0] = ptr[1]; - ptr[1] = tmp; - ptr += 2; - } - } - return 0; -} - -static int rm_read_close(AVFormatContext *s) -{ - return 0; -} - -static int rm_probe(AVProbeData *p) -{ - /* check file header */ - if (p->buf_size <= 32) - return 0; - if (p->buf[0] == '.' && p->buf[1] == 'R' && - p->buf[2] == 'M' && p->buf[3] == 'F' && - p->buf[4] == 0 && p->buf[5] == 0) - return AVPROBE_SCORE_MAX; - else - return 0; -} - -static AVInputFormat rm_iformat = { - "rm", - "rm format", - sizeof(RMContext), - rm_probe, - rm_read_header, - rm_read_packet, - rm_read_close, -}; - -static AVOutputFormat rm_oformat = { - "rm", - "rm format", - "audio/x-pn-realaudio", - "rm,ra", - sizeof(RMContext), - CODEC_ID_AC3, - CODEC_ID_RV10, - rm_write_header, - rm_write_packet, - rm_write_trailer, -}; - -int rm_init(void) -{ - av_register_input_format(&rm_iformat); - av_register_output_format(&rm_oformat); - return 0; -} diff --git a/libav/rtp.c b/libav/rtp.c deleted file mode 100644 index f36da6d41d..0000000000 --- a/libav/rtp.c +++ /dev/null @@ -1,687 +0,0 @@ -/* - * RTP input/output format - * Copyright (c) 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" - -#include <unistd.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#ifndef __BEOS__ -# include <arpa/inet.h> -#else -# include "barpainet.h" -#endif -#include <netdb.h> - -//#define DEBUG - - -/* TODO: - add RTCP statistics reporting (should be optional). - - - add support for h263/mpeg4 packetized output : IDEA: send a - buffer to 'rtp_write_packet' contains all the packets for ONE - frame. Each packet should have a four byte header containing - the length in big endian format (same trick as - 'url_open_dyn_packet_buf') -*/ - -#define RTP_VERSION 2 - -#define RTP_MAX_SDES 256 /* maximum text length for SDES */ - -/* RTCP paquets use 0.5 % of the bandwidth */ -#define RTCP_TX_RATIO_NUM 5 -#define RTCP_TX_RATIO_DEN 1000 - -typedef enum { - RTCP_SR = 200, - RTCP_RR = 201, - RTCP_SDES = 202, - RTCP_BYE = 203, - RTCP_APP = 204 -} rtcp_type_t; - -typedef enum { - RTCP_SDES_END = 0, - RTCP_SDES_CNAME = 1, - RTCP_SDES_NAME = 2, - RTCP_SDES_EMAIL = 3, - RTCP_SDES_PHONE = 4, - RTCP_SDES_LOC = 5, - RTCP_SDES_TOOL = 6, - RTCP_SDES_NOTE = 7, - RTCP_SDES_PRIV = 8, - RTCP_SDES_IMG = 9, - RTCP_SDES_DOOR = 10, - RTCP_SDES_SOURCE = 11 -} rtcp_sdes_type_t; - -enum RTPPayloadType { - RTP_PT_ULAW = 0, - RTP_PT_GSM = 3, - RTP_PT_G723 = 4, - RTP_PT_ALAW = 8, - RTP_PT_S16BE_STEREO = 10, - RTP_PT_S16BE_MONO = 11, - RTP_PT_MPEGAUDIO = 14, - RTP_PT_JPEG = 26, - RTP_PT_H261 = 31, - RTP_PT_MPEGVIDEO = 32, - RTP_PT_MPEG2TS = 33, - RTP_PT_H263 = 34, /* old H263 encapsulation */ - RTP_PT_PRIVATE = 96, -}; - -typedef struct RTPContext { - int payload_type; - UINT32 ssrc; - UINT16 seq; - UINT32 timestamp; - UINT32 base_timestamp; - UINT32 cur_timestamp; - int max_payload_size; - /* rtcp sender statistics receive */ - INT64 last_rtcp_ntp_time; - UINT32 last_rtcp_timestamp; - /* rtcp sender statistics */ - unsigned int packet_count; - unsigned int octet_count; - unsigned int last_octet_count; - int first_packet; - /* buffer for output */ - UINT8 buf[RTP_MAX_PACKET_LENGTH]; - UINT8 *buf_ptr; -} RTPContext; - -int rtp_get_codec_info(AVCodecContext *codec, int payload_type) -{ - switch(payload_type) { - case RTP_PT_ULAW: - codec->codec_id = CODEC_ID_PCM_MULAW; - codec->channels = 1; - codec->sample_rate = 8000; - break; - case RTP_PT_ALAW: - codec->codec_id = CODEC_ID_PCM_ALAW; - codec->channels = 1; - codec->sample_rate = 8000; - break; - case RTP_PT_S16BE_STEREO: - codec->codec_id = CODEC_ID_PCM_S16BE; - codec->channels = 2; - codec->sample_rate = 44100; - break; - case RTP_PT_S16BE_MONO: - codec->codec_id = CODEC_ID_PCM_S16BE; - codec->channels = 1; - codec->sample_rate = 44100; - break; - case RTP_PT_MPEGAUDIO: - codec->codec_id = CODEC_ID_MP2; - break; - case RTP_PT_JPEG: - codec->codec_id = CODEC_ID_MJPEG; - break; - case RTP_PT_MPEGVIDEO: - codec->codec_id = CODEC_ID_MPEG1VIDEO; - break; - default: - return -1; - } - return 0; -} - -/* return < 0 if unknown payload type */ -int rtp_get_payload_type(AVCodecContext *codec) -{ - int payload_type; - - /* compute the payload type */ - payload_type = -1; - switch(codec->codec_id) { - case CODEC_ID_PCM_MULAW: - payload_type = RTP_PT_ULAW; - break; - case CODEC_ID_PCM_ALAW: - payload_type = RTP_PT_ALAW; - break; - case CODEC_ID_PCM_S16BE: - if (codec->channels == 1) { - payload_type = RTP_PT_S16BE_MONO; - } else if (codec->channels == 2) { - payload_type = RTP_PT_S16BE_STEREO; - } - break; - case CODEC_ID_MP2: - case CODEC_ID_MP3LAME: - payload_type = RTP_PT_MPEGAUDIO; - break; - case CODEC_ID_MJPEG: - payload_type = RTP_PT_JPEG; - break; - case CODEC_ID_MPEG1VIDEO: - payload_type = RTP_PT_MPEGVIDEO; - break; - default: - break; - } - return payload_type; -} - -static inline UINT32 decode_be32(const UINT8 *p) -{ - return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; -} - -static inline UINT32 decode_be64(const UINT8 *p) -{ - return ((UINT64)decode_be32(p) << 32) | decode_be32(p + 4); -} - -static int rtcp_parse_packet(AVFormatContext *s1, const unsigned char *buf, int len) -{ - RTPContext *s = s1->priv_data; - - if (buf[1] != 200) - return -1; - s->last_rtcp_ntp_time = decode_be64(buf + 8); - s->last_rtcp_timestamp = decode_be32(buf + 16); - return 0; -} - -/** - * Parse an RTP packet directly sent as raw data. Can only be used if - * 'raw' is given as input file - * @param s1 media file context - * @param pkt returned packet - * @param buf input buffer - * @param len buffer len - * @return zero if no error. - */ -int rtp_parse_packet(AVFormatContext *s1, AVPacket *pkt, - const unsigned char *buf, int len) -{ - RTPContext *s = s1->priv_data; - unsigned int ssrc, h; - int payload_type, seq, delta_timestamp; - AVStream *st; - UINT32 timestamp; - - if (len < 12) - return -1; - - if ((buf[0] & 0xc0) != (RTP_VERSION << 6)) - return -1; - if (buf[1] >= 200 && buf[1] <= 204) { - rtcp_parse_packet(s1, buf, len); - return -1; - } - payload_type = buf[1] & 0x7f; - seq = (buf[2] << 8) | buf[3]; - timestamp = decode_be32(buf + 4); - ssrc = decode_be32(buf + 8); - - if (s->payload_type < 0) { - s->payload_type = payload_type; - - if (payload_type == RTP_PT_MPEG2TS) { - /* XXX: special case : not a single codec but a whole stream */ - return -1; - } else { - st = av_new_stream(s1, 0); - if (!st) - return -1; - rtp_get_codec_info(&st->codec, payload_type); - } - } - - /* NOTE: we can handle only one payload type */ - if (s->payload_type != payload_type) - return -1; -#if defined(DEBUG) || 1 - if (seq != ((s->seq + 1) & 0xffff)) { - printf("RTP: PT=%02x: bad cseq %04x expected=%04x\n", - payload_type, seq, ((s->seq + 1) & 0xffff)); - } - s->seq = seq; -#endif - len -= 12; - buf += 12; - st = s1->streams[0]; - switch(st->codec.codec_id) { - case CODEC_ID_MP2: - /* better than nothing: skip mpeg audio RTP header */ - if (len <= 4) - return -1; - h = decode_be32(buf); - len -= 4; - buf += 4; - av_new_packet(pkt, len); - memcpy(pkt->data, buf, len); - break; - case CODEC_ID_MPEG1VIDEO: - /* better than nothing: skip mpeg audio RTP header */ - if (len <= 4) - return -1; - h = decode_be32(buf); - buf += 4; - len -= 4; - if (h & (1 << 26)) { - /* mpeg2 */ - if (len <= 4) - return -1; - buf += 4; - len -= 4; - } - av_new_packet(pkt, len); - memcpy(pkt->data, buf, len); - break; - default: - av_new_packet(pkt, len); - memcpy(pkt->data, buf, len); - break; - } - - if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE) { - /* compute pts from timestamp with received ntp_time */ - delta_timestamp = timestamp - s->last_rtcp_timestamp; - /* XXX: do conversion, but not needed for mpeg at 90 KhZ */ - pkt->pts = s->last_rtcp_ntp_time + delta_timestamp; - } - return 0; -} - -static int rtp_read_header(AVFormatContext *s1, - AVFormatParameters *ap) -{ - RTPContext *s = s1->priv_data; - s->payload_type = -1; - s->last_rtcp_ntp_time = AV_NOPTS_VALUE; - return 0; -} - -static int rtp_read_packet(AVFormatContext *s1, AVPacket *pkt) -{ - char buf[RTP_MAX_PACKET_LENGTH]; - int ret; - - /* XXX: needs a better API for packet handling ? */ - for(;;) { - ret = url_read(url_fileno(&s1->pb), buf, sizeof(buf)); - if (ret < 0) - return AVERROR_IO; - if (rtp_parse_packet(s1, pkt, buf, ret) == 0) - break; - } - return 0; -} - -static int rtp_read_close(AVFormatContext *s1) -{ - // RTPContext *s = s1->priv_data; - return 0; -} - -static int rtp_probe(AVProbeData *p) -{ - if (strstart(p->filename, "rtp://", NULL)) - return AVPROBE_SCORE_MAX; - return 0; -} - -/* rtp output */ - -static int rtp_write_header(AVFormatContext *s1) -{ - RTPContext *s = s1->priv_data; - int payload_type, max_packet_size; - AVStream *st; - - if (s1->nb_streams != 1) - return -1; - st = s1->streams[0]; - - payload_type = rtp_get_payload_type(&st->codec); - if (payload_type < 0) - payload_type = RTP_PT_PRIVATE; /* private payload type */ - s->payload_type = payload_type; - - s->base_timestamp = random(); - s->timestamp = s->base_timestamp; - s->ssrc = random(); - s->first_packet = 1; - - max_packet_size = url_fget_max_packet_size(&s1->pb); - if (max_packet_size <= 12) - return AVERROR_IO; - s->max_payload_size = max_packet_size - 12; - - switch(st->codec.codec_id) { - case CODEC_ID_MP2: - case CODEC_ID_MP3LAME: - s->buf_ptr = s->buf + 4; - s->cur_timestamp = 0; - break; - case CODEC_ID_MPEG1VIDEO: - s->cur_timestamp = 0; - break; - default: - s->buf_ptr = s->buf; - break; - } - - return 0; -} - -/* send an rtcp sender report packet */ -static void rtcp_send_sr(AVFormatContext *s1, INT64 ntp_time) -{ - RTPContext *s = s1->priv_data; -#if defined(DEBUG) - printf("RTCP: %02x %Lx %x\n", s->payload_type, ntp_time, s->timestamp); -#endif - put_byte(&s1->pb, (RTP_VERSION << 6)); - put_byte(&s1->pb, 200); - put_be16(&s1->pb, 6); /* length in words - 1 */ - put_be32(&s1->pb, s->ssrc); - put_be64(&s1->pb, ntp_time); - put_be32(&s1->pb, s->timestamp); - put_be32(&s1->pb, s->packet_count); - put_be32(&s1->pb, s->octet_count); - put_flush_packet(&s1->pb); -} - -/* send an rtp packet. sequence number is incremented, but the caller - must update the timestamp itself */ -static void rtp_send_data(AVFormatContext *s1, UINT8 *buf1, int len) -{ - RTPContext *s = s1->priv_data; - -#ifdef DEBUG - printf("rtp_send_data size=%d\n", len); -#endif - - /* build the RTP header */ - put_byte(&s1->pb, (RTP_VERSION << 6)); - put_byte(&s1->pb, s->payload_type & 0x7f); - put_be16(&s1->pb, s->seq); - put_be32(&s1->pb, s->timestamp); - put_be32(&s1->pb, s->ssrc); - - put_buffer(&s1->pb, buf1, len); - put_flush_packet(&s1->pb); - - s->seq++; - s->octet_count += len; - s->packet_count++; -} - -/* send an integer number of samples and compute time stamp and fill - the rtp send buffer before sending. */ -static void rtp_send_samples(AVFormatContext *s1, - UINT8 *buf1, int size, int sample_size) -{ - RTPContext *s = s1->priv_data; - int len, max_packet_size, n; - - max_packet_size = (s->max_payload_size / sample_size) * sample_size; - /* not needed, but who nows */ - if ((size % sample_size) != 0) - av_abort(); - while (size > 0) { - len = (max_packet_size - (s->buf_ptr - s->buf)); - if (len > size) - len = size; - - /* copy data */ - memcpy(s->buf_ptr, buf1, len); - s->buf_ptr += len; - buf1 += len; - size -= len; - n = (s->buf_ptr - s->buf); - /* if buffer full, then send it */ - if (n >= max_packet_size) { - rtp_send_data(s1, s->buf, n); - s->buf_ptr = s->buf; - /* update timestamp */ - s->timestamp += n / sample_size; - } - } -} - -/* NOTE: we suppose that exactly one frame is given as argument here */ -/* XXX: test it */ -static void rtp_send_mpegaudio(AVFormatContext *s1, - UINT8 *buf1, int size) -{ - RTPContext *s = s1->priv_data; - AVStream *st = s1->streams[0]; - int len, count, max_packet_size; - - max_packet_size = s->max_payload_size; - - /* test if we must flush because not enough space */ - len = (s->buf_ptr - s->buf); - if ((len + size) > max_packet_size) { - if (len > 4) { - rtp_send_data(s1, s->buf, s->buf_ptr - s->buf); - s->buf_ptr = s->buf + 4; - /* 90 KHz time stamp */ - s->timestamp = s->base_timestamp + - (s->cur_timestamp * 90000LL) / st->codec.sample_rate; - } - } - - /* add the packet */ - if (size > max_packet_size) { - /* big packet: fragment */ - count = 0; - while (size > 0) { - len = max_packet_size - 4; - if (len > size) - len = size; - /* build fragmented packet */ - s->buf[0] = 0; - s->buf[1] = 0; - s->buf[2] = count >> 8; - s->buf[3] = count; - memcpy(s->buf + 4, buf1, len); - rtp_send_data(s1, s->buf, len + 4); - size -= len; - buf1 += len; - count += len; - } - } else { - if (s->buf_ptr == s->buf + 4) { - /* no fragmentation possible */ - s->buf[0] = 0; - s->buf[1] = 0; - s->buf[2] = 0; - s->buf[3] = 0; - } - memcpy(s->buf_ptr, buf1, size); - s->buf_ptr += size; - } - s->cur_timestamp += st->codec.frame_size; -} - -/* NOTE: a single frame must be passed with sequence header if - needed. XXX: use slices. */ -static void rtp_send_mpegvideo(AVFormatContext *s1, - UINT8 *buf1, int size) -{ - RTPContext *s = s1->priv_data; - AVStream *st = s1->streams[0]; - int len, h, max_packet_size; - UINT8 *q; - - max_packet_size = s->max_payload_size; - - while (size > 0) { - /* XXX: more correct headers */ - h = 0; - if (st->codec.sub_id == 2) - h |= 1 << 26; /* mpeg 2 indicator */ - q = s->buf; - *q++ = h >> 24; - *q++ = h >> 16; - *q++ = h >> 8; - *q++ = h; - - if (st->codec.sub_id == 2) { - h = 0; - *q++ = h >> 24; - *q++ = h >> 16; - *q++ = h >> 8; - *q++ = h; - } - - len = max_packet_size - (q - s->buf); - if (len > size) - len = size; - - memcpy(q, buf1, len); - q += len; - - /* 90 KHz time stamp */ - /* XXX: overflow */ - s->timestamp = s->base_timestamp + - (s->cur_timestamp * 90000LL * FRAME_RATE_BASE) / st->codec.frame_rate; - rtp_send_data(s1, s->buf, q - s->buf); - - buf1 += len; - size -= len; - } - s->cur_timestamp++; -} - -static void rtp_send_raw(AVFormatContext *s1, - UINT8 *buf1, int size) -{ - RTPContext *s = s1->priv_data; - AVStream *st = s1->streams[0]; - int len, max_packet_size; - - max_packet_size = s->max_payload_size; - - while (size > 0) { - len = max_packet_size; - if (len > size) - len = size; - - /* 90 KHz time stamp */ - /* XXX: overflow */ - s->timestamp = s->base_timestamp + - (s->cur_timestamp * 90000LL * FRAME_RATE_BASE) / st->codec.frame_rate; - rtp_send_data(s1, buf1, len); - - buf1 += len; - size -= len; - } - s->cur_timestamp++; -} - -/* write an RTP packet. 'buf1' must contain a single specific frame. */ -static int rtp_write_packet(AVFormatContext *s1, int stream_index, - UINT8 *buf1, int size, int force_pts) -{ - RTPContext *s = s1->priv_data; - AVStream *st = s1->streams[0]; - int rtcp_bytes; - INT64 ntp_time; - -#ifdef DEBUG - printf("%d: write len=%d\n", stream_index, size); -#endif - - /* XXX: mpeg pts hardcoded. RTCP send every 0.5 seconds */ - rtcp_bytes = ((s->octet_count - s->last_octet_count) * RTCP_TX_RATIO_NUM) / - RTCP_TX_RATIO_DEN; - if (s->first_packet || rtcp_bytes >= 28) { - /* compute NTP time */ - ntp_time = force_pts; // ((INT64)force_pts << 28) / 5625 - rtcp_send_sr(s1, ntp_time); - s->last_octet_count = s->octet_count; - s->first_packet = 0; - } - - switch(st->codec.codec_id) { - case CODEC_ID_PCM_MULAW: - case CODEC_ID_PCM_ALAW: - case CODEC_ID_PCM_U8: - case CODEC_ID_PCM_S8: - rtp_send_samples(s1, buf1, size, 1 * st->codec.channels); - break; - case CODEC_ID_PCM_U16BE: - case CODEC_ID_PCM_U16LE: - case CODEC_ID_PCM_S16BE: - case CODEC_ID_PCM_S16LE: - rtp_send_samples(s1, buf1, size, 2 * st->codec.channels); - break; - case CODEC_ID_MP2: - case CODEC_ID_MP3LAME: - rtp_send_mpegaudio(s1, buf1, size); - break; - case CODEC_ID_MPEG1VIDEO: - rtp_send_mpegvideo(s1, buf1, size); - break; - default: - /* better than nothing : send the codec raw data */ - rtp_send_raw(s1, buf1, size); - break; - } - return 0; -} - -static int rtp_write_trailer(AVFormatContext *s1) -{ - // RTPContext *s = s1->priv_data; - return 0; -} - -AVInputFormat rtp_demux = { - "rtp", - "RTP input format", - sizeof(RTPContext), - rtp_probe, - rtp_read_header, - rtp_read_packet, - rtp_read_close, - .flags = AVFMT_NOHEADER, -}; - -AVOutputFormat rtp_mux = { - "rtp", - "RTP output format", - NULL, - NULL, - sizeof(RTPContext), - CODEC_ID_PCM_MULAW, - CODEC_ID_NONE, - rtp_write_header, - rtp_write_packet, - rtp_write_trailer, -}; - -int rtp_init(void) -{ - av_register_output_format(&rtp_mux); - av_register_input_format(&rtp_demux); - return 0; -} diff --git a/libav/rtp.h b/libav/rtp.h deleted file mode 100644 index 0c0ae35ac0..0000000000 --- a/libav/rtp.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * RTP definitions - * Copyright (c) 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#ifndef RTP_H -#define RTP_H - -#define RTP_MIN_PACKET_LENGTH 12 -#define RTP_MAX_PACKET_LENGTH 1500 /* XXX: suppress this define */ - -int rtp_init(void); -int rtp_get_codec_info(AVCodecContext *codec, int payload_type); -int rtp_get_payload_type(AVCodecContext *codec); -int rtp_parse_packet(AVFormatContext *s1, AVPacket *pkt, - const unsigned char *buf, int len); - -extern AVOutputFormat rtp_mux; -extern AVInputFormat rtp_demux; - -int rtp_get_local_port(URLContext *h); -int rtp_set_remote_url(URLContext *h, const char *uri); -void rtp_get_file_handles(URLContext *h, int *prtp_fd, int *prtcp_fd); - -extern URLProtocol rtp_protocol; - -#endif /* RTP_H */ diff --git a/libav/rtpproto.c b/libav/rtpproto.c deleted file mode 100644 index 41823fc829..0000000000 --- a/libav/rtpproto.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * RTP network protocol - * Copyright (c) 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" - -#include <unistd.h> -#include <stdarg.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#ifndef __BEOS__ -# include <arpa/inet.h> -#else -# include "barpainet.h" -#endif -#include <netdb.h> -#include <fcntl.h> - -#define RTP_TX_BUF_SIZE (64 * 1024) -#define RTP_RX_BUF_SIZE (128 * 1024) - -typedef struct RTPContext { - URLContext *rtp_hd, *rtcp_hd; - int rtp_fd, rtcp_fd; -} RTPContext; - -/** - * If no filename is given to av_open_input_file because you want to - * get the local port first, then you must call this function to set - * the remote server address. - * - * @param s1 media file context - * @param uri of the remote server - * @return zero if no error. - */ -int rtp_set_remote_url(URLContext *h, const char *uri) -{ - RTPContext *s = h->priv_data; - char hostname[256]; - int port; - - char buf[1024]; - char path[1024]; - - url_split(NULL, 0, hostname, sizeof(hostname), &port, - path, sizeof(path), uri); - - snprintf(buf, sizeof(buf), "udp://%s:%d%s", hostname, port, path); - udp_set_remote_url(s->rtp_hd, buf); - - snprintf(buf, sizeof(buf), "udp://%s:%d%s", hostname, port + 1, path); - udp_set_remote_url(s->rtcp_hd, buf); - return 0; -} - - -/* add option to url of the form: - "http://host:port/path?option1=val1&option2=val2... */ -void url_add_option(char *buf, int buf_size, const char *fmt, ...) -{ - char buf1[1024]; - va_list ap; - - va_start(ap, fmt); - if (strchr(buf, '?')) - pstrcat(buf, buf_size, "&"); - else - pstrcat(buf, buf_size, "?"); - vsnprintf(buf1, sizeof(buf1), fmt, ap); - pstrcat(buf, buf_size, buf1); - va_end(ap); -} - -void build_udp_url(char *buf, int buf_size, - const char *hostname, int port, - int local_port, int multicast, int ttl) -{ - snprintf(buf, buf_size, "udp://%s:%d", hostname, port); - if (local_port >= 0) - url_add_option(buf, buf_size, "localport=%d", local_port); - if (multicast) - url_add_option(buf, buf_size, "multicast=1", multicast); - if (ttl >= 0) - url_add_option(buf, buf_size, "ttl=%d", ttl); -} - -/* - * url syntax: rtp://host:port[?option=val...] - * option: 'multicast=1' : enable multicast - * 'ttl=n' : set the ttl value (for multicast only) - * 'localport=n' : set the local port to n - * - */ -static int rtp_open(URLContext *h, const char *uri, int flags) -{ - RTPContext *s; - int port, is_output, is_multicast, ttl, local_port; - char hostname[256]; - char buf[1024]; - char path[1024]; - const char *p; - - is_output = (flags & URL_WRONLY); - - s = av_mallocz(sizeof(RTPContext)); - if (!s) - return -ENOMEM; - h->priv_data = s; - - url_split(NULL, 0, hostname, sizeof(hostname), &port, - path, sizeof(path), uri); - /* extract parameters */ - is_multicast = 0; - ttl = -1; - local_port = -1; - p = strchr(uri, '?'); - if (p) { - is_multicast = find_info_tag(buf, sizeof(buf), "multicast", p); - if (find_info_tag(buf, sizeof(buf), "ttl", p)) { - ttl = strtol(buf, NULL, 10); - } - if (find_info_tag(buf, sizeof(buf), "localport", p)) { - local_port = strtol(buf, NULL, 10); - } - } - - build_udp_url(buf, sizeof(buf), - hostname, port, local_port, is_multicast, ttl); - if (url_open(&s->rtp_hd, buf, flags) < 0) - goto fail; - local_port = udp_get_local_port(s->rtp_hd); - /* XXX: need to open another connexion if the port is not even */ - - /* well, should suppress localport in path */ - - build_udp_url(buf, sizeof(buf), - hostname, port + 1, local_port + 1, is_multicast, ttl); - if (url_open(&s->rtcp_hd, buf, flags) < 0) - goto fail; - - /* just to ease handle access. XXX: need to suppress direct handle - access */ - s->rtp_fd = udp_get_file_handle(s->rtp_hd); - s->rtcp_fd = udp_get_file_handle(s->rtcp_hd); - - h->max_packet_size = url_get_max_packet_size(s->rtp_hd); - h->is_streamed = 1; - return 0; - - fail: - if (s->rtp_hd) - url_close(s->rtp_hd); - if (s->rtcp_hd) - url_close(s->rtcp_hd); - av_free(s); - return -EIO; -} - -static int rtp_read(URLContext *h, UINT8 *buf, int size) -{ - RTPContext *s = h->priv_data; - struct sockaddr_in from; - int from_len, len, fd_max, n; - fd_set rfds; -#if 0 - for(;;) { - from_len = sizeof(from); - len = recvfrom (s->rtp_fd, buf, size, 0, - (struct sockaddr *)&from, &from_len); - if (len < 0) { - if (errno == EAGAIN || errno == EINTR) - continue; - return -EIO; - } - break; - } -#else - for(;;) { - /* build fdset to listen to RTP and RTCP packets */ - FD_ZERO(&rfds); - fd_max = s->rtp_fd; - FD_SET(s->rtp_fd, &rfds); - if (s->rtcp_fd > fd_max) - fd_max = s->rtcp_fd; - FD_SET(s->rtcp_fd, &rfds); - n = select(fd_max + 1, &rfds, NULL, NULL, NULL); - if (n > 0) { - /* first try RTCP */ - if (FD_ISSET(s->rtcp_fd, &rfds)) { - from_len = sizeof(from); - len = recvfrom (s->rtcp_fd, buf, size, 0, - (struct sockaddr *)&from, &from_len); - if (len < 0) { - if (errno == EAGAIN || errno == EINTR) - continue; - return -EIO; - } - break; - } - /* then RTP */ - if (FD_ISSET(s->rtp_fd, &rfds)) { - from_len = sizeof(from); - len = recvfrom (s->rtp_fd, buf, size, 0, - (struct sockaddr *)&from, &from_len); - if (len < 0) { - if (errno == EAGAIN || errno == EINTR) - continue; - return -EIO; - } - break; - } - } - } -#endif - return len; -} - -static int rtp_write(URLContext *h, UINT8 *buf, int size) -{ - RTPContext *s = h->priv_data; - int ret; - URLContext *hd; - - if (buf[1] >= 200 && buf[1] <= 204) { - /* RTCP payload type */ - hd = s->rtcp_hd; - } else { - /* RTP payload type */ - hd = s->rtp_hd; - } - - ret = url_write(hd, buf, size); -#if 0 - { - struct timespec ts; - ts.tv_sec = 0; - ts.tv_nsec = 10 * 1000000; - nanosleep(&ts, NULL); - } -#endif - return ret; -} - -static int rtp_close(URLContext *h) -{ - RTPContext *s = h->priv_data; - - url_close(s->rtp_hd); - url_close(s->rtcp_hd); - av_free(s); - return 0; -} - -/** - * Return the local port used by the RTP connexion - * @param s1 media file context - * @return the local port number - */ -int rtp_get_local_port(URLContext *h) -{ - RTPContext *s = h->priv_data; - return udp_get_local_port(s->rtp_hd); -} - -/** - * Return the rtp and rtcp file handles for select() usage to wait for several RTP - * streams at the same time. - * @param h media file context - */ -void rtp_get_file_handles(URLContext *h, int *prtp_fd, int *prtcp_fd) -{ - RTPContext *s = h->priv_data; - - *prtp_fd = s->rtp_fd; - *prtcp_fd = s->rtcp_fd; -} - -URLProtocol rtp_protocol = { - "rtp", - rtp_open, - rtp_read, - rtp_write, - NULL, /* seek */ - rtp_close, -}; diff --git a/libav/rtsp.c b/libav/rtsp.c deleted file mode 100644 index c173cb89b7..0000000000 --- a/libav/rtsp.c +++ /dev/null @@ -1,1163 +0,0 @@ -/* - * RTSP/SDP client - * Copyright (c) 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" - -#include <sys/time.h> -#include <netinet/in.h> -#include <sys/socket.h> -#include <ctype.h> -#ifndef __BEOS__ -# include <arpa/inet.h> -#else -# include "barpainet.h" -#endif - -//#define DEBUG - -typedef struct RTSPState { - URLContext *rtsp_hd; /* RTSP TCP connexion handle */ - ByteIOContext rtsp_gb; - int seq; /* RTSP command sequence number */ - char session_id[512]; - enum RTSPProtocol protocol; - char last_reply[2048]; /* XXX: allocate ? */ -} RTSPState; - -typedef struct RTSPStream { - AVFormatContext *ic; - int interleaved_min, interleaved_max; /* interleave ids, if TCP transport */ - char control_url[1024]; /* url for this stream (from SDP) */ - - int sdp_port; /* port (from SDP content - not used in RTSP) */ - struct in_addr sdp_ip; /* IP address (from SDP content - not used in RTSP) */ - int sdp_ttl; /* IP TTL (from SDP content - not used in RTSP) */ - int sdp_payload_type; /* payload type - only used in SDP */ -} RTSPStream; - -/* suppress this hack */ -int rtsp_abort_req = 0; - -/* XXX: currently, the only way to change the protocols consists in - changing this variable */ -int rtsp_default_protocols = (1 << RTSP_PROTOCOL_RTP_TCP) | (1 << RTSP_PROTOCOL_RTP_UDP) | (1 << RTSP_PROTOCOL_RTP_UDP_MULTICAST); - -/* if non zero, then set a range for RTP ports */ -int rtsp_rtp_port_min = 0; -int rtsp_rtp_port_max = 0; - -FFRTSPCallback *ff_rtsp_callback = NULL; - -static int rtsp_probe(AVProbeData *p) -{ - if (strstart(p->filename, "rtsp:", NULL)) - return AVPROBE_SCORE_MAX; - return 0; -} - -static int redir_isspace(int c) -{ - return (c == ' ' || c == '\t' || c == '\n' || c == '\r'); -} - -static void skip_spaces(const char **pp) -{ - const char *p; - p = *pp; - while (redir_isspace(*p)) - p++; - *pp = p; -} - -static void get_word_sep(char *buf, int buf_size, const char *sep, - const char **pp) -{ - const char *p; - char *q; - - p = *pp; - skip_spaces(&p); - q = buf; - while (!strchr(sep, *p) && *p != '\0') { - if ((q - buf) < buf_size - 1) - *q++ = *p; - p++; - } - if (buf_size > 0) - *q = '\0'; - *pp = p; -} - -static void get_word(char *buf, int buf_size, const char **pp) -{ - const char *p; - char *q; - - p = *pp; - skip_spaces(&p); - q = buf; - while (!redir_isspace(*p) && *p != '\0') { - if ((q - buf) < buf_size - 1) - *q++ = *p; - p++; - } - if (buf_size > 0) - *q = '\0'; - *pp = p; -} - -/* parse the rtpmap description: <codec_name>/<clock_rate>[/<other - params>] */ -static int sdp_parse_rtpmap(AVCodecContext *codec, const char *p) -{ - char buf[256]; - - /* codec name */ - get_word_sep(buf, sizeof(buf), "/", &p); - if (!strcmp(buf, "MP4V-ES")) { - codec->codec_id = CODEC_ID_MPEG4; - return 0; - } else { - return -1; - } -} - -/* return the length and optionnaly the data */ -static int hex_to_data(uint8_t *data, const char *p) -{ - int c, len, v; - - len = 0; - v = 1; - for(;;) { - skip_spaces(&p); - if (p == '\0') - break; - c = toupper((unsigned char)*p++); - if (c >= '0' && c <= '9') - c = c - '0'; - else if (c >= 'A' && c <= 'F') - c = c - 'A' + 10; - else - break; - v = (v << 4) | c; - if (v & 0x100) { - if (data) - data[len] = v; - len++; - v = 1; - } - } - return len; -} - -static void sdp_parse_fmtp(AVCodecContext *codec, const char *p) -{ - char attr[256]; - char value[4096]; - int len; - - /* loop on each attribute */ - for(;;) { - skip_spaces(&p); - if (*p == '\0') - break; - get_word_sep(attr, sizeof(attr), "=", &p); - if (*p == '=') - p++; - get_word_sep(value, sizeof(value), ";", &p); - if (*p == ';') - p++; - /* handle MPEG4 video */ - switch(codec->codec_id) { - case CODEC_ID_MPEG4: - if (!strcmp(attr, "config")) { - /* decode the hexa encoded parameter */ - len = hex_to_data(NULL, value); - codec->extradata = av_mallocz(len); - if (!codec->extradata) - goto fail; - codec->extradata_size = len; - hex_to_data(codec->extradata, value); - } - break; - default: - /* ignore data for other codecs */ - break; - } - fail: ; - // printf("'%s' = '%s'\n", attr, value); - } -} - -typedef struct SDPParseState { - /* SDP only */ - struct in_addr default_ip; - int default_ttl; -} SDPParseState; - -static void sdp_parse_line(AVFormatContext *s, SDPParseState *s1, - int letter, const char *buf) -{ - char buf1[64], st_type[64]; - const char *p; - int codec_type, payload_type, i; - AVStream *st; - RTSPStream *rtsp_st; - struct in_addr sdp_ip; - int ttl; - -#ifdef DEBUG - printf("sdp: %c='%s'\n", letter, buf); -#endif - - p = buf; - switch(letter) { - case 'c': - get_word(buf1, sizeof(buf1), &p); - if (strcmp(buf1, "IN") != 0) - return; - get_word(buf1, sizeof(buf1), &p); - if (strcmp(buf1, "IP4") != 0) - return; - get_word_sep(buf1, sizeof(buf1), "/", &p); - if (inet_aton(buf1, &sdp_ip) == 0) - return; - ttl = 16; - if (*p == '/') { - p++; - get_word_sep(buf1, sizeof(buf1), "/", &p); - ttl = atoi(buf1); - } - if (s->nb_streams == 0) { - s1->default_ip = sdp_ip; - s1->default_ttl = ttl; - } else { - st = s->streams[s->nb_streams - 1]; - rtsp_st = st->priv_data; - rtsp_st->sdp_ip = sdp_ip; - rtsp_st->sdp_ttl = ttl; - } - break; - case 's': - pstrcpy(s->title, sizeof(s->title), p); - break; - case 'i': - if (s->nb_streams == 0) { - pstrcpy(s->comment, sizeof(s->comment), p); - break; - } - break; - case 'm': - /* new stream */ - get_word(st_type, sizeof(st_type), &p); - if (!strcmp(st_type, "audio")) { - codec_type = CODEC_TYPE_AUDIO; - } else if (!strcmp(st_type, "video")) { - codec_type = CODEC_TYPE_VIDEO; - } else { - return; - } - rtsp_st = av_mallocz(sizeof(RTSPStream)); - if (!rtsp_st) - return; - st = av_new_stream(s, s->nb_streams); - if (!st) - return; - st->priv_data = rtsp_st; - - rtsp_st->sdp_ip = s1->default_ip; - rtsp_st->sdp_ttl = s1->default_ttl; - - st->codec.codec_type = codec_type; - - get_word(buf1, sizeof(buf1), &p); /* port */ - rtsp_st->sdp_port = atoi(buf1); - - get_word(buf1, sizeof(buf1), &p); /* protocol (ignored) */ - - /* XXX: handle list of formats */ - get_word(buf1, sizeof(buf1), &p); /* format list */ - rtsp_st->sdp_payload_type = atoi(buf1); - if (rtsp_st->sdp_payload_type < 96) { - /* if standard payload type, we can find the codec right now */ - rtp_get_codec_info(&st->codec, rtsp_st->sdp_payload_type); - } - - /* put a default control url */ - pstrcpy(rtsp_st->control_url, sizeof(rtsp_st->control_url), s->filename); - break; - case 'a': - if (strstart(p, "control:", &p) && s->nb_streams > 0) { - char proto[32]; - /* get the control url */ - st = s->streams[s->nb_streams - 1]; - rtsp_st = st->priv_data; - - /* XXX: may need to add full url resolution */ - url_split(proto, sizeof(proto), NULL, 0, NULL, NULL, 0, p); - if (proto[0] == '\0') { - /* relative control URL */ - pstrcat(rtsp_st->control_url, sizeof(rtsp_st->control_url), "/"); - pstrcat(rtsp_st->control_url, sizeof(rtsp_st->control_url), p); - } else { - pstrcpy(rtsp_st->control_url, sizeof(rtsp_st->control_url), p); - } - } else if (strstart(p, "rtpmap:", &p)) { - /* NOTE: rtpmap is only supported AFTER the 'm=' tag */ - get_word(buf1, sizeof(buf1), &p); - payload_type = atoi(buf1); - for(i = 0; i < s->nb_streams;i++) { - st = s->streams[i]; - rtsp_st = st->priv_data; - if (rtsp_st->sdp_payload_type == payload_type) { - sdp_parse_rtpmap(&st->codec, p); - } - } - } else if (strstart(p, "fmtp:", &p)) { - /* NOTE: fmtp is only supported AFTER the 'a=rtpmap:xxx' tag */ - get_word(buf1, sizeof(buf1), &p); - payload_type = atoi(buf1); - for(i = 0; i < s->nb_streams;i++) { - st = s->streams[i]; - rtsp_st = st->priv_data; - if (rtsp_st->sdp_payload_type == payload_type) { - sdp_parse_fmtp(&st->codec, p); - } - } - } - break; - } -} - -int sdp_parse(AVFormatContext *s, const char *content) -{ - const char *p; - int letter; - char buf[1024], *q; - SDPParseState sdp_parse_state, *s1 = &sdp_parse_state; - - memset(s1, 0, sizeof(SDPParseState)); - p = content; - for(;;) { - skip_spaces(&p); - letter = *p; - if (letter == '\0') - break; - p++; - if (*p != '=') - goto next_line; - p++; - /* get the content */ - q = buf; - while (*p != '\n' && *p != '\0') { - if ((q - buf) < sizeof(buf) - 1) - *q++ = *p; - p++; - } - *q = '\0'; - sdp_parse_line(s, s1, letter, buf); - next_line: - while (*p != '\n' && *p != '\0') - p++; - if (*p == '\n') - p++; - } - return 0; -} - -static void rtsp_parse_range(int *min_ptr, int *max_ptr, const char **pp) -{ - const char *p; - int v; - - p = *pp; - skip_spaces(&p); - v = strtol(p, (char **)&p, 10); - if (*p == '-') { - p++; - *min_ptr = v; - v = strtol(p, (char **)&p, 10); - *max_ptr = v; - } else { - *min_ptr = v; - *max_ptr = v; - } - *pp = p; -} - -/* XXX: only one transport specification is parsed */ -static void rtsp_parse_transport(RTSPHeader *reply, const char *p) -{ - char transport_protocol[16]; - char profile[16]; - char lower_transport[16]; - char parameter[16]; - RTSPTransportField *th; - char buf[256]; - - reply->nb_transports = 0; - - for(;;) { - skip_spaces(&p); - if (*p == '\0') - break; - - th = &reply->transports[reply->nb_transports]; - - get_word_sep(transport_protocol, sizeof(transport_protocol), - "/", &p); - if (*p == '/') - p++; - get_word_sep(profile, sizeof(profile), "/;,", &p); - lower_transport[0] = '\0'; - if (*p == '/') { - get_word_sep(lower_transport, sizeof(lower_transport), - ";,", &p); - } - if (!strcmp(lower_transport, "TCP")) - th->protocol = RTSP_PROTOCOL_RTP_TCP; - else - th->protocol = RTSP_PROTOCOL_RTP_UDP; - - if (*p == ';') - p++; - /* get each parameter */ - while (*p != '\0' && *p != ',') { - get_word_sep(parameter, sizeof(parameter), "=;,", &p); - if (!strcmp(parameter, "port")) { - if (*p == '=') { - p++; - rtsp_parse_range(&th->port_min, &th->port_max, &p); - } - } else if (!strcmp(parameter, "client_port")) { - if (*p == '=') { - p++; - rtsp_parse_range(&th->client_port_min, - &th->client_port_max, &p); - } - } else if (!strcmp(parameter, "server_port")) { - if (*p == '=') { - p++; - rtsp_parse_range(&th->server_port_min, - &th->server_port_max, &p); - } - } else if (!strcmp(parameter, "interleaved")) { - if (*p == '=') { - p++; - rtsp_parse_range(&th->interleaved_min, - &th->interleaved_max, &p); - } - } else if (!strcmp(parameter, "multicast")) { - if (th->protocol == RTSP_PROTOCOL_RTP_UDP) - th->protocol = RTSP_PROTOCOL_RTP_UDP_MULTICAST; - } else if (!strcmp(parameter, "ttl")) { - if (*p == '=') { - p++; - th->ttl = strtol(p, (char **)&p, 10); - } - } else if (!strcmp(parameter, "destination")) { - struct in_addr ipaddr; - - if (*p == '=') { - p++; - get_word_sep(buf, sizeof(buf), ";,", &p); - if (inet_aton(buf, &ipaddr)) - th->destination = ntohl(ipaddr.s_addr); - } - } - while (*p != ';' && *p != '\0' && *p != ',') - p++; - if (*p == ';') - p++; - } - if (*p == ',') - p++; - - reply->nb_transports++; - } -} - -void rtsp_parse_line(RTSPHeader *reply, const char *buf) -{ - const char *p; - - /* NOTE: we do case independent match for broken servers */ - p = buf; - if (stristart(p, "Session:", &p)) { - get_word_sep(reply->session_id, sizeof(reply->session_id), ";", &p); - } else if (stristart(p, "Content-Length:", &p)) { - reply->content_length = strtol(p, NULL, 10); - } else if (stristart(p, "Transport:", &p)) { - rtsp_parse_transport(reply, p); - } else if (stristart(p, "CSeq:", &p)) { - reply->seq = strtol(p, NULL, 10); - } -} - - -static void rtsp_send_cmd(AVFormatContext *s, - const char *cmd, RTSPHeader *reply, - unsigned char **content_ptr) -{ - RTSPState *rt = s->priv_data; - char buf[4096], buf1[1024], *q; - unsigned char ch; - const char *p; - int content_length, line_count; - unsigned char *content = NULL; - - memset(reply, 0, sizeof(RTSPHeader)); - - rt->seq++; - pstrcpy(buf, sizeof(buf), cmd); - snprintf(buf1, sizeof(buf1), "CSeq: %d\n", rt->seq); - pstrcat(buf, sizeof(buf), buf1); - if (rt->session_id[0] != '\0' && !strstr(cmd, "\nIf-Match:")) { - snprintf(buf1, sizeof(buf1), "Session: %s\n", rt->session_id); - pstrcat(buf, sizeof(buf), buf1); - } - pstrcat(buf, sizeof(buf), "\n"); -#ifdef DEBUG - printf("Sending:\n%s--\n", buf); -#endif - url_write(rt->rtsp_hd, buf, strlen(buf)); - - /* parse reply (XXX: use buffers) */ - line_count = 0; - rt->last_reply[0] = '\0'; - for(;;) { - q = buf; - for(;;) { - if (url_read(rt->rtsp_hd, &ch, 1) == 0) - break; - if (ch == '\n') - break; - if (ch != '\r') { - if ((q - buf) < sizeof(buf) - 1) - *q++ = ch; - } - } - *q = '\0'; -#ifdef DEBUG - printf("line='%s'\n", buf); -#endif - /* test if last line */ - if (buf[0] == '\0') - break; - p = buf; - if (line_count == 0) { - /* get reply code */ - get_word(buf1, sizeof(buf1), &p); - get_word(buf1, sizeof(buf1), &p); - reply->status_code = atoi(buf1); - } else { - rtsp_parse_line(reply, p); - pstrcat(rt->last_reply, sizeof(rt->last_reply), p); - pstrcat(rt->last_reply, sizeof(rt->last_reply), "\n"); - } - line_count++; - } - - if (rt->session_id[0] == '\0' && reply->session_id[0] != '\0') - pstrcpy(rt->session_id, sizeof(rt->session_id), reply->session_id); - - content_length = reply->content_length; - if (content_length > 0) { - /* leave some room for a trailing '\0' (useful for simple parsing) */ - content = av_malloc(content_length + 1); - url_read(rt->rtsp_hd, content, content_length); - content[content_length] = '\0'; - } - if (content_ptr) - *content_ptr = content; -} - -/* useful for modules: set RTSP callback function */ - -void rtsp_set_callback(FFRTSPCallback *rtsp_cb) -{ - ff_rtsp_callback = rtsp_cb; -} - - -static int rtsp_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - RTSPState *rt = s->priv_data; - char host[1024], path[1024], tcpname[1024], cmd[2048]; - URLContext *rtsp_hd; - int port, i, ret, err; - RTSPHeader reply1, *reply = &reply1; - unsigned char *content = NULL; - AVStream *st; - RTSPStream *rtsp_st; - int protocol_mask; - - rtsp_abort_req = 0; - - /* extract hostname and port */ - url_split(NULL, 0, - host, sizeof(host), &port, path, sizeof(path), s->filename); - if (port < 0) - port = RTSP_DEFAULT_PORT; - - /* open the tcp connexion */ - snprintf(tcpname, sizeof(tcpname), "tcp://%s:%d", host, port); - if (url_open(&rtsp_hd, tcpname, URL_RDWR) < 0) - return AVERROR_IO; - rt->rtsp_hd = rtsp_hd; - rt->seq = 0; - - /* describe the stream */ - snprintf(cmd, sizeof(cmd), - "DESCRIBE %s RTSP/1.0\n" - "Accept: application/sdp\n", - s->filename); - rtsp_send_cmd(s, cmd, reply, &content); - if (!content) { - err = AVERROR_INVALIDDATA; - goto fail; - } - if (reply->status_code != RTSP_STATUS_OK) { - err = AVERROR_INVALIDDATA; - goto fail; - } - - /* now we got the SDP description, we parse it */ - ret = sdp_parse(s, (const char *)content); - av_freep(&content); - if (ret < 0) { - err = AVERROR_INVALIDDATA; - goto fail; - } - - protocol_mask = rtsp_default_protocols; - - /* for each stream, make the setup request */ - /* XXX: we assume the same server is used for the control of each - RTSP stream */ - for(i=0;i<s->nb_streams;i++) { - char transport[2048]; - AVInputFormat *fmt; - - st = s->streams[i]; - rtsp_st = st->priv_data; - - /* compute available transports */ - transport[0] = '\0'; - - /* RTP/UDP */ - if (protocol_mask & (1 << RTSP_PROTOCOL_RTP_UDP)) { - char buf[256]; - int j; - - /* first try in specified port range */ - if (rtsp_rtp_port_min != 0) { - for(j=rtsp_rtp_port_min;j<=rtsp_rtp_port_max;j++) { - snprintf(buf, sizeof(buf), "rtp://?localport=%d", j); - if (!av_open_input_file(&rtsp_st->ic, buf, - &rtp_demux, 0, NULL)) - goto rtp_opened; - } - } - - /* then try on any port */ - if (av_open_input_file(&rtsp_st->ic, "rtp://", - &rtp_demux, 0, NULL) < 0) { - err = AVERROR_INVALIDDATA; - goto fail; - } - - rtp_opened: - port = rtp_get_local_port(url_fileno(&rtsp_st->ic->pb)); - if (transport[0] != '\0') - pstrcat(transport, sizeof(transport), ","); - snprintf(transport + strlen(transport), sizeof(transport) - strlen(transport) - 1, - "RTP/AVP/UDP;unicast;client_port=%d-%d", - port, port + 1); - } - - /* RTP/TCP */ - if (protocol_mask & (1 << RTSP_PROTOCOL_RTP_TCP)) { - if (transport[0] != '\0') - pstrcat(transport, sizeof(transport), ","); - snprintf(transport + strlen(transport), sizeof(transport) - strlen(transport) - 1, - "RTP/AVP/TCP"); - } - - if (protocol_mask & (1 << RTSP_PROTOCOL_RTP_UDP_MULTICAST)) { - if (transport[0] != '\0') - pstrcat(transport, sizeof(transport), ","); - snprintf(transport + strlen(transport), - sizeof(transport) - strlen(transport) - 1, - "RTP/AVP/UDP;multicast"); - } - - snprintf(cmd, sizeof(cmd), - "SETUP %s RTSP/1.0\n" - "Transport: %s\n", - rtsp_st->control_url, transport); - rtsp_send_cmd(s, cmd, reply, NULL); - if (reply->status_code != RTSP_STATUS_OK || - reply->nb_transports != 1) { - err = AVERROR_INVALIDDATA; - goto fail; - } - - /* XXX: same protocol for all streams is required */ - if (i > 0) { - if (reply->transports[0].protocol != rt->protocol) { - err = AVERROR_INVALIDDATA; - goto fail; - } - } else { - rt->protocol = reply->transports[0].protocol; - } - - /* close RTP connection if not choosen */ - if (reply->transports[0].protocol != RTSP_PROTOCOL_RTP_UDP && - (protocol_mask & (1 << RTSP_PROTOCOL_RTP_UDP))) { - av_close_input_file(rtsp_st->ic); - rtsp_st->ic = NULL; - } - - switch(reply->transports[0].protocol) { - case RTSP_PROTOCOL_RTP_TCP: - fmt = &rtp_demux; - if (av_open_input_file(&rtsp_st->ic, "null", fmt, 0, NULL) < 0) { - err = AVERROR_INVALIDDATA; - goto fail; - } - rtsp_st->interleaved_min = reply->transports[0].interleaved_min; - rtsp_st->interleaved_max = reply->transports[0].interleaved_max; - break; - - case RTSP_PROTOCOL_RTP_UDP: - { - char url[1024]; - - /* XXX: also use address if specified */ - snprintf(url, sizeof(url), "rtp://%s:%d", - host, reply->transports[0].server_port_min); - if (rtp_set_remote_url(url_fileno(&rtsp_st->ic->pb), url) < 0) { - err = AVERROR_INVALIDDATA; - goto fail; - } - } - break; - case RTSP_PROTOCOL_RTP_UDP_MULTICAST: - { - char url[1024]; - int ttl; - - fmt = &rtp_demux; - ttl = reply->transports[0].ttl; - if (!ttl) - ttl = 16; - snprintf(url, sizeof(url), "rtp://%s:%d?multicast=1&ttl=%d", - host, - reply->transports[0].server_port_min, - ttl); - if (av_open_input_file(&rtsp_st->ic, url, fmt, 0, NULL) < 0) { - err = AVERROR_INVALIDDATA; - goto fail; - } - } - break; - } - } - - /* use callback if available to extend setup */ - if (ff_rtsp_callback) { - if (ff_rtsp_callback(RTSP_ACTION_CLIENT_SETUP, rt->session_id, - NULL, 0, rt->last_reply) < 0) { - err = AVERROR_INVALIDDATA; - goto fail; - } - } - - /* start playing */ - snprintf(cmd, sizeof(cmd), - "PLAY %s RTSP/1.0\n", - s->filename); - rtsp_send_cmd(s, cmd, reply, NULL); - if (reply->status_code != RTSP_STATUS_OK) { - err = AVERROR_INVALIDDATA; - goto fail; - } - - /* open TCP with bufferized input */ - if (rt->protocol == RTSP_PROTOCOL_RTP_TCP) { - if (url_fdopen(&rt->rtsp_gb, rt->rtsp_hd) < 0) { - err = AVERROR_NOMEM; - goto fail; - } - } - - return 0; - fail: - for(i=0;i<s->nb_streams;i++) { - st = s->streams[i]; - rtsp_st = st->priv_data; - if (rtsp_st) { - if (rtsp_st->ic) - av_close_input_file(rtsp_st->ic); - } - av_free(rtsp_st); - } - av_freep(&content); - url_close(rt->rtsp_hd); - return err; -} - -static int tcp_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - RTSPState *rt = s->priv_data; - ByteIOContext *rtsp_gb = &rt->rtsp_gb; - int c, id, len, i, ret; - AVStream *st; - RTSPStream *rtsp_st; - char buf[RTP_MAX_PACKET_LENGTH]; - - redo: - for(;;) { - c = url_fgetc(rtsp_gb); - if (c == URL_EOF) - return AVERROR_IO; - if (c == '$') - break; - } - id = get_byte(rtsp_gb); - len = get_be16(rtsp_gb); - if (len > RTP_MAX_PACKET_LENGTH || len < 12) - goto redo; - /* get the data */ - get_buffer(rtsp_gb, buf, len); - - /* find the matching stream */ - for(i = 0; i < s->nb_streams; i++) { - st = s->streams[i]; - rtsp_st = st->priv_data; - if (i >= rtsp_st->interleaved_min && - i <= rtsp_st->interleaved_max) - goto found; - } - goto redo; - found: - ret = rtp_parse_packet(rtsp_st->ic, pkt, buf, len); - if (ret < 0) - goto redo; - pkt->stream_index = i; - return ret; -} - -/* NOTE: output one packet at a time. May need to add a small fifo */ -static int udp_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - AVFormatContext *ic; - AVStream *st; - RTSPStream *rtsp_st; - fd_set rfds; - int fd1, fd2, fd_max, n, i, ret; - char buf[RTP_MAX_PACKET_LENGTH]; - struct timeval tv; - - for(;;) { - if (rtsp_abort_req) - return -EIO; - FD_ZERO(&rfds); - fd_max = -1; - for(i = 0; i < s->nb_streams; i++) { - st = s->streams[i]; - rtsp_st = st->priv_data; - ic = rtsp_st->ic; - /* currently, we cannot probe RTCP handle because of blocking restrictions */ - rtp_get_file_handles(url_fileno(&ic->pb), &fd1, &fd2); - if (fd1 > fd_max) - fd_max = fd1; - FD_SET(fd1, &rfds); - } - /* XXX: also add proper API to abort */ - tv.tv_sec = 0; - tv.tv_usec = 500000; - n = select(fd_max + 1, &rfds, NULL, NULL, &tv); - if (n > 0) { - for(i = 0; i < s->nb_streams; i++) { - st = s->streams[i]; - rtsp_st = st->priv_data; - ic = rtsp_st->ic; - rtp_get_file_handles(url_fileno(&ic->pb), &fd1, &fd2); - if (FD_ISSET(fd1, &rfds)) { - ret = url_read(url_fileno(&ic->pb), buf, sizeof(buf)); - if (ret >= 0 && - rtp_parse_packet(ic, pkt, buf, ret) == 0) { - pkt->stream_index = i; - return ret; - } - } - } - } - } -} - -static int rtsp_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - RTSPState *rt = s->priv_data; - int ret; - - switch(rt->protocol) { - default: - case RTSP_PROTOCOL_RTP_TCP: - ret = tcp_read_packet(s, pkt); - break; - case RTSP_PROTOCOL_RTP_UDP: - ret = udp_read_packet(s, pkt); - break; - } - return ret; -} - -static int rtsp_read_close(AVFormatContext *s) -{ - RTSPState *rt = s->priv_data; - AVStream *st; - RTSPStream *rtsp_st; - RTSPHeader reply1, *reply = &reply1; - int i; - char cmd[1024]; - - /* NOTE: it is valid to flush the buffer here */ - if (rt->protocol == RTSP_PROTOCOL_RTP_TCP) { - url_fclose(&rt->rtsp_gb); - } - - snprintf(cmd, sizeof(cmd), - "TEARDOWN %s RTSP/1.0\n", - s->filename); - rtsp_send_cmd(s, cmd, reply, NULL); - - if (ff_rtsp_callback) { - ff_rtsp_callback(RTSP_ACTION_CLIENT_TEARDOWN, rt->session_id, - NULL, 0, NULL); - } - - for(i=0;i<s->nb_streams;i++) { - st = s->streams[i]; - rtsp_st = st->priv_data; - if (rtsp_st) { - if (rtsp_st->ic) - av_close_input_file(rtsp_st->ic); - } - av_free(rtsp_st); - } - url_close(rt->rtsp_hd); - return 0; -} - -static AVInputFormat rtsp_demux = { - "rtsp", - "RTSP input format", - sizeof(RTSPState), - rtsp_probe, - rtsp_read_header, - rtsp_read_packet, - rtsp_read_close, - .flags = AVFMT_NOFILE, -}; - -static int sdp_probe(AVProbeData *p1) -{ - const char *p; - - /* we look for a line beginning "c=IN IP4" */ - p = p1->buf; - while (*p != '\0') { - if (strstart(p, "c=IN IP4", NULL)) - return AVPROBE_SCORE_MAX / 2; - p = strchr(p, '\n'); - if (!p) - break; - p++; - if (*p == '\r') - p++; - } - return 0; -} - -#define SDP_MAX_SIZE 8192 - -static int sdp_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - AVStream *st; - RTSPStream *rtsp_st; - int size, i, err; - char *content; - char url[1024]; - - /* read the whole sdp file */ - /* XXX: better loading */ - content = av_malloc(SDP_MAX_SIZE); - size = get_buffer(&s->pb, content, SDP_MAX_SIZE - 1); - if (size <= 0) { - av_free(content); - return AVERROR_INVALIDDATA; - } - content[size] ='\0'; - - sdp_parse(s, content); - av_free(content); - - /* open each RTP stream */ - for(i=0;i<s->nb_streams;i++) { - st = s->streams[i]; - rtsp_st = st->priv_data; - - snprintf(url, sizeof(url), "rtp://%s:%d?multicast=1&ttl=%d", - inet_ntoa(rtsp_st->sdp_ip), - rtsp_st->sdp_port, - rtsp_st->sdp_ttl); - if (av_open_input_file(&rtsp_st->ic, url, &rtp_demux, 0, NULL) < 0) { - err = AVERROR_INVALIDDATA; - goto fail; - } - } - return 0; - fail: - for(i=0;i<s->nb_streams;i++) { - st = s->streams[i]; - rtsp_st = st->priv_data; - if (rtsp_st) { - if (rtsp_st->ic) - av_close_input_file(rtsp_st->ic); - } - av_free(rtsp_st); - } - return err; -} - -static int sdp_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - return udp_read_packet(s, pkt); -} - -static int sdp_read_close(AVFormatContext *s) -{ - AVStream *st; - RTSPStream *rtsp_st; - int i; - - for(i=0;i<s->nb_streams;i++) { - st = s->streams[i]; - rtsp_st = st->priv_data; - if (rtsp_st) { - if (rtsp_st->ic) - av_close_input_file(rtsp_st->ic); - } - av_free(rtsp_st); - } - return 0; -} - - -static AVInputFormat sdp_demux = { - "sdp", - "SDP", - sizeof(RTSPState), - sdp_probe, - sdp_read_header, - sdp_read_packet, - sdp_read_close, -}; - - -/* dummy redirector format (used directly in av_open_input_file now) */ -static int redir_probe(AVProbeData *pd) -{ - const char *p; - p = pd->buf; - while (redir_isspace(*p)) - p++; - if (strstart(p, "http://", NULL) || - strstart(p, "rtsp://", NULL)) - return AVPROBE_SCORE_MAX; - return 0; -} - -/* called from utils.c */ -int redir_open(AVFormatContext **ic_ptr, ByteIOContext *f) -{ - char buf[4096], *q; - int c; - AVFormatContext *ic = NULL; - - /* parse each URL and try to open it */ - c = url_fgetc(f); - while (c != URL_EOF) { - /* skip spaces */ - for(;;) { - if (!redir_isspace(c)) - break; - c = url_fgetc(f); - } - if (c == URL_EOF) - break; - /* record url */ - q = buf; - for(;;) { - if (c == URL_EOF || redir_isspace(c)) - break; - if ((q - buf) < sizeof(buf) - 1) - *q++ = c; - c = url_fgetc(f); - } - *q = '\0'; - //printf("URL='%s'\n", buf); - /* try to open the media file */ - if (av_open_input_file(&ic, buf, NULL, 0, NULL) == 0) - break; - } - *ic_ptr = ic; - if (!ic) - return AVERROR_IO; - else - return 0; -} - -AVInputFormat redir_demux = { - "redir", - "Redirector format", - 0, - redir_probe, - NULL, - NULL, - NULL, -}; - -int rtsp_init(void) -{ - av_register_input_format(&rtsp_demux); - av_register_input_format(&redir_demux); - av_register_input_format(&sdp_demux); - return 0; -} diff --git a/libav/rtsp.h b/libav/rtsp.h deleted file mode 100644 index 3dd231571e..0000000000 --- a/libav/rtsp.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * RTSP definitions - * Copyright (c) 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#ifndef RTSP_H -#define RTSP_H - -/* RTSP handling */ -enum RTSPStatusCode { -#define DEF(n, c, s) c = n, -#include "rtspcodes.h" -#undef DEF -}; - -enum RTSPProtocol { - RTSP_PROTOCOL_RTP_UDP = 0, - RTSP_PROTOCOL_RTP_TCP = 1, - RTSP_PROTOCOL_RTP_UDP_MULTICAST = 2, -}; - -#define RTSP_DEFAULT_PORT 554 -#define RTSP_MAX_TRANSPORTS 8 - -typedef struct RTSPTransportField { - int interleaved_min, interleaved_max; /* interleave ids, if TCP transport */ - int port_min, port_max; /* RTP ports */ - int client_port_min, client_port_max; /* RTP ports */ - int server_port_min, server_port_max; /* RTP ports */ - int ttl; /* ttl value */ - UINT32 destination; /* destination IP address */ - enum RTSPProtocol protocol; -} RTSPTransportField; - -typedef struct RTSPHeader { - int content_length; - enum RTSPStatusCode status_code; /* response code from server */ - int nb_transports; - RTSPTransportField transports[RTSP_MAX_TRANSPORTS]; - int seq; /* sequence number */ - char session_id[512]; -} RTSPHeader; - -/* the callback can be used to extend the connection setup/teardown step */ -enum RTSPCallbackAction { - RTSP_ACTION_SERVER_SETUP, - RTSP_ACTION_SERVER_TEARDOWN, - RTSP_ACTION_CLIENT_SETUP, - RTSP_ACTION_CLIENT_TEARDOWN, -}; - -typedef struct RTSPActionServerSetup { - UINT32 ipaddr; - char transport_option[512]; -} RTSPActionServerSetup; - -typedef int FFRTSPCallback(enum RTSPCallbackAction action, - const char *session_id, - char *buf, int buf_size, - void *arg); - -void rtsp_set_callback(FFRTSPCallback *rtsp_cb); - -int rtsp_init(void); -void rtsp_parse_line(RTSPHeader *reply, const char *buf); - -extern int rtsp_abort_req; -extern int rtsp_default_protocols; -extern int rtsp_rtp_port_min; -extern int rtsp_rtp_port_max; -extern FFRTSPCallback *ff_rtsp_callback; - -#endif /* RTSP_H */ diff --git a/libav/rtspcodes.h b/libav/rtspcodes.h deleted file mode 100644 index b967cb932a..0000000000 --- a/libav/rtspcodes.h +++ /dev/null @@ -1,11 +0,0 @@ -DEF(200, RTSP_STATUS_OK, "OK") -DEF(405, RTSP_STATUS_METHOD, "Method Not Allowed") -DEF(453, RTSP_STATUS_BANDWIDTH, "Not Enough Bandwidth") -DEF(454, RTSP_STATUS_SESSION, "Session Not Found") -DEF(455, RTSP_STATUS_STATE, "Method Not Valid in This State") -DEF(459, RTSP_STATUS_AGGREGATE, "Aggregate operation not allowed") -DEF(460, RTSP_STATUS_ONLY_AGGREGATE, "Only aggregate operation allowed") -DEF(461, RTSP_STATUS_TRANSPORT, "Unsupported transport") -DEF(500, RTSP_STATUS_INTERNAL, "Internal Server Error") -DEF(503, RTSP_STATUS_SERVICE, "Service Unavailable") -DEF(505, RTSP_STATUS_VERSION, "RTSP Version not supported") diff --git a/libav/strptime.c b/libav/strptime.c deleted file mode 100644 index 7aece6a08e..0000000000 --- a/libav/strptime.c +++ /dev/null @@ -1,1004 +0,0 @@ -/* Convert a string representation of time to a time value. - Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The GNU C Library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* XXX This version of the implementation is not really complete. - Some of the fields cannot add information alone. But if seeing - some of them in the same format (such as year, week and weekday) - this is enough information for determining the date. */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include <ctype.h> -#include <limits.h> -#include <string.h> -#include <time.h> - -#ifdef _LIBC -# include "../locale/localeinfo.h" -#endif - -#include "strptime.h" - -#ifndef __P -# if defined (__GNUC__) || (defined (__STDC__) && __STDC__) -# define __P(args) args -# else -# define __P(args) () -# endif /* GCC. */ -#endif /* Not __P. */ - -#if ! HAVE_LOCALTIME_R && ! defined localtime_r -# ifdef _LIBC -# define localtime_r __localtime_r -# else -/* Approximate localtime_r as best we can in its absence. */ -# define localtime_r my_localtime_r -static struct tm *localtime_r __P ((const time_t *, struct tm *)); -static struct tm * -localtime_r (t, tp) - const time_t *t; - struct tm *tp; -{ - struct tm *l = localtime (t); - if (! l) - return 0; - *tp = *l; - return tp; -} -# endif /* ! _LIBC */ -#endif /* ! HAVE_LOCALTIME_R && ! defined (localtime_r) */ - - -#define match_char(ch1, ch2) if (ch1 != ch2) return NULL -#if defined __GNUC__ && __GNUC__ >= 2 -# define match_string(cs1, s2) \ - ({ size_t len = strlen (cs1); \ - int result = strncasecmp ((cs1), (s2), len) == 0; \ - if (result) (s2) += len; \ - result; }) -#else -/* Oh come on. Get a reasonable compiler. */ -# define match_string(cs1, s2) \ - (strncasecmp ((cs1), (s2), strlen (cs1)) ? 0 : ((s2) += strlen (cs1), 1)) -#endif -/* We intentionally do not use isdigit() for testing because this will - lead to problems with the wide character version. */ -#define get_number(from, to, n) \ - do { \ - int __n = n; \ - val = 0; \ - while (*rp == ' ') \ - ++rp; \ - if (*rp < '0' || *rp > '9') \ - return NULL; \ - do { \ - val *= 10; \ - val += *rp++ - '0'; \ - } while (--__n > 0 && val * 10 <= to && *rp >= '0' && *rp <= '9'); \ - if (val < from || val > to) \ - return NULL; \ - } while (0) -#ifdef _NL_CURRENT -# define get_alt_number(from, to, n) \ - ({ \ - __label__ do_normal; \ - if (*decided != raw) \ - { \ - const char *alts = _NL_CURRENT (LC_TIME, ALT_DIGITS); \ - int __n = n; \ - int any = 0; \ - while (*rp == ' ') \ - ++rp; \ - val = 0; \ - do { \ - val *= 10; \ - while (*alts != '\0') \ - { \ - size_t len = strlen (alts); \ - if (strncasecmp (alts, rp, len) == 0) \ - break; \ - alts += len + 1; \ - ++val; \ - } \ - if (*alts == '\0') \ - { \ - if (*decided == not && ! any) \ - goto do_normal; \ - /* If we haven't read anything it's an error. */ \ - if (! any) \ - return NULL; \ - /* Correct the premature multiplication. */ \ - val /= 10; \ - break; \ - } \ - else \ - *decided = loc; \ - } while (--__n > 0 && val * 10 <= to); \ - if (val < from || val > to) \ - return NULL; \ - } \ - else \ - { \ - do_normal: \ - get_number (from, to, n); \ - } \ - 0; \ - }) -#else -# define get_alt_number(from, to, n) \ - /* We don't have the alternate representation. */ \ - get_number(from, to, n) -#endif -#define recursive(new_fmt) \ - (*(new_fmt) != '\0' \ - && (rp = strptime_internal (rp, (new_fmt), tm, decided, era_cnt)) != NULL) - - -#ifdef _LIBC -/* This is defined in locale/C-time.c in the GNU libc. */ -extern const struct locale_data _nl_C_LC_TIME; -extern const unsigned short int __mon_yday[2][13]; - -# define weekday_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (DAY_1)].string) -# define ab_weekday_name \ - (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABDAY_1)].string) -# define month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (MON_1)].string) -# define ab_month_name (&_nl_C_LC_TIME.values[_NL_ITEM_INDEX (ABMON_1)].string) -# define HERE_D_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_T_FMT)].string) -# define HERE_D_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (D_FMT)].string) -# define HERE_AM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (AM_STR)].string) -# define HERE_PM_STR (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (PM_STR)].string) -# define HERE_T_FMT_AMPM \ - (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT_AMPM)].string) -# define HERE_T_FMT (_nl_C_LC_TIME.values[_NL_ITEM_INDEX (T_FMT)].string) - -# define strncasecmp(s1, s2, n) __strncasecmp (s1, s2, n) -#else -static char const weekday_name[][10] = - { - "Sunday", "Monday", "Tuesday", "Wednesday", - "Thursday", "Friday", "Saturday" - }; -static char const ab_weekday_name[][4] = - { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" - }; -static char const month_name[][10] = - { - "January", "February", "March", "April", "May", "June", - "July", "August", "September", "October", "November", "December" - }; -static char const ab_month_name[][4] = - { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" - }; -# define HERE_D_T_FMT "%a %b %e %H:%M:%S %Y" -# define HERE_D_FMT "%m/%d/%y" -# define HERE_AM_STR "AM" -# define HERE_PM_STR "PM" -# define HERE_T_FMT_AMPM "%I:%M:%S %p" -# define HERE_T_FMT "%H:%M:%S" - -const unsigned short int __mon_yday[2][13] = - { - /* Normal years. */ - { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, - /* Leap years. */ - { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } - }; -#endif - -/* Status of lookup: do we use the locale data or the raw data? */ -enum locale_status { not, loc, raw }; - - -#ifndef __isleap -/* Nonzero if YEAR is a leap year (every 4 years, - except every 100th isn't, and every 400th is). */ -# define __isleap(year) \ - ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) -#endif - -/* Compute the day of the week. */ -static void -day_of_the_week (struct tm *tm) -{ - /* We know that January 1st 1970 was a Thursday (= 4). Compute the - the difference between this data in the one on TM and so determine - the weekday. */ - int corr_year = 1900 + tm->tm_year - (tm->tm_mon < 2); - int wday = (-473 - + (365 * (tm->tm_year - 70)) - + (corr_year / 4) - - ((corr_year / 4) / 25) + ((corr_year / 4) % 25 < 0) - + (((corr_year / 4) / 25) / 4) - + __mon_yday[0][tm->tm_mon] - + tm->tm_mday - 1); - tm->tm_wday = ((wday % 7) + 7) % 7; -} - -/* Compute the day of the year. */ -static void -day_of_the_year (struct tm *tm) -{ - tm->tm_yday = (__mon_yday[__isleap (1900 + tm->tm_year)][tm->tm_mon] - + (tm->tm_mday - 1)); -} - -static char * -#ifdef _LIBC -internal_function -#endif -strptime_internal __P ((const char *rp, const char *fmt, struct tm *tm, - enum locale_status *decided, int era_cnt)); - -static char * -#ifdef _LIBC -internal_function -#endif -strptime_internal (rp, fmt, tm, decided, era_cnt) - const char *rp; - const char *fmt; - struct tm *tm; - enum locale_status *decided; - int era_cnt; -{ - const char *rp_backup; - int cnt; - size_t val; - int have_I, is_pm; - int century, want_century; - int want_era; - int have_wday, want_xday; - int have_yday; - int have_mon, have_mday; -#ifdef _NL_CURRENT - size_t num_eras; -#endif - struct era_entry *era; - - have_I = is_pm = 0; - century = -1; - want_century = 0; - want_era = 0; - era = NULL; - - have_wday = want_xday = have_yday = have_mon = have_mday = 0; - - while (*fmt != '\0') - { - /* A white space in the format string matches 0 more or white - space in the input string. */ - if (isspace (*fmt)) - { - while (isspace (*rp)) - ++rp; - ++fmt; - continue; - } - - /* Any character but `%' must be matched by the same character - in the iput string. */ - if (*fmt != '%') - { - match_char (*fmt++, *rp++); - continue; - } - - ++fmt; -#ifndef _NL_CURRENT - /* We need this for handling the `E' modifier. */ - start_over: -#endif - - /* Make back up of current processing pointer. */ - rp_backup = rp; - - switch (*fmt++) - { - case '%': - /* Match the `%' character itself. */ - match_char ('%', *rp++); - break; - case 'a': - case 'A': - /* Match day of week. */ - for (cnt = 0; cnt < 7; ++cnt) - { -#ifdef _NL_CURRENT - if (*decided !=raw) - { - if (match_string (_NL_CURRENT (LC_TIME, DAY_1 + cnt), rp)) - { - if (*decided == not - && strcmp (_NL_CURRENT (LC_TIME, DAY_1 + cnt), - weekday_name[cnt])) - *decided = loc; - break; - } - if (match_string (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), rp)) - { - if (*decided == not - && strcmp (_NL_CURRENT (LC_TIME, ABDAY_1 + cnt), - ab_weekday_name[cnt])) - *decided = loc; - break; - } - } -#endif - if (*decided != loc - && (match_string (weekday_name[cnt], rp) - || match_string (ab_weekday_name[cnt], rp))) - { - *decided = raw; - break; - } - } - if (cnt == 7) - /* Does not match a weekday name. */ - return NULL; - tm->tm_wday = cnt; - have_wday = 1; - break; - case 'b': - case 'B': - case 'h': - /* Match month name. */ - for (cnt = 0; cnt < 12; ++cnt) - { -#ifdef _NL_CURRENT - if (*decided !=raw) - { - if (match_string (_NL_CURRENT (LC_TIME, MON_1 + cnt), rp)) - { - if (*decided == not - && strcmp (_NL_CURRENT (LC_TIME, MON_1 + cnt), - month_name[cnt])) - *decided = loc; - break; - } - if (match_string (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), rp)) - { - if (*decided == not - && strcmp (_NL_CURRENT (LC_TIME, ABMON_1 + cnt), - ab_month_name[cnt])) - *decided = loc; - break; - } - } -#endif - if (match_string (month_name[cnt], rp) - || match_string (ab_month_name[cnt], rp)) - { - *decided = raw; - break; - } - } - if (cnt == 12) - /* Does not match a month name. */ - return NULL; - tm->tm_mon = cnt; - want_xday = 1; - break; - case 'c': - /* Match locale's date and time format. */ -#ifdef _NL_CURRENT - if (*decided != raw) - { - if (!recursive (_NL_CURRENT (LC_TIME, D_T_FMT))) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (*decided == not && - strcmp (_NL_CURRENT (LC_TIME, D_T_FMT), HERE_D_T_FMT)) - *decided = loc; - want_xday = 1; - break; - } - *decided = raw; - } -#endif - if (!recursive (HERE_D_T_FMT)) - return NULL; - want_xday = 1; - break; - case 'C': - /* Match century number. */ -#ifdef _NL_CURRENT - match_century: -#endif - get_number (0, 99, 2); - century = val; - want_xday = 1; - break; - case 'd': - case 'e': - /* Match day of month. */ - get_number (1, 31, 2); - tm->tm_mday = val; - have_mday = 1; - want_xday = 1; - break; - case 'F': - if (!recursive ("%Y-%m-%d")) - return NULL; - want_xday = 1; - break; - case 'x': -#ifdef _NL_CURRENT - if (*decided != raw) - { - if (!recursive (_NL_CURRENT (LC_TIME, D_FMT))) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (*decided == not - && strcmp (_NL_CURRENT (LC_TIME, D_FMT), HERE_D_FMT)) - *decided = loc; - want_xday = 1; - break; - } - *decided = raw; - } -#endif - /* Fall through. */ - case 'D': - /* Match standard day format. */ - if (!recursive (HERE_D_FMT)) - return NULL; - want_xday = 1; - break; - case 'k': - case 'H': - /* Match hour in 24-hour clock. */ - get_number (0, 23, 2); - tm->tm_hour = val; - have_I = 0; - break; - case 'I': - /* Match hour in 12-hour clock. */ - get_number (1, 12, 2); - tm->tm_hour = val % 12; - have_I = 1; - break; - case 'j': - /* Match day number of year. */ - get_number (1, 366, 3); - tm->tm_yday = val - 1; - have_yday = 1; - break; - case 'm': - /* Match number of month. */ - get_number (1, 12, 2); - tm->tm_mon = val - 1; - have_mon = 1; - want_xday = 1; - break; - case 'M': - /* Match minute. */ - get_number (0, 59, 2); - tm->tm_min = val; - break; - case 'n': - case 't': - /* Match any white space. */ - while (isspace (*rp)) - ++rp; - break; - case 'p': - /* Match locale's equivalent of AM/PM. */ -#ifdef _NL_CURRENT - if (*decided != raw) - { - if (match_string (_NL_CURRENT (LC_TIME, AM_STR), rp)) - { - if (strcmp (_NL_CURRENT (LC_TIME, AM_STR), HERE_AM_STR)) - *decided = loc; - break; - } - if (match_string (_NL_CURRENT (LC_TIME, PM_STR), rp)) - { - if (strcmp (_NL_CURRENT (LC_TIME, PM_STR), HERE_PM_STR)) - *decided = loc; - is_pm = 1; - break; - } - *decided = raw; - } -#endif - if (!match_string (HERE_AM_STR, rp)) - if (match_string (HERE_PM_STR, rp)) - is_pm = 1; - else - return NULL; - break; - case 'r': -#ifdef _NL_CURRENT - if (*decided != raw) - { - if (!recursive (_NL_CURRENT (LC_TIME, T_FMT_AMPM))) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (*decided == not && - strcmp (_NL_CURRENT (LC_TIME, T_FMT_AMPM), - HERE_T_FMT_AMPM)) - *decided = loc; - break; - } - *decided = raw; - } -#endif - if (!recursive (HERE_T_FMT_AMPM)) - return NULL; - break; - case 'R': - if (!recursive ("%H:%M")) - return NULL; - break; - case 's': - { - /* The number of seconds may be very high so we cannot use - the `get_number' macro. Instead read the number - character for character and construct the result while - doing this. */ - time_t secs = 0; - if (*rp < '0' || *rp > '9') - /* We need at least one digit. */ - return NULL; - - do - { - secs *= 10; - secs += *rp++ - '0'; - } - while (*rp >= '0' && *rp <= '9'); - - if (localtime_r (&secs, tm) == NULL) - /* Error in function. */ - return NULL; - } - break; - case 'S': - get_number (0, 61, 2); - tm->tm_sec = val; - break; - case 'X': -#ifdef _NL_CURRENT - if (*decided != raw) - { - if (!recursive (_NL_CURRENT (LC_TIME, T_FMT))) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (strcmp (_NL_CURRENT (LC_TIME, T_FMT), HERE_T_FMT)) - *decided = loc; - break; - } - *decided = raw; - } -#endif - /* Fall through. */ - case 'T': - if (!recursive (HERE_T_FMT)) - return NULL; - break; - case 'u': - get_number (1, 7, 1); - tm->tm_wday = val % 7; - have_wday = 1; - break; - case 'g': - get_number (0, 99, 2); - /* XXX This cannot determine any field in TM. */ - break; - case 'G': - if (*rp < '0' || *rp > '9') - return NULL; - /* XXX Ignore the number since we would need some more - information to compute a real date. */ - do - ++rp; - while (*rp >= '0' && *rp <= '9'); - break; - case 'U': - case 'V': - case 'W': - get_number (0, 53, 2); - /* XXX This cannot determine any field in TM without some - information. */ - break; - case 'w': - /* Match number of weekday. */ - get_number (0, 6, 1); - tm->tm_wday = val; - have_wday = 1; - break; - case 'y': -#ifdef _NL_CURRENT - match_year_in_century: -#endif - /* Match year within century. */ - get_number (0, 99, 2); - /* The "Year 2000: The Millennium Rollover" paper suggests that - values in the range 69-99 refer to the twentieth century. */ - tm->tm_year = val >= 69 ? val : val + 100; - /* Indicate that we want to use the century, if specified. */ - want_century = 1; - want_xday = 1; - break; - case 'Y': - /* Match year including century number. */ - get_number (0, 9999, 4); - tm->tm_year = val - 1900; - want_century = 0; - want_xday = 1; - break; - case 'Z': - /* XXX How to handle this? */ - break; - case 'E': -#ifdef _NL_CURRENT - switch (*fmt++) - { - case 'c': - /* Match locale's alternate date and time format. */ - if (*decided != raw) - { - const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT); - - if (*fmt == '\0') - fmt = _NL_CURRENT (LC_TIME, D_T_FMT); - - if (!recursive (fmt)) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (strcmp (fmt, HERE_D_T_FMT)) - *decided = loc; - want_xday = 1; - break; - } - *decided = raw; - } - /* The C locale has no era information, so use the - normal representation. */ - if (!recursive (HERE_D_T_FMT)) - return NULL; - want_xday = 1; - break; - case 'C': - if (*decided != raw) - { - if (era_cnt >= 0) - { - era = _nl_select_era_entry (era_cnt); - if (match_string (era->era_name, rp)) - { - *decided = loc; - break; - } - else - return NULL; - } - else - { - num_eras = _NL_CURRENT_WORD (LC_TIME, - _NL_TIME_ERA_NUM_ENTRIES); - for (era_cnt = 0; era_cnt < (int) num_eras; - ++era_cnt, rp = rp_backup) - { - era = _nl_select_era_entry (era_cnt); - if (match_string (era->era_name, rp)) - { - *decided = loc; - break; - } - } - if (era_cnt == (int) num_eras) - { - era_cnt = -1; - if (*decided == loc) - return NULL; - } - else - break; - } - - *decided = raw; - } - /* The C locale has no era information, so use the - normal representation. */ - goto match_century; - case 'y': - if (*decided == raw) - goto match_year_in_century; - - get_number(0, 9999, 4); - tm->tm_year = val; - want_era = 1; - want_xday = 1; - break; - case 'Y': - if (*decided != raw) - { - num_eras = _NL_CURRENT_WORD (LC_TIME, - _NL_TIME_ERA_NUM_ENTRIES); - for (era_cnt = 0; era_cnt < (int) num_eras; - ++era_cnt, rp = rp_backup) - { - era = _nl_select_era_entry (era_cnt); - if (recursive (era->era_format)) - break; - } - if (era_cnt == (int) num_eras) - { - era_cnt = -1; - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - *decided = loc; - era_cnt = -1; - break; - } - - *decided = raw; - } - get_number (0, 9999, 4); - tm->tm_year = val - 1900; - want_century = 0; - want_xday = 1; - break; - case 'x': - if (*decided != raw) - { - const char *fmt = _NL_CURRENT (LC_TIME, ERA_D_FMT); - - if (*fmt == '\0') - fmt = _NL_CURRENT (LC_TIME, D_FMT); - - if (!recursive (fmt)) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (strcmp (fmt, HERE_D_FMT)) - *decided = loc; - break; - } - *decided = raw; - } - if (!recursive (HERE_D_FMT)) - return NULL; - break; - case 'X': - if (*decided != raw) - { - const char *fmt = _NL_CURRENT (LC_TIME, ERA_T_FMT); - - if (*fmt == '\0') - fmt = _NL_CURRENT (LC_TIME, T_FMT); - - if (!recursive (fmt)) - { - if (*decided == loc) - return NULL; - else - rp = rp_backup; - } - else - { - if (strcmp (fmt, HERE_T_FMT)) - *decided = loc; - break; - } - *decided = raw; - } - if (!recursive (HERE_T_FMT)) - return NULL; - break; - default: - return NULL; - } - break; -#else - /* We have no information about the era format. Just use - the normal format. */ - if (*fmt != 'c' && *fmt != 'C' && *fmt != 'y' && *fmt != 'Y' - && *fmt != 'x' && *fmt != 'X') - /* This is an illegal format. */ - return NULL; - - goto start_over; -#endif - case 'O': - switch (*fmt++) - { - case 'd': - case 'e': - /* Match day of month using alternate numeric symbols. */ - get_alt_number (1, 31, 2); - tm->tm_mday = val; - have_mday = 1; - want_xday = 1; - break; - case 'H': - /* Match hour in 24-hour clock using alternate numeric - symbols. */ - get_alt_number (0, 23, 2); - tm->tm_hour = val; - have_I = 0; - break; - case 'I': - /* Match hour in 12-hour clock using alternate numeric - symbols. */ - get_alt_number (1, 12, 2); - tm->tm_hour = val - 1; - have_I = 1; - break; - case 'm': - /* Match month using alternate numeric symbols. */ - get_alt_number (1, 12, 2); - tm->tm_mon = val - 1; - have_mon = 1; - want_xday = 1; - break; - case 'M': - /* Match minutes using alternate numeric symbols. */ - get_alt_number (0, 59, 2); - tm->tm_min = val; - break; - case 'S': - /* Match seconds using alternate numeric symbols. */ - get_alt_number (0, 61, 2); - tm->tm_sec = val; - break; - case 'U': - case 'V': - case 'W': - get_alt_number (0, 53, 2); - /* XXX This cannot determine any field in TM without - further information. */ - break; - case 'w': - /* Match number of weekday using alternate numeric symbols. */ - get_alt_number (0, 6, 1); - tm->tm_wday = val; - have_wday = 1; - break; - case 'y': - /* Match year within century using alternate numeric symbols. */ - get_alt_number (0, 99, 2); - tm->tm_year = val >= 69 ? val : val + 100; - want_xday = 1; - break; - default: - return NULL; - } - break; - default: - return NULL; - } - } - - if (have_I && is_pm) - tm->tm_hour += 12; - - if (century != -1) - { - if (want_century) - tm->tm_year = tm->tm_year % 100 + (century - 19) * 100; - else - /* Only the century, but not the year. Strange, but so be it. */ - tm->tm_year = (century - 19) * 100; - } - -#ifdef _NL_CURRENT - if (era_cnt != -1) - { - era = _nl_select_era_entry(era_cnt); - if (want_era) - tm->tm_year = (era->start_date[0] - + ((tm->tm_year - era->offset) - * era->absolute_direction)); - else - /* Era start year assumed. */ - tm->tm_year = era->start_date[0]; - } - else -#endif - if (want_era) - return NULL; - - if (want_xday && !have_wday) - { - if ( !(have_mon && have_mday) && have_yday) - { - /* We don't have tm_mon and/or tm_mday, compute them. */ - int t_mon = 0; - while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday) - t_mon++; - if (!have_mon) - tm->tm_mon = t_mon - 1; - if (!have_mday) - tm->tm_mday = - (tm->tm_yday - - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1); - } - day_of_the_week (tm); - } - if (want_xday && !have_yday) - day_of_the_year (tm); - - return (char *) rp; -} - - -char * -strptime (buf, format, tm) - const char *buf; - const char *format; - struct tm *tm; -{ - enum locale_status decided; - -#ifdef _NL_CURRENT - decided = not; -#else - decided = raw; -#endif - return strptime_internal (buf, format, tm, &decided, -1); -} diff --git a/libav/strptime.h b/libav/strptime.h deleted file mode 100644 index a1106fda40..0000000000 --- a/libav/strptime.h +++ /dev/null @@ -1,32 +0,0 @@ -/* strptime.h - * - * $Id$ - * - * Ethereal - Network traffic analyzer - * By Gerald Combs <gerald@ethereal.com> - * Copyright 1998 Gerald Combs - * - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef __STRPTIME_H__ -#define __STRPTIME_H__ - -/* - * Version of "strptime()", for the benefit of OSes that don't have it. - */ -extern char *strptime(const char *, const char *, struct tm *); - -#endif diff --git a/libav/swf.c b/libav/swf.c deleted file mode 100644 index 14f8707f96..0000000000 --- a/libav/swf.c +++ /dev/null @@ -1,571 +0,0 @@ -/* - * Flash Compatible Streaming Format - * Copyright (c) 2000 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" - -/* should have a generic way to indicate probable size */ -#define DUMMY_FILE_SIZE (100 * 1024 * 1024) -#define DUMMY_DURATION 600 /* in seconds */ - -#define TAG_END 0 -#define TAG_SHOWFRAME 1 -#define TAG_DEFINESHAPE 2 -#define TAG_FREECHARACTER 3 -#define TAG_PLACEOBJECT 4 -#define TAG_REMOVEOBJECT 5 -#define TAG_STREAMHEAD 18 -#define TAG_STREAMBLOCK 19 -#define TAG_JPEG2 21 - -#define TAG_LONG 0x100 - -/* flags for shape definition */ -#define FLAG_MOVETO 0x01 -#define FLAG_SETFILL0 0x02 -#define FLAG_SETFILL1 0x04 - -/* character id used */ -#define BITMAP_ID 0 -#define SHAPE_ID 1 - -typedef struct { - offset_t duration_pos; - offset_t tag_pos; - int tag; -} SWFContext; - -static void put_swf_tag(AVFormatContext *s, int tag) -{ - SWFContext *swf = s->priv_data; - ByteIOContext *pb = &s->pb; - - swf->tag_pos = url_ftell(pb); - swf->tag = tag; - /* reserve some room for the tag */ - if (tag & TAG_LONG) { - put_le16(pb, 0); - put_le32(pb, 0); - } else { - put_le16(pb, 0); - } -} - -static void put_swf_end_tag(AVFormatContext *s) -{ - SWFContext *swf = s->priv_data; - ByteIOContext *pb = &s->pb; - offset_t pos; - int tag_len, tag; - - pos = url_ftell(pb); - tag_len = pos - swf->tag_pos - 2; - tag = swf->tag; - url_fseek(pb, swf->tag_pos, SEEK_SET); - if (tag & TAG_LONG) { - tag &= ~TAG_LONG; - put_le16(pb, (tag << 6) | 0x3f); - put_le32(pb, tag_len - 4); - } else { - assert(tag_len < 0x3f); - put_le16(pb, (tag << 6) | tag_len); - } - url_fseek(pb, pos, SEEK_SET); -} - -static inline void max_nbits(int *nbits_ptr, int val) -{ - int n; - - if (val == 0) - return; - val = abs(val); - n = 1; - while (val != 0) { - n++; - val >>= 1; - } - if (n > *nbits_ptr) - *nbits_ptr = n; -} - -static void put_swf_rect(ByteIOContext *pb, - int xmin, int xmax, int ymin, int ymax) -{ - PutBitContext p; - UINT8 buf[256]; - int nbits, mask; - - init_put_bits(&p, buf, sizeof(buf), NULL, NULL); - - nbits = 0; - max_nbits(&nbits, xmin); - max_nbits(&nbits, xmax); - max_nbits(&nbits, ymin); - max_nbits(&nbits, ymax); - mask = (1 << nbits) - 1; - - /* rectangle info */ - put_bits(&p, 5, nbits); - put_bits(&p, nbits, xmin & mask); - put_bits(&p, nbits, xmax & mask); - put_bits(&p, nbits, ymin & mask); - put_bits(&p, nbits, ymax & mask); - - flush_put_bits(&p); - put_buffer(pb, buf, pbBufPtr(&p) - p.buf); -} - -static void put_swf_line_edge(PutBitContext *pb, int dx, int dy) -{ - int nbits, mask; - - put_bits(pb, 1, 1); /* edge */ - put_bits(pb, 1, 1); /* line select */ - nbits = 2; - max_nbits(&nbits, dx); - max_nbits(&nbits, dy); - - mask = (1 << nbits) - 1; - put_bits(pb, 4, nbits - 2); /* 16 bits precision */ - if (dx == 0) { - put_bits(pb, 1, 0); - put_bits(pb, 1, 1); - put_bits(pb, nbits, dy & mask); - } else if (dy == 0) { - put_bits(pb, 1, 0); - put_bits(pb, 1, 0); - put_bits(pb, nbits, dx & mask); - } else { - put_bits(pb, 1, 1); - put_bits(pb, nbits, dx & mask); - put_bits(pb, nbits, dy & mask); - } -} - -#define FRAC_BITS 16 - -/* put matrix (not size optimized */ -static void put_swf_matrix(ByteIOContext *pb, - int a, int b, int c, int d, int tx, int ty) -{ - PutBitContext p; - UINT8 buf[256]; - - init_put_bits(&p, buf, sizeof(buf), NULL, NULL); - - put_bits(&p, 1, 1); /* a, d present */ - put_bits(&p, 5, 20); /* nb bits */ - put_bits(&p, 20, a); - put_bits(&p, 20, d); - - put_bits(&p, 1, 1); /* b, c present */ - put_bits(&p, 5, 20); /* nb bits */ - put_bits(&p, 20, c); - put_bits(&p, 20, b); - - put_bits(&p, 5, 20); /* nb bits */ - put_bits(&p, 20, tx); - put_bits(&p, 20, ty); - - flush_put_bits(&p); - put_buffer(pb, buf, pbBufPtr(&p) - p.buf); -} - -/* XXX: handle audio only */ -static int swf_write_header(AVFormatContext *s) -{ - SWFContext *swf; - ByteIOContext *pb = &s->pb; - AVCodecContext *enc, *audio_enc, *video_enc; - PutBitContext p; - UINT8 buf1[256]; - int i, width, height, rate; - - swf = av_malloc(sizeof(SWFContext)); - if (!swf) - return -1; - s->priv_data = swf; - - video_enc = NULL; - audio_enc = NULL; - for(i=0;i<s->nb_streams;i++) { - enc = &s->streams[i]->codec; - if (enc->codec_type == CODEC_TYPE_AUDIO) - audio_enc = enc; - else - video_enc = enc; - } - - if (!video_enc) { - /* currenty, cannot work correctly if audio only */ - width = 320; - height = 200; - rate = 10 * FRAME_RATE_BASE; - } else { - width = video_enc->width; - height = video_enc->height; - rate = video_enc->frame_rate; - } - - put_tag(pb, "FWS"); - put_byte(pb, 4); /* version (should use 4 for mpeg audio support) */ - put_le32(pb, DUMMY_FILE_SIZE); /* dummy size - (will be patched if not streamed) */ - - put_swf_rect(pb, 0, width, 0, height); - put_le16(pb, (rate * 256) / FRAME_RATE_BASE); /* frame rate */ - swf->duration_pos = url_ftell(pb); - put_le16(pb, (UINT16)(DUMMY_DURATION * (INT64)rate / FRAME_RATE_BASE)); /* frame count */ - - /* define a shape with the jpeg inside */ - - put_swf_tag(s, TAG_DEFINESHAPE); - - put_le16(pb, SHAPE_ID); /* ID of shape */ - /* bounding rectangle */ - put_swf_rect(pb, 0, width, 0, height); - /* style info */ - put_byte(pb, 1); /* one fill style */ - put_byte(pb, 0x41); /* clipped bitmap fill */ - put_le16(pb, BITMAP_ID); /* bitmap ID */ - /* position of the bitmap */ - put_swf_matrix(pb, (int)(1.0 * (1 << FRAC_BITS)), 0, - 0, (int)(1.0 * (1 << FRAC_BITS)), 0, 0); - put_byte(pb, 0); /* no line style */ - - /* shape drawing */ - init_put_bits(&p, buf1, sizeof(buf1), NULL, NULL); - put_bits(&p, 4, 1); /* one fill bit */ - put_bits(&p, 4, 0); /* zero line bit */ - - put_bits(&p, 1, 0); /* not an edge */ - put_bits(&p, 5, FLAG_MOVETO | FLAG_SETFILL0); - put_bits(&p, 5, 1); /* nbits */ - put_bits(&p, 1, 0); /* X */ - put_bits(&p, 1, 0); /* Y */ - put_bits(&p, 1, 1); /* set fill style 1 */ - - /* draw the rectangle ! */ - put_swf_line_edge(&p, width, 0); - put_swf_line_edge(&p, 0, height); - put_swf_line_edge(&p, -width, 0); - put_swf_line_edge(&p, 0, -height); - - /* end of shape */ - put_bits(&p, 1, 0); /* not an edge */ - put_bits(&p, 5, 0); - - flush_put_bits(&p); - put_buffer(pb, buf1, pbBufPtr(&p) - p.buf); - - put_swf_end_tag(s); - - - if (audio_enc) { - int v; - - /* start sound */ - - v = 0; - switch(audio_enc->sample_rate) { - case 11025: - v |= 1 << 2; - break; - case 22050: - v |= 2 << 2; - break; - case 44100: - v |= 3 << 2; - break; - default: - /* not supported */ - av_free(swf); - return -1; - } - if (audio_enc->channels == 2) - v |= 1; - v |= 0x20; /* mp3 compressed */ - v |= 0x02; /* 16 bits */ - - put_swf_tag(s, TAG_STREAMHEAD); - put_byte(&s->pb, 0); - put_byte(&s->pb, v); - put_le16(&s->pb, (audio_enc->sample_rate * FRAME_RATE_BASE) / rate); /* avg samples per frame */ - - - put_swf_end_tag(s); - } - - put_flush_packet(&s->pb); - return 0; -} - -static int swf_write_video(AVFormatContext *s, - AVCodecContext *enc, UINT8 *buf, int size) -{ - ByteIOContext *pb = &s->pb; - static int tag_id = 0; - - if (enc->frame_number > 1) { - /* remove the shape */ - put_swf_tag(s, TAG_REMOVEOBJECT); - put_le16(pb, SHAPE_ID); /* shape ID */ - put_le16(pb, 1); /* depth */ - put_swf_end_tag(s); - - /* free the bitmap */ - put_swf_tag(s, TAG_FREECHARACTER); - put_le16(pb, BITMAP_ID); - put_swf_end_tag(s); - } - - put_swf_tag(s, TAG_JPEG2 | TAG_LONG); - - put_le16(pb, tag_id); /* ID of the image */ - - /* a dummy jpeg header seems to be required */ - put_byte(pb, 0xff); - put_byte(pb, 0xd8); - put_byte(pb, 0xff); - put_byte(pb, 0xd9); - /* write the jpeg image */ - put_buffer(pb, buf, size); - - put_swf_end_tag(s); - - /* draw the shape */ - - put_swf_tag(s, TAG_PLACEOBJECT); - put_le16(pb, SHAPE_ID); /* shape ID */ - put_le16(pb, 1); /* depth */ - put_swf_matrix(pb, 1 << FRAC_BITS, 0, 0, 1 << FRAC_BITS, 0, 0); - put_swf_end_tag(s); - - /* output the frame */ - put_swf_tag(s, TAG_SHOWFRAME); - put_swf_end_tag(s); - - put_flush_packet(&s->pb); - return 0; -} - -static int swf_write_audio(AVFormatContext *s, UINT8 *buf, int size) -{ - ByteIOContext *pb = &s->pb; - - put_swf_tag(s, TAG_STREAMBLOCK | TAG_LONG); - - put_buffer(pb, buf, size); - - put_swf_end_tag(s); - put_flush_packet(&s->pb); - return 0; -} - -static int swf_write_packet(AVFormatContext *s, int stream_index, - UINT8 *buf, int size, int force_pts) -{ - AVCodecContext *codec = &s->streams[stream_index]->codec; - if (codec->codec_type == CODEC_TYPE_AUDIO) - return swf_write_audio(s, buf, size); - else - return swf_write_video(s, codec, buf, size); -} - -static int swf_write_trailer(AVFormatContext *s) -{ - SWFContext *swf = s->priv_data; - ByteIOContext *pb = &s->pb; - AVCodecContext *enc, *video_enc; - int file_size, i; - - video_enc = NULL; - for(i=0;i<s->nb_streams;i++) { - enc = &s->streams[i]->codec; - if (enc->codec_type == CODEC_TYPE_VIDEO) - video_enc = enc; - } - - put_swf_tag(s, TAG_END); - put_swf_end_tag(s); - - put_flush_packet(&s->pb); - - /* patch file size and number of frames if not streamed */ - if (!url_is_streamed(&s->pb) && video_enc) { - file_size = url_ftell(pb); - url_fseek(pb, 4, SEEK_SET); - put_le32(pb, file_size); - url_fseek(pb, swf->duration_pos, SEEK_SET); - put_le16(pb, video_enc->frame_number); - } - return 0; -} - -/***********************************/ -/* just to extract MP3 from swf */ - -static int get_swf_tag(ByteIOContext *pb, int *len_ptr) -{ - int tag, len; - - if (url_feof(pb)) - return -1; - - tag = get_le16(pb); - len = tag & 0x3f; - tag = tag >> 6; - if (len == 0x3f) { - len = get_le32(pb); - } - *len_ptr = len; - return tag; -} - - -static int swf_probe(AVProbeData *p) -{ - /* check file header */ - if (p->buf_size <= 16) - return 0; - if (p->buf[0] == 'F' && p->buf[1] == 'W' && - p->buf[2] == 'S') - return AVPROBE_SCORE_MAX; - else - return 0; -} - -static int swf_read_header(AVFormatContext *s, AVFormatParameters *ap) -{ - ByteIOContext *pb = &s->pb; - int nbits, len, frame_rate, tag, v; - AVStream *st; - - if ((get_be32(pb) & 0xffffff00) != MKBETAG('F', 'W', 'S', 0)) - return -EIO; - get_le32(pb); - /* skip rectangle size */ - nbits = get_byte(pb) >> 3; - len = (4 * nbits - 3 + 7) / 8; - url_fskip(pb, len); - frame_rate = get_le16(pb); - get_le16(pb); /* frame count */ - - for(;;) { - tag = get_swf_tag(pb, &len); - if (tag < 0) { - fprintf(stderr, "No streaming found in SWF\n"); - return -EIO; - } - if (tag == TAG_STREAMHEAD) { - /* streaming found */ - get_byte(pb); - v = get_byte(pb); - get_le16(pb); - /* if mp3 streaming found, OK */ - if ((v & 0x20) != 0) { - st = av_mallocz(sizeof(AVStream)); - if (!st) - return -ENOMEM; - if (v & 0x01) - st->codec.channels = 2; - else - st->codec.channels = 1; - s->nb_streams = 1; - s->streams[0] = st; - - switch((v>> 2) & 0x03) { - case 1: - st->codec.sample_rate = 11025; - break; - case 2: - st->codec.sample_rate = 22050; - break; - case 3: - st->codec.sample_rate = 44100; - break; - default: - av_free(st); - return -EIO; - } - st->codec.codec_type = CODEC_TYPE_AUDIO; - st->codec.codec_id = CODEC_ID_MP2; - break; - } - } else { - url_fskip(pb, len); - } - } - - return 0; -} - -static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - ByteIOContext *pb = &s->pb; - int tag, len; - - for(;;) { - tag = get_swf_tag(pb, &len); - if (tag < 0) - return -EIO; - if (tag == TAG_STREAMBLOCK) { - av_new_packet(pkt, len); - get_buffer(pb, pkt->data, pkt->size); - break; - } else { - url_fskip(pb, len); - } - } - return 0; -} - -static int swf_read_close(AVFormatContext *s) -{ - return 0; -} - -static AVInputFormat swf_iformat = { - "swf", - "Flash format", - 0, - swf_probe, - swf_read_header, - swf_read_packet, - swf_read_close, -}; - -static AVOutputFormat swf_oformat = { - "swf", - "Flash format", - "application/x-shockwave-flash", - "swf", - sizeof(SWFContext), - CODEC_ID_MP2, - CODEC_ID_MJPEG, - swf_write_header, - swf_write_packet, - swf_write_trailer, -}; - -int swf_init(void) -{ - av_register_input_format(&swf_iformat); - av_register_output_format(&swf_oformat); - return 0; -} diff --git a/libav/tcp.c b/libav/tcp.c deleted file mode 100644 index 61d8665525..0000000000 --- a/libav/tcp.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * TCP protocol - * Copyright (c) 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" -#include <unistd.h> -#include <ctype.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#ifndef __BEOS__ -# include <arpa/inet.h> -#else -# include "barpainet.h" -#endif -#include <netdb.h> - -typedef struct TCPContext { - int fd; -} TCPContext; - -/* resolve host with also IP address parsing */ -int resolve_host(struct in_addr *sin_addr, const char *hostname) -{ - struct hostent *hp; - - if ((inet_aton(hostname, sin_addr)) == 0) { - hp = gethostbyname(hostname); - if (!hp) - return -1; - memcpy (sin_addr, hp->h_addr, sizeof(struct in_addr)); - } - return 0; -} - -/* return non zero if error */ -static int tcp_open(URLContext *h, const char *uri, int flags) -{ - struct sockaddr_in dest_addr; - char hostname[1024], *q; - int port, fd = -1; - TCPContext *s; - const char *p; - - s = av_malloc(sizeof(TCPContext)); - if (!s) - return -ENOMEM; - h->priv_data = s; - p = uri; - if (!strstart(p, "tcp://", &p)) - goto fail; - q = hostname; - while (*p != ':' && *p != '/' && *p != '\0') { - if ((q - hostname) < sizeof(hostname) - 1) - *q++ = *p; - p++; - } - *q = '\0'; - if (*p != ':') - goto fail; - p++; - port = strtoul(p, (char **)&p, 10); - if (port <= 0 || port >= 65536) - goto fail; - - dest_addr.sin_family = AF_INET; - dest_addr.sin_port = htons(port); - if (resolve_host(&dest_addr.sin_addr, hostname) < 0) - goto fail; - - fd = socket(PF_INET, SOCK_STREAM, 0); - if (fd < 0) - goto fail; - - if (connect(fd, (struct sockaddr *)&dest_addr, - sizeof(dest_addr)) < 0) - goto fail; - - s->fd = fd; - return 0; - - fail: - if (fd >= 0) - close(fd); - av_free(s); - return -EIO; -} - -static int tcp_read(URLContext *h, UINT8 *buf, int size) -{ - TCPContext *s = h->priv_data; - int size1, len; - - size1 = size; - while (size > 0) { -#ifdef CONFIG_BEOS_NETSERVER - len = recv (s->fd, buf, size, 0); -#else - len = read (s->fd, buf, size); -#endif - if (len < 0) { - if (errno != EINTR && errno != EAGAIN) -#ifdef __BEOS__ - return errno; -#else - return -errno; -#endif - else - continue; - } else if (len == 0) { - break; - } - size -= len; - buf += len; - } - return size1 - size; -} - -static int tcp_write(URLContext *h, UINT8 *buf, int size) -{ - TCPContext *s = h->priv_data; - int ret, size1; - - size1 = size; - while (size > 0) { -#ifdef CONFIG_BEOS_NETSERVER - ret = send (s->fd, buf, size, 0); -#else - ret = write (s->fd, buf, size); -#endif - if (ret < 0 && errno != EINTR && errno != EAGAIN) -#ifdef __BEOS__ - return errno; -#else - return -errno; -#endif - size -= ret; - buf += ret; - } - return size1 - size; -} - -static int tcp_close(URLContext *h) -{ - TCPContext *s = h->priv_data; -#ifdef CONFIG_BEOS_NETSERVER - closesocket(s->fd); -#else - close(s->fd); -#endif - av_free(s); - return 0; -} - -URLProtocol tcp_protocol = { - "tcp", - tcp_open, - tcp_read, - tcp_write, - NULL, /* seek */ - tcp_close, -}; diff --git a/libav/udp.c b/libav/udp.c deleted file mode 100644 index 3d159ef4f8..0000000000 --- a/libav/udp.c +++ /dev/null @@ -1,272 +0,0 @@ -/* - * UDP prototype streaming system - * 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" -#include <unistd.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#ifndef __BEOS__ -# include <arpa/inet.h> -#else -# include "barpainet.h" -#endif -#include <netdb.h> - -typedef struct { - int udp_fd; - int ttl; - int is_multicast; - int local_port; - struct ip_mreq mreq; - struct sockaddr_in dest_addr; -} UDPContext; - -#define UDP_TX_BUF_SIZE 32768 - -/** - * If no filename is given to av_open_input_file because you want to - * get the local port first, then you must call this function to set - * the remote server address. - * - * url syntax: udp://host:port[?option=val...] - * option: 'multicast=1' : enable multicast - * 'ttl=n' : set the ttl value (for multicast only) - * 'localport=n' : set the local port - * - * @param s1 media file context - * @param uri of the remote server - * @return zero if no error. - */ -int udp_set_remote_url(URLContext *h, const char *uri) -{ - UDPContext *s = h->priv_data; - char hostname[256]; - int port; - - url_split(NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri); - - /* set the destination address */ - if (resolve_host(&s->dest_addr.sin_addr, hostname) < 0) - return -EIO; - s->dest_addr.sin_family = AF_INET; - s->dest_addr.sin_port = htons(port); - return 0; -} - -/** - * Return the local port used by the UDP connexion - * @param s1 media file context - * @return the local port number - */ -int udp_get_local_port(URLContext *h) -{ - UDPContext *s = h->priv_data; - return s->local_port; -} - -/** - * Return the udp file handle for select() usage to wait for several RTP - * streams at the same time. - * @param h media file context - */ -int udp_get_file_handle(URLContext *h) -{ - UDPContext *s = h->priv_data; - return s->udp_fd; -} - -/* put it in UDP context */ -/* return non zero if error */ -static int udp_open(URLContext *h, const char *uri, int flags) -{ - struct sockaddr_in my_addr, my_addr1; - char hostname[1024]; - int port, udp_fd = -1, tmp; - UDPContext *s = NULL; - int is_output, len; - const char *p; - char buf[256]; - - h->is_streamed = 1; - - is_output = (flags & URL_WRONLY); - - s = av_malloc(sizeof(UDPContext)); - if (!s) - return -ENOMEM; - - h->priv_data = s; - s->ttl = 16; - s->is_multicast = 0; - p = strchr(uri, '?'); - if (p) { - s->is_multicast = find_info_tag(buf, sizeof(buf), "multicast", p); - if (find_info_tag(buf, sizeof(buf), "ttl", p)) { - s->ttl = strtol(buf, NULL, 10); - } - if (find_info_tag(buf, sizeof(buf), "localport", p)) { - s->local_port = strtol(buf, NULL, 10); - } - } - - /* fill the dest addr */ - url_split(NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri); - - /* XXX: fix url_split */ - if (hostname[0] == '\0' || hostname[0] == '?') { - /* only accepts null hostname if input */ - if (s->is_multicast || (flags & URL_WRONLY)) - goto fail; - } else { - udp_set_remote_url(h, uri); - } - - udp_fd = socket(PF_INET, SOCK_DGRAM, 0); - if (udp_fd < 0) - goto fail; - - my_addr.sin_family = AF_INET; - my_addr.sin_addr.s_addr = htonl (INADDR_ANY); - if (s->is_multicast && !(h->flags & URL_WRONLY)) { - /* special case: the bind must be done on the multicast address port */ - my_addr.sin_port = s->dest_addr.sin_port; - } else { - my_addr.sin_port = htons(s->local_port); - } - - /* the bind is needed to give a port to the socket now */ - if (bind(udp_fd,(struct sockaddr *)&my_addr, sizeof(my_addr)) < 0) - goto fail; - - len = sizeof(my_addr1); - getsockname(udp_fd, (struct sockaddr *)&my_addr1, &len); - s->local_port = ntohs(my_addr1.sin_port); - -#ifndef CONFIG_BEOS_NETSERVER - if (s->is_multicast) { - if (h->flags & URL_WRONLY) { - /* output */ - if (setsockopt(udp_fd, IPPROTO_IP, IP_MULTICAST_TTL, - &s->ttl, sizeof(s->ttl)) < 0) { - perror("IP_MULTICAST_TTL"); - goto fail; - } - } else { - /* input */ - memset(&s->mreq, 0, sizeof(s->mreq)); - s->mreq.imr_multiaddr = s->dest_addr.sin_addr; - s->mreq.imr_interface.s_addr = htonl (INADDR_ANY); - if (setsockopt(udp_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, - &s->mreq, sizeof(s->mreq)) < 0) { - perror("rtp: IP_ADD_MEMBERSHIP"); - goto fail; - } - } - } -#endif - - if (is_output) { - /* limit the tx buf size to limit latency */ - tmp = UDP_TX_BUF_SIZE; - if (setsockopt(udp_fd, SOL_SOCKET, SO_SNDBUF, &tmp, sizeof(tmp)) < 0) { - perror("setsockopt sndbuf"); - goto fail; - } - } - - s->udp_fd = udp_fd; - h->max_packet_size = 1472; /* XXX: probe it ? */ - return 0; - fail: - if (udp_fd >= 0) -#ifdef CONFIG_BEOS_NETSERVER - closesocket(udp_fd); -#else - close(udp_fd); -#endif - av_free(s); - return -EIO; -} - -static int udp_read(URLContext *h, UINT8 *buf, int size) -{ - UDPContext *s = h->priv_data; - struct sockaddr_in from; - int from_len, len; - - for(;;) { - from_len = sizeof(from); - len = recvfrom (s->udp_fd, buf, size, 0, - (struct sockaddr *)&from, &from_len); - if (len < 0) { - if (errno != EAGAIN && errno != EINTR) - return -EIO; - } else { - break; - } - } - return len; -} - -static int udp_write(URLContext *h, UINT8 *buf, int size) -{ - UDPContext *s = h->priv_data; - int ret; - - for(;;) { - ret = sendto (s->udp_fd, buf, size, 0, - (struct sockaddr *) &s->dest_addr, - sizeof (s->dest_addr)); - if (ret < 0) { - if (errno != EINTR && errno != EAGAIN) - return -EIO; - } else { - break; - } - } - return size; -} - -static int udp_close(URLContext *h) -{ - UDPContext *s = h->priv_data; - -#ifndef CONFIG_BEOS_NETSERVER - if (s->is_multicast && !(h->flags & URL_WRONLY)) { - if (setsockopt(s->udp_fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, - &s->mreq, sizeof(s->mreq)) < 0) { - perror("IP_DROP_MEMBERSHIP"); - } - } - close(s->udp_fd); -#else - closesocket(s->udp_fd); -#endif - av_free(s); - return 0; -} - -URLProtocol udp_protocol = { - "udp", - udp_open, - udp_read, - udp_write, - NULL, /* seek */ - udp_close, -}; diff --git a/libav/utils.c b/libav/utils.c deleted file mode 100644 index 5a9aa082f4..0000000000 --- a/libav/utils.c +++ /dev/null @@ -1,1280 +0,0 @@ -/* - * Various utilities for ffmpeg system - * 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" -#include <ctype.h> -#ifndef CONFIG_WIN32 -#include <unistd.h> -#include <fcntl.h> -#include <sys/time.h> -#else -#define strcasecmp _stricmp -#include <sys/types.h> -#include <sys/timeb.h> -#endif -#include <time.h> - -#ifndef HAVE_STRPTIME -#include "strptime.h" -#endif - -AVInputFormat *first_iformat; -AVOutputFormat *first_oformat; - -void av_register_input_format(AVInputFormat *format) -{ - AVInputFormat **p; - p = &first_iformat; - while (*p != NULL) p = &(*p)->next; - *p = format; - format->next = NULL; -} - -void av_register_output_format(AVOutputFormat *format) -{ - AVOutputFormat **p; - p = &first_oformat; - while (*p != NULL) p = &(*p)->next; - *p = format; - format->next = NULL; -} - -int match_ext(const char *filename, const char *extensions) -{ - const char *ext, *p; - char ext1[32], *q; - - ext = strrchr(filename, '.'); - if (ext) { - ext++; - p = extensions; - for(;;) { - q = ext1; - while (*p != '\0' && *p != ',') - *q++ = *p++; - *q = '\0'; - if (!strcasecmp(ext1, ext)) - return 1; - if (*p == '\0') - break; - p++; - } - } - return 0; -} - -AVOutputFormat *guess_format(const char *short_name, const char *filename, - const char *mime_type) -{ - AVOutputFormat *fmt, *fmt_found; - int score_max, score; - - /* find the proper file type */ - fmt_found = NULL; - score_max = 0; - fmt = first_oformat; - while (fmt != NULL) { - score = 0; - if (fmt->name && short_name && !strcmp(fmt->name, short_name)) - score += 100; - if (fmt->mime_type && mime_type && !strcmp(fmt->mime_type, mime_type)) - score += 10; - if (filename && fmt->extensions && - match_ext(filename, fmt->extensions)) { - score += 5; - } - if (score > score_max) { - score_max = score; - fmt_found = fmt; - } - fmt = fmt->next; - } - return fmt_found; -} - -AVOutputFormat *guess_stream_format(const char *short_name, const char *filename, - const char *mime_type) -{ - AVOutputFormat *fmt = guess_format(short_name, filename, mime_type); - - if (fmt) { - AVOutputFormat *stream_fmt; - char stream_format_name[64]; - - snprintf(stream_format_name, sizeof(stream_format_name), "%s_stream", fmt->name); - stream_fmt = guess_format(stream_format_name, NULL, NULL); - - if (stream_fmt) - fmt = stream_fmt; - } - - return fmt; -} - -AVInputFormat *av_find_input_format(const char *short_name) -{ - AVInputFormat *fmt; - for(fmt = first_iformat; fmt != NULL; fmt = fmt->next) { - if (!strcmp(fmt->name, short_name)) - return fmt; - } - return NULL; -} - -/* memory handling */ - -/** - * Allocate the payload of a packet and intialized its fields to default values. - * - * @param pkt packet - * @param size wanted payload size - * @return 0 if OK. AVERROR_xxx otherwise. - */ -int av_new_packet(AVPacket *pkt, int size) -{ - int i; - pkt->data = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!pkt->data) - return AVERROR_NOMEM; - pkt->size = size; - /* sane state */ - pkt->pts = AV_NOPTS_VALUE; - pkt->stream_index = 0; - pkt->flags = 0; - - for(i=0; i<FF_INPUT_BUFFER_PADDING_SIZE; i++) - pkt->data[size+i]= 0; - - return 0; -} - -/** - * Free a packet - * - * @param pkt packet to free - */ -void av_free_packet(AVPacket *pkt) -{ - av_freep(&pkt->data); - /* fail safe */ - pkt->size = 0; -} - -/* fifo handling */ - -int fifo_init(FifoBuffer *f, int size) -{ - f->buffer = av_malloc(size); - if (!f->buffer) - return -1; - f->end = f->buffer + size; - f->wptr = f->rptr = f->buffer; - return 0; -} - -void fifo_free(FifoBuffer *f) -{ - av_free(f->buffer); -} - -int fifo_size(FifoBuffer *f, UINT8 *rptr) -{ - int size; - - if (f->wptr >= rptr) { - size = f->wptr - rptr; - } else { - size = (f->end - rptr) + (f->wptr - f->buffer); - } - return size; -} - -/* get data from the fifo (return -1 if not enough data) */ -int fifo_read(FifoBuffer *f, UINT8 *buf, int buf_size, UINT8 **rptr_ptr) -{ - UINT8 *rptr = *rptr_ptr; - int size, len; - - if (f->wptr >= rptr) { - size = f->wptr - rptr; - } else { - size = (f->end - rptr) + (f->wptr - f->buffer); - } - - if (size < buf_size) - return -1; - while (buf_size > 0) { - len = f->end - rptr; - if (len > buf_size) - len = buf_size; - memcpy(buf, rptr, len); - buf += len; - rptr += len; - if (rptr >= f->end) - rptr = f->buffer; - buf_size -= len; - } - *rptr_ptr = rptr; - return 0; -} - -void fifo_write(FifoBuffer *f, UINT8 *buf, int size, UINT8 **wptr_ptr) -{ - int len; - UINT8 *wptr; - wptr = *wptr_ptr; - while (size > 0) { - len = f->end - wptr; - if (len > size) - len = size; - memcpy(wptr, buf, len); - wptr += len; - if (wptr >= f->end) - wptr = f->buffer; - buf += len; - size -= len; - } - *wptr_ptr = wptr; -} - -int filename_number_test(const char *filename) -{ - char buf[1024]; - return get_frame_filename(buf, sizeof(buf), filename, 1); -} - -/* guess file format */ -AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened) -{ - AVInputFormat *fmt1, *fmt; - int score, score_max; - - fmt = NULL; - score_max = 0; - for(fmt1 = first_iformat; fmt1 != NULL; fmt1 = fmt1->next) { - if (!is_opened && !(fmt1->flags & AVFMT_NOFILE)) - continue; - score = 0; - if (fmt1->read_probe) { - score = fmt1->read_probe(pd); - } else if (fmt1->extensions) { - if (match_ext(pd->filename, fmt1->extensions)) { - score = 50; - } - } - if (score > score_max) { - score_max = score; - fmt = fmt1; - } - } - return fmt; -} - -/************************************************************/ -/* input media file */ - -#define PROBE_BUF_SIZE 2048 - -/** - * Open a media file as input. The codec are not opened. Only the file - * header (if present) is read. - * - * @param ic_ptr the opened media file handle is put here - * @param filename filename to open. - * @param fmt if non NULL, force the file format to use - * @param buf_size optional buffer size (zero if default is OK) - * @param ap additionnal parameters needed when opening the file (NULL if default) - * @return 0 if OK. AVERROR_xxx otherwise. - */ -int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, - AVInputFormat *fmt, - int buf_size, - AVFormatParameters *ap) -{ - AVFormatContext *ic = NULL; - int err; - char buf[PROBE_BUF_SIZE]; - AVProbeData probe_data, *pd = &probe_data; - - ic = av_mallocz(sizeof(AVFormatContext)); - if (!ic) { - err = AVERROR_NOMEM; - goto fail; - } - pstrcpy(ic->filename, sizeof(ic->filename), filename); - pd->filename = ic->filename; - pd->buf = buf; - pd->buf_size = 0; - - if (!fmt) { - /* guess format if no file can be opened */ - fmt = av_probe_input_format(pd, 0); - } - - /* if no file needed do not try to open one */ - if (!fmt || !(fmt->flags & AVFMT_NOFILE)) { - if (url_fopen(&ic->pb, filename, URL_RDONLY) < 0) { - err = AVERROR_IO; - goto fail; - } - if (buf_size > 0) { - url_setbufsize(&ic->pb, buf_size); - } - if (!fmt) { - /* read probe data */ - pd->buf_size = get_buffer(&ic->pb, buf, PROBE_BUF_SIZE); - url_fseek(&ic->pb, 0, SEEK_SET); - } - } - - /* guess file format */ - if (!fmt) { - fmt = av_probe_input_format(pd, 1); - } - - /* if still no format found, error */ - if (!fmt) { - err = AVERROR_NOFMT; - goto fail; - } - - /* XXX: suppress this hack for redirectors */ - if (fmt == &redir_demux) { - err = redir_open(ic_ptr, &ic->pb); - url_fclose(&ic->pb); - av_free(ic); - return err; - } - - ic->iformat = fmt; - - /* allocate private data */ - ic->priv_data = av_mallocz(fmt->priv_data_size); - if (!ic->priv_data) { - err = AVERROR_NOMEM; - goto fail; - } - - /* default pts settings is MPEG like */ - av_set_pts_info(ic, 33, 1, 90000); - - /* check filename in case of an image number is expected */ - if (ic->iformat->flags & AVFMT_NEEDNUMBER) { - if (filename_number_test(ic->filename) < 0) { - err = AVERROR_NUMEXPECTED; - goto fail1; - } - } - - err = ic->iformat->read_header(ic, ap); - if (err < 0) - goto fail1; - *ic_ptr = ic; - return 0; - fail1: - if (!(fmt->flags & AVFMT_NOFILE)) { - url_fclose(&ic->pb); - } - fail: - if (ic) { - av_freep(&ic->priv_data); - } - av_free(ic); - *ic_ptr = NULL; - return err; -} - -/** - * Read a packet from a media file - * @param s media file handle - * @param pkt is filled - * @return 0 if OK. AVERROR_xxx if error. - */ -int av_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - AVPacketList *pktl; - - pktl = s->packet_buffer; - if (pktl) { - /* read packet from packet buffer, if there is data */ - *pkt = pktl->pkt; - s->packet_buffer = pktl->next; - av_free(pktl); - return 0; - } else { - return s->iformat->read_packet(s, pkt); - } -} - -/* state for codec information */ -#define CSTATE_NOTFOUND 0 -#define CSTATE_DECODING 1 -#define CSTATE_FOUND 2 - -static int has_codec_parameters(AVCodecContext *enc) -{ - int val; - switch(enc->codec_type) { - case CODEC_TYPE_AUDIO: - val = enc->sample_rate; - break; - case CODEC_TYPE_VIDEO: - val = enc->width; - break; - default: - val = 1; - break; - } - return (val != 0); -} - -/** - * Read the beginning of a media file to get stream information. This - * is useful for file formats with no headers such as MPEG. This - * function also compute the real frame rate in case of mpeg2 repeat - * frame mode. - * - * @param ic media file handle - * @return >=0 if OK. AVERROR_xxx if error. - */ -int av_find_stream_info(AVFormatContext *ic) -{ - int i, count, ret, got_picture, size, read_size; - AVCodec *codec; - AVStream *st; - AVPacket *pkt; - AVPicture picture; - AVPacketList *pktl=NULL, **ppktl; - short samples[AVCODEC_MAX_AUDIO_FRAME_SIZE / 2]; - UINT8 *ptr; - int min_read_size, max_read_size; - - /* typical mpeg ts rate is 40 Mbits. DVD rate is about 10 - Mbits. We read at most 0.1 second of file to find all streams */ - - /* XXX: base it on stream bitrate when possible */ - if (ic->iformat == &mpegts_demux) { - /* maximum number of bytes we accept to read to find all the streams - in a file */ - min_read_size = 3000000; - } else { - min_read_size = 125000; - } - /* max read size is 2 seconds of video max */ - max_read_size = min_read_size * 20; - - /* set initial codec state */ - for(i=0;i<ic->nb_streams;i++) { - st = ic->streams[i]; - if (has_codec_parameters(&st->codec)) - st->codec_info_state = CSTATE_FOUND; - else - st->codec_info_state = CSTATE_NOTFOUND; - st->codec_info_nb_repeat_frames = 0; - st->codec_info_nb_real_frames = 0; - } - - count = 0; - read_size = 0; - ppktl = &ic->packet_buffer; - for(;;) { - /* check if one codec still needs to be handled */ - for(i=0;i<ic->nb_streams;i++) { - st = ic->streams[i]; - if (st->codec_info_state != CSTATE_FOUND) - break; - } - if (i == ic->nb_streams) { - /* NOTE: if the format has no header, then we need to read - some packets to get most of the streams, so we cannot - stop here */ - if (!(ic->iformat->flags & AVFMT_NOHEADER) || - read_size >= min_read_size) { - /* if we found the info for all the codecs, we can stop */ - ret = count; - break; - } - } else { - /* we did not get all the codec info, but we read too much data */ - if (read_size >= max_read_size) { - ret = count; - break; - } - } - - pktl = av_mallocz(sizeof(AVPacketList)); - if (!pktl) { - ret = AVERROR_NOMEM; - break; - } - - /* add the packet in the buffered packet list */ - *ppktl = pktl; - ppktl = &pktl->next; - - /* NOTE: a new stream can be added there if no header in file - (AVFMT_NOHEADER) */ - pkt = &pktl->pkt; - if (ic->iformat->read_packet(ic, pkt) < 0) { - /* EOF or error */ - ret = -1; /* we could not have all the codec parameters before EOF */ - if ((ic->iformat->flags & AVFMT_NOHEADER) && - i == ic->nb_streams) - ret = 0; - break; - } - read_size += pkt->size; - - /* open new codecs */ - for(i=0;i<ic->nb_streams;i++) { - st = ic->streams[i]; - if (st->codec_info_state == CSTATE_NOTFOUND) { - /* set to found in case of error */ - st->codec_info_state = CSTATE_FOUND; - codec = avcodec_find_decoder(st->codec.codec_id); - if (codec) { - if(codec->capabilities & CODEC_CAP_TRUNCATED) - st->codec.flags |= CODEC_FLAG_TRUNCATED; - - ret = avcodec_open(&st->codec, codec); - if (ret >= 0) - st->codec_info_state = CSTATE_DECODING; - } - } - } - - st = ic->streams[pkt->stream_index]; - if (st->codec_info_state == CSTATE_DECODING) { - /* decode the data and update codec parameters */ - ptr = pkt->data; - size = pkt->size; - while (size > 0) { - switch(st->codec.codec_type) { - case CODEC_TYPE_VIDEO: - ret = avcodec_decode_video(&st->codec, &picture, - &got_picture, ptr, size); - break; - case CODEC_TYPE_AUDIO: - ret = avcodec_decode_audio(&st->codec, samples, - &got_picture, ptr, size); - break; - default: - ret = -1; - break; - } - if (ret < 0) { - /* if error, simply ignore because another packet - may be OK */ - break; - } - if (got_picture) { - /* we got the parameters - now we can stop - examining this stream */ - /* XXX: add a codec info so that we can decide if - the codec can repeat frames */ - if (st->codec.codec_id == CODEC_ID_MPEG1VIDEO && - ic->iformat != &mpegts_demux && - st->codec.sub_id == 2) { - /* for mpeg2 video, we want to know the real - frame rate, so we decode 40 frames. In mpeg - TS case we do not do it because it would be - too long */ - st->codec_info_nb_real_frames++; - st->codec_info_nb_repeat_frames += st->codec.repeat_pict; -#if 0 - /* XXX: testing */ - if ((st->codec_info_nb_real_frames % 24) == 23) { - st->codec_info_nb_repeat_frames += 2; - } -#endif - /* stop after 40 frames */ - if (st->codec_info_nb_real_frames >= 40) { - st->r_frame_rate = (st->codec.frame_rate * - st->codec_info_nb_real_frames) / - (st->codec_info_nb_real_frames + - (st->codec_info_nb_repeat_frames >> 1)); - goto close_codec; - } - } else { - close_codec: - st->codec_info_state = CSTATE_FOUND; - avcodec_close(&st->codec); - break; - } - } - ptr += ret; - size -= ret; - } - } - count++; - } - - /* close each codec if there are opened */ - for(i=0;i<ic->nb_streams;i++) { - st = ic->streams[i]; - if (st->codec_info_state == CSTATE_DECODING) - avcodec_close(&st->codec); - } - - /* set real frame rate info */ - for(i=0;i<ic->nb_streams;i++) { - st = ic->streams[i]; - if (st->codec.codec_type == CODEC_TYPE_VIDEO) { - if (!st->r_frame_rate) - st->r_frame_rate = st->codec.frame_rate; - } - } - - return ret; -} - -/** - * Close a media file (but not its codecs) - * - * @param s media file handle - */ -void av_close_input_file(AVFormatContext *s) -{ - int i; - - if (s->iformat->read_close) - s->iformat->read_close(s); - for(i=0;i<s->nb_streams;i++) { - av_free(s->streams[i]); - } - if (s->packet_buffer) { - AVPacketList *p, *p1; - p = s->packet_buffer; - while (p != NULL) { - p1 = p->next; - av_free_packet(&p->pkt); - av_free(p); - p = p1; - } - s->packet_buffer = NULL; - } - if (!(s->iformat->flags & AVFMT_NOFILE)) { - url_fclose(&s->pb); - } - av_freep(&s->priv_data); - av_free(s); -} - -/** - * Add a new stream to a media file. Can only be called in the - * read_header function. If the flag AVFMT_NOHEADER is in the format - * description, then new streams can be added in read_packet too. - * - * - * @param s media file handle - * @param id file format dependent stream id - */ -AVStream *av_new_stream(AVFormatContext *s, int id) -{ - AVStream *st; - - if (s->nb_streams >= MAX_STREAMS) - return NULL; - - st = av_mallocz(sizeof(AVStream)); - if (!st) - return NULL; - st->index = s->nb_streams; - st->id = id; - s->streams[s->nb_streams++] = st; - return st; -} - -/************************************************************/ -/* output media file */ - -/** - * allocate the stream private data and write the stream header to an - * output media file - * - * @param s media file handle - * @return 0 if OK. AVERROR_xxx if error. - */ -int av_write_header(AVFormatContext *s) -{ - int ret, i; - AVStream *st; - - s->priv_data = av_mallocz(s->oformat->priv_data_size); - if (!s->priv_data) - return AVERROR_NOMEM; - /* default pts settings is MPEG like */ - av_set_pts_info(s, 33, 1, 90000); - ret = s->oformat->write_header(s); - if (ret < 0) - return ret; - - /* init PTS generation */ - for(i=0;i<s->nb_streams;i++) { - st = s->streams[i]; - - switch (st->codec.codec_type) { - case CODEC_TYPE_AUDIO: - av_frac_init(&st->pts, 0, 0, - (INT64)s->pts_num * st->codec.sample_rate); - break; - case CODEC_TYPE_VIDEO: - av_frac_init(&st->pts, 0, 0, - (INT64)s->pts_num * st->codec.frame_rate); - break; - default: - break; - } - } - return 0; -} - -/** - * Write a packet to an output media file. The packet shall contain - * one audio or video frame. - * - * @param s media file handle - * @param stream_index stream index - * @param buf buffer containing the frame data - * @param size size of buffer - * @return < 0 if error, = 0 if OK, 1 if end of stream wanted. - */ -int av_write_frame(AVFormatContext *s, int stream_index, const uint8_t *buf, - int size) -{ - AVStream *st; - INT64 pts_mask; - int ret, frame_size; - - st = s->streams[stream_index]; - pts_mask = (1LL << s->pts_wrap_bits) - 1; - ret = s->oformat->write_packet(s, stream_index, (uint8_t *)buf, size, - st->pts.val & pts_mask); - if (ret < 0) - return ret; - - /* update pts */ - switch (st->codec.codec_type) { - case CODEC_TYPE_AUDIO: - if (st->codec.frame_size <= 1) { - frame_size = size / st->codec.channels; - /* specific hack for pcm codecs because no frame size is provided */ - switch(st->codec.codec_id) { - case CODEC_ID_PCM_S16LE: - case CODEC_ID_PCM_S16BE: - case CODEC_ID_PCM_U16LE: - case CODEC_ID_PCM_U16BE: - frame_size >>= 1; - break; - default: - break; - } - } else { - frame_size = st->codec.frame_size; - } - av_frac_add(&st->pts, - (INT64)s->pts_den * frame_size); - break; - case CODEC_TYPE_VIDEO: - av_frac_add(&st->pts, - (INT64)s->pts_den * FRAME_RATE_BASE); - break; - default: - break; - } - return ret; -} - -/** - * write the stream trailer to an output media file and and free the - * file private data. - * - * @param s media file handle - * @return 0 if OK. AVERROR_xxx if error. */ -int av_write_trailer(AVFormatContext *s) -{ - int ret; - ret = s->oformat->write_trailer(s); - av_freep(&s->priv_data); - return ret; -} - -/* "user interface" functions */ - -void dump_format(AVFormatContext *ic, - int index, - const char *url, - int is_output) -{ - int i, flags; - char buf[256]; - - fprintf(stderr, "%s #%d, %s, %s '%s':\n", - is_output ? "Output" : "Input", - index, - is_output ? ic->oformat->name : ic->iformat->name, - is_output ? "to" : "from", url); - for(i=0;i<ic->nb_streams;i++) { - AVStream *st = ic->streams[i]; - avcodec_string(buf, sizeof(buf), &st->codec, is_output); - fprintf(stderr, " Stream #%d.%d", index, i); - /* the pid is an important information, so we display it */ - /* XXX: add a generic system */ - if (is_output) - flags = ic->oformat->flags; - else - flags = ic->iformat->flags; - if (flags & AVFMT_SHOW_IDS) { - fprintf(stderr, "[0x%x]", st->id); - } - fprintf(stderr, ": %s\n", buf); - } -} - -typedef struct { - const char *str; - int width, height; -} SizeEntry; - -static SizeEntry sizes[] = { - { "sqcif", 128, 96 }, - { "qcif", 176, 144 }, - { "cif", 352, 288 }, - { "4cif", 704, 576 }, -}; - -int parse_image_size(int *width_ptr, int *height_ptr, const char *str) -{ - int i; - int n = sizeof(sizes) / sizeof(SizeEntry); - const char *p; - int frame_width = 0, frame_height = 0; - - for(i=0;i<n;i++) { - if (!strcmp(sizes[i].str, str)) { - frame_width = sizes[i].width; - frame_height = sizes[i].height; - break; - } - } - if (i == n) { - p = str; - frame_width = strtol(p, (char **)&p, 10); - if (*p) - p++; - frame_height = strtol(p, (char **)&p, 10); - } - if (frame_width <= 0 || frame_height <= 0) - return -1; - *width_ptr = frame_width; - *height_ptr = frame_height; - return 0; -} - -INT64 av_gettime(void) -{ -#ifdef CONFIG_WIN32 - struct _timeb tb; - _ftime(&tb); - return ((INT64)tb.time * INT64_C(1000) + (INT64)tb.millitm) * INT64_C(1000); -#else - struct timeval tv; - gettimeofday(&tv,NULL); - return (INT64)tv.tv_sec * 1000000 + tv.tv_usec; -#endif -} - -static time_t mktimegm(struct tm *tm) -{ - time_t t; - - int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday; - - if (m < 3) { - m += 12; - y--; - } - - t = 86400 * - (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469); - - t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec; - - return t; -} - -/* Syntax: - * - If not a duration: - * [{YYYY-MM-DD|YYYYMMDD}]{T| }{HH[:MM[:SS[.m...]]][Z]|HH[MM[SS[.m...]]][Z]} - * Time is localtime unless Z is suffixed to the end. In this case GMT - * Return the date in micro seconds since 1970 - * - If duration: - * HH[:MM[:SS[.m...]]] - * S+[.m...] - */ -INT64 parse_date(const char *datestr, int duration) -{ - const char *p; - INT64 t; - struct tm dt; - int i; - static const char *date_fmt[] = { - "%Y-%m-%d", - "%Y%m%d", - }; - static const char *time_fmt[] = { - "%H:%M:%S", - "%H%M%S", - }; - const char *q; - int is_utc, len; - char lastch; - time_t now = time(0); - - len = strlen(datestr); - if (len > 0) - lastch = datestr[len - 1]; - else - lastch = '\0'; - is_utc = (lastch == 'z' || lastch == 'Z'); - - memset(&dt, 0, sizeof(dt)); - - p = datestr; - q = NULL; - if (!duration) { - for (i = 0; i < sizeof(date_fmt) / sizeof(date_fmt[0]); i++) { - q = strptime(p, date_fmt[i], &dt); - if (q) { - break; - } - } - - if (!q) { - if (is_utc) { - dt = *gmtime(&now); - } else { - dt = *localtime(&now); - } - dt.tm_hour = dt.tm_min = dt.tm_sec = 0; - } else { - p = q; - } - - if (*p == 'T' || *p == 't' || *p == ' ') - p++; - - for (i = 0; i < sizeof(time_fmt) / sizeof(time_fmt[0]); i++) { - q = strptime(p, time_fmt[i], &dt); - if (q) { - break; - } - } - } else { - q = strptime(p, time_fmt[0], &dt); - if (!q) { - dt.tm_sec = strtol(p, (char **)&q, 10); - dt.tm_min = 0; - dt.tm_hour = 0; - } - } - - /* Now we have all the fields that we can get */ - if (!q) { - if (duration) - return 0; - else - return now * INT64_C(1000000); - } - - if (duration) { - t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec; - } else { - dt.tm_isdst = -1; /* unknown */ - if (is_utc) { - t = mktimegm(&dt); - } else { - t = mktime(&dt); - } - } - - t *= 1000000; - - if (*q == '.') { - int val, n; - q++; - for (val = 0, n = 100000; n >= 1; n /= 10, q++) { - if (!isdigit(*q)) - break; - val += n * (*q - '0'); - } - t += val; - } - return t; -} - -/* syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done. Return - 1 if found */ -int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info) -{ - const char *p; - char tag[128], *q; - - p = info; - if (*p == '?') - p++; - for(;;) { - q = tag; - while (*p != '\0' && *p != '=' && *p != '&') { - if ((q - tag) < sizeof(tag) - 1) - *q++ = *p; - p++; - } - *q = '\0'; - q = arg; - if (*p == '=') { - p++; - while (*p != '&' && *p != '\0') { - if ((q - arg) < arg_size - 1) { - if (*p == '+') - *q++ = ' '; - else - *q++ = *p; - } - p++; - } - *q = '\0'; - } - if (!strcmp(tag, tag1)) - return 1; - if (*p != '&') - break; - p++; - } - return 0; -} - -/* Return in 'buf' the path with '%d' replaced by number. Also handles - the '%0nd' format where 'n' is the total number of digits and - '%%'. Return 0 if OK, and -1 if format error */ -int get_frame_filename(char *buf, int buf_size, - const char *path, int number) -{ - const char *p; - char *q, buf1[20]; - int nd, len, c, percentd_found; - - q = buf; - p = path; - percentd_found = 0; - for(;;) { - c = *p++; - if (c == '\0') - break; - if (c == '%') { - nd = 0; - while (*p >= '0' && *p <= '9') { - nd = nd * 10 + *p++ - '0'; - } - c = *p++; - switch(c) { - case '%': - goto addchar; - case 'd': - if (percentd_found) - goto fail; - percentd_found = 1; - snprintf(buf1, sizeof(buf1), "%0*d", nd, number); - len = strlen(buf1); - if ((q - buf + len) > buf_size - 1) - goto fail; - memcpy(q, buf1, len); - q += len; - break; - default: - goto fail; - } - } else { - addchar: - if ((q - buf) < buf_size - 1) - *q++ = c; - } - } - if (!percentd_found) - goto fail; - *q = '\0'; - return 0; - fail: - *q = '\0'; - return -1; -} - -/** - * - * Print on stdout a nice hexa dump of a buffer - * @param buf buffer - * @param size buffer size - */ -void av_hex_dump(UINT8 *buf, int size) -{ - int len, i, j, c; - - for(i=0;i<size;i+=16) { - len = size - i; - if (len > 16) - len = 16; - printf("%08x ", i); - for(j=0;j<16;j++) { - if (j < len) - printf(" %02x", buf[i+j]); - else - printf(" "); - } - printf(" "); - for(j=0;j<len;j++) { - c = buf[i+j]; - if (c < ' ' || c > '~') - c = '.'; - printf("%c", c); - } - printf("\n"); - } -} - -void url_split(char *proto, int proto_size, - char *hostname, int hostname_size, - int *port_ptr, - char *path, int path_size, - const char *url) -{ - const char *p; - char *q; - int port; - - port = -1; - - p = url; - q = proto; - while (*p != ':' && *p != '\0') { - if ((q - proto) < proto_size - 1) - *q++ = *p; - p++; - } - if (proto_size > 0) - *q = '\0'; - if (*p == '\0') { - if (proto_size > 0) - proto[0] = '\0'; - if (hostname_size > 0) - hostname[0] = '\0'; - p = url; - } else { - p++; - if (*p == '/') - p++; - if (*p == '/') - p++; - q = hostname; - while (*p != ':' && *p != '/' && *p != '?' && *p != '\0') { - if ((q - hostname) < hostname_size - 1) - *q++ = *p; - p++; - } - if (hostname_size > 0) - *q = '\0'; - if (*p == ':') { - p++; - port = strtoul(p, (char **)&p, 10); - } - } - if (port_ptr) - *port_ptr = port; - pstrcpy(path, path_size, p); -} - -/** - * Set the pts for a given stream - * @param s stream - * @param pts_wrap_bits number of bits effectively used by the pts - * (used for wrap control, 33 is the value for MPEG) - * @param pts_num numerator to convert to seconds (MPEG: 1) - * @param pts_den denominator to convert to seconds (MPEG: 90000) - */ -void av_set_pts_info(AVFormatContext *s, int pts_wrap_bits, - int pts_num, int pts_den) -{ - s->pts_wrap_bits = pts_wrap_bits; - s->pts_num = pts_num; - s->pts_den = pts_den; -} - -/* fraction handling */ - -/** - * f = val + (num / den) + 0.5. 'num' is normalized so that it is such - * as 0 <= num < den. - * - * @param f fractional number - * @param val integer value - * @param num must be >= 0 - * @param den must be >= 1 - */ -void av_frac_init(AVFrac *f, INT64 val, INT64 num, INT64 den) -{ - num += (den >> 1); - if (num >= den) { - val += num / den; - num = num % den; - } - f->val = val; - f->num = num; - f->den = den; -} - -/* set f to (val + 0.5) */ -void av_frac_set(AVFrac *f, INT64 val) -{ - f->val = val; - f->num = f->den >> 1; -} - -/** - * Fractionnal addition to f: f = f + (incr / f->den) - * - * @param f fractional number - * @param incr increment, can be positive or negative - */ -void av_frac_add(AVFrac *f, INT64 incr) -{ - INT64 num, den; - - num = f->num + incr; - den = f->den; - if (num < 0) { - f->val += num / den; - num = num % den; - if (num < 0) { - num += den; - f->val--; - } - } else if (num >= den) { - f->val += num / den; - num = num % den; - } - f->num = num; -} diff --git a/libav/wav.c b/libav/wav.c deleted file mode 100644 index f6bcd7b0e5..0000000000 --- a/libav/wav.c +++ /dev/null @@ -1,326 +0,0 @@ -/* - * WAV encoder and decoder - * Copyright (c) 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, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * 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 - */ -#include "avformat.h" -#include "avi.h" - -const CodecTag codec_wav_tags[] = { - { CODEC_ID_MP2, 0x50 }, - { CODEC_ID_MP3LAME, 0x55 }, - { CODEC_ID_AC3, 0x2000 }, - { CODEC_ID_PCM_S16LE, 0x01 }, - { CODEC_ID_PCM_U8, 0x01 }, /* must come after s16le in this list */ - { CODEC_ID_PCM_ALAW, 0x06 }, - { CODEC_ID_PCM_MULAW, 0x07 }, - { CODEC_ID_ADPCM_MS, 0x02 }, - { CODEC_ID_ADPCM_IMA_WAV, 0x11 }, - { CODEC_ID_WMAV1, 0x160 }, - { CODEC_ID_WMAV2, 0x161 }, - { 0, 0 }, -}; - -/* WAVEFORMATEX header */ -/* returns the size or -1 on error */ -int put_wav_header(ByteIOContext *pb, AVCodecContext *enc) -{ - int tag, bps, blkalign, bytespersec; - int hdrsize = 18; - - tag = codec_get_tag(codec_wav_tags, enc->codec_id); - if (tag == 0) - return -1; - put_le16(pb, tag); - put_le16(pb, enc->channels); - put_le32(pb, enc->sample_rate); - if (enc->codec_id == CODEC_ID_PCM_U8 || - enc->codec_id == CODEC_ID_PCM_ALAW || - enc->codec_id == CODEC_ID_PCM_MULAW) { - bps = 8; - } else if (enc->codec_id == CODEC_ID_MP2 || enc->codec_id == CODEC_ID_MP3LAME) { - bps = 0; - } else if (enc->codec_id == CODEC_ID_ADPCM_IMA_WAV || enc->codec_id == CODEC_ID_ADPCM_MS) { - bps = 4; - } else { - bps = 16; - } - - if (enc->codec_id == CODEC_ID_MP2 || enc->codec_id == CODEC_ID_MP3LAME) { - blkalign = 1; - //blkalign = 144 * enc->bit_rate/enc->sample_rate; - } else if (enc->block_align != 0) { /* specified by the codec */ - blkalign = enc->block_align; - } else - blkalign = enc->channels*bps >> 3; - if (enc->codec_id == CODEC_ID_PCM_U8 || - enc->codec_id == CODEC_ID_PCM_S16LE) { - bytespersec = enc->sample_rate * blkalign; - } else { - bytespersec = enc->bit_rate / 8; - } - put_le32(pb, bytespersec); /* bytes per second */ - put_le16(pb, blkalign); /* block align */ - put_le16(pb, bps); /* bits per sample */ - if (enc->codec_id == CODEC_ID_MP3LAME) { - put_le16(pb, 12); /* wav_extra_size */ - hdrsize += 12; - put_le16(pb, 1); /* wID */ - put_le32(pb, 2); /* fdwFlags */ - put_le16(pb, 1152); /* nBlockSize */ - put_le16(pb, 1); /* nFramesPerBlock */ - put_le16(pb, 1393); /* nCodecDelay */ - } else if (enc->codec_id == CODEC_ID_MP2) { - put_le16(pb, 22); /* wav_extra_size */ - hdrsize += 22; - put_le16(pb, 2); /* fwHeadLayer */ - put_le32(pb, enc->bit_rate); /* dwHeadBitrate */ - put_le16(pb, enc->channels == 2 ? 1 : 8); /* fwHeadMode */ - put_le16(pb, 0); /* fwHeadModeExt */ - put_le16(pb, 1); /* wHeadEmphasis */ - put_le16(pb, 16); /* fwHeadFlags */ - put_le32(pb, 0); /* dwPTSLow */ - put_le32(pb, 0); /* dwPTSHigh */ - } else if (enc->codec_id == CODEC_ID_ADPCM_IMA_WAV) { - put_le16(pb, 2); /* wav_extra_size */ - put_le16(pb, ((enc->block_align - 4 * enc->channels) / (4 * enc->channels)) * 8 + 1); /* wSamplesPerBlock */ - } else - put_le16(pb, 0); /* wav_extra_size */ - - return hdrsize; -} - -void get_wav_header(ByteIOContext *pb, AVCodecContext *codec, - int has_extra_data) -{ - int id; - - id = get_le16(pb); - codec->codec_type = CODEC_TYPE_AUDIO; - codec->codec_tag = id; - codec->fourcc = id; - codec->channels = get_le16(pb); - codec->sample_rate = get_le32(pb); - codec->bit_rate = get_le32(pb) * 8; - codec->block_align = get_le16(pb); - codec->frame_bits = get_le16(pb); /* bits per sample */ - codec->codec_id = wav_codec_get_id(id, codec->frame_bits); - if (has_extra_data) { - codec->extradata_size = get_le16(pb); - if (codec->extradata_size > 0) { - codec->extradata = av_mallocz(codec->extradata_size); - get_buffer(pb, codec->extradata, codec->extradata_size); - } - } -} - - -int wav_codec_get_id(unsigned int tag, int bps) -{ - int id; - id = codec_get_id(codec_wav_tags, tag); - if (id <= 0) - return id; - /* handle specific u8 codec */ - if (id == CODEC_ID_PCM_S16LE && bps == 8) - id = CODEC_ID_PCM_U8; - return id; -} - -typedef struct { - offset_t data; -} WAVContext; - -static int wav_write_header(AVFormatContext *s) -{ - WAVContext *wav = s->priv_data; - ByteIOContext *pb = &s->pb; - offset_t fmt; - - put_tag(pb, "RIFF"); - put_le32(pb, 0); /* file length */ - put_tag(pb, "WAVE"); - - /* format header */ - fmt = start_tag(pb, "fmt "); - if (put_wav_header(pb, &s->streams[0]->codec) < 0) { - av_free(wav); - return -1; - } - end_tag(pb, fmt); - - /* data header */ - wav->data = start_tag(pb, "data"); - - put_flush_packet(pb); - - return 0; -} - -static int wav_write_packet(AVFormatContext *s, int stream_index_ptr, - UINT8 *buf, int size, int force_pts) -{ - ByteIOContext *pb = &s->pb; - put_buffer(pb, buf, size); - return 0; -} - -static int wav_write_trailer(AVFormatContext *s) -{ - ByteIOContext *pb = &s->pb; - WAVContext *wav = s->priv_data; - offset_t file_size; - - if (!url_is_streamed(&s->pb)) { - end_tag(pb, wav->data); - - /* update file size */ - file_size = url_ftell(pb); - url_fseek(pb, 4, SEEK_SET); - put_le32(pb, (UINT32)(file_size - 8)); - url_fseek(pb, file_size, SEEK_SET); - - put_flush_packet(pb); - } - return 0; -} - -/* return the size of the found tag */ -/* XXX: > 2GB ? */ -static int find_tag(ByteIOContext *pb, UINT32 tag1) -{ - unsigned int tag; - int size; - - for(;;) { - if (url_feof(pb)) - return -1; - tag = get_le32(pb); - size = get_le32(pb); - if (tag == tag1) - break; - url_fseek(pb, size, SEEK_CUR); - } - if (size < 0) - size = 0x7fffffff; - return size; -} - -static int wav_probe(AVProbeData *p) -{ - /* check file header */ - if (p->buf_size <= 32) - return 0; - if (p->buf[0] == 'R' && p->buf[1] == 'I' && - p->buf[2] == 'F' && p->buf[3] == 'F' && - p->buf[8] == 'W' && p->buf[9] == 'A' && - p->buf[10] == 'V' && p->buf[11] == 'E') - return AVPROBE_SCORE_MAX; - else - return 0; -} - -/* wav input */ -static int wav_read_header(AVFormatContext *s, - AVFormatParameters *ap) -{ - int size; - unsigned int tag; - ByteIOContext *pb = &s->pb; - AVStream *st; - - /* check RIFF header */ - tag = get_le32(pb); - - if (tag != MKTAG('R', 'I', 'F', 'F')) - return -1; - get_le32(pb); /* file size */ - tag = get_le32(pb); - if (tag != MKTAG('W', 'A', 'V', 'E')) - return -1; - - /* parse fmt header */ - size = find_tag(pb, MKTAG('f', 'm', 't', ' ')); - if (size < 0) - return -1; - st = av_new_stream(s, 0); - if (!st) - return AVERROR_NOMEM; - - get_wav_header(pb, &st->codec, (size >= 18)); - - size = find_tag(pb, MKTAG('d', 'a', 't', 'a')); - if (size < 0) - return -1; - return 0; -} - -#define MAX_SIZE 4096 - -static int wav_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - int ret; - - if (url_feof(&s->pb)) - return -EIO; - if (av_new_packet(pkt, MAX_SIZE)) - return -EIO; - pkt->stream_index = 0; - - ret = get_buffer(&s->pb, pkt->data, pkt->size); - if (ret < 0) - av_free_packet(pkt); - /* note: we need to modify the packet size here to handle the last - packet */ - pkt->size = ret; - return ret; -} - -static int wav_read_close(AVFormatContext *s) -{ - return 0; -} - -static AVInputFormat wav_iformat = { - "wav", - "wav format", - 0, - wav_probe, - wav_read_header, - wav_read_packet, - wav_read_close, -}; - -static AVOutputFormat wav_oformat = { - "wav", - "wav format", - "audio/x-wav", - "wav", - sizeof(WAVContext), - CODEC_ID_PCM_S16LE, - CODEC_ID_NONE, - wav_write_header, - wav_write_packet, - wav_write_trailer, -}; - -int wav_init(void) -{ - av_register_input_format(&wav_iformat); - av_register_output_format(&wav_oformat); - return 0; -} |