Mercurial > audlegacy-plugins
changeset 827:81749781b75f trunk
[svn] - remove some more stuff
author | nenolod |
---|---|
date | Mon, 12 Mar 2007 14:49:42 -0700 |
parents | b9b0a15d0ad3 |
children | c294c4700937 |
files | ChangeLog src/ffmpeg/Makefile src/ffmpeg/libavformat/gxf.c src/ffmpeg/libavformat/gxf.h src/ffmpeg/libavformat/gxfenc.c src/ffmpeg/libavformat/ogg.c src/ffmpeg/libavformat/ogg2.c src/ffmpeg/libavformat/ogg2.h src/ffmpeg/libavformat/oggparseflac.c src/ffmpeg/libavformat/oggparseogm.c src/ffmpeg/libavformat/oggparsetheora.c src/ffmpeg/libavformat/oggparsevorbis.c |
diffstat | 12 files changed, 12 insertions(+), 3024 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Mon Mar 12 14:43:32 2007 -0700 +++ b/ChangeLog Mon Mar 12 14:49:42 2007 -0700 @@ -1,3 +1,15 @@ +2007-03-12 21:43:32 +0000 William Pitcock <nenolod@sacredspiral.co.uk> + revision [1752] + - start removing demuxers for video and images + + trunk/src/ffmpeg/Makefile | 3 + trunk/src/ffmpeg/libavcodec/allcodecs.c | 582 -------------------- + trunk/src/ffmpeg/libavformat/gif.c | 432 --------------- + trunk/src/ffmpeg/libavformat/jpeg.c | 240 -------- + trunk/src/ffmpeg/libavformat/png.c | 889 -------------------------------- + 5 files changed, 2146 deletions(-) + + 2007-03-12 21:37:31 +0000 William Pitcock <nenolod@sacredspiral.co.uk> revision [1750] - make this compile again
--- a/src/ffmpeg/Makefile Mon Mar 12 14:43:32 2007 -0700 +++ b/src/ffmpeg/Makefile Mon Mar 12 14:49:42 2007 -0700 @@ -95,8 +95,6 @@ libavformat/framehook.c \ libavformat/gifdec.c \ libavformat/grab.c \ - libavformat/gxf.c \ - libavformat/gxfenc.c \ libavformat/idcin.c \ libavformat/idroq.c \ libavformat/img.c \ @@ -118,12 +116,6 @@ libavformat/nsvdec.c \ libavformat/nut.c \ libavformat/nuv.c \ - libavformat/ogg.c \ - libavformat/ogg2.c \ - libavformat/oggparseflac.c \ - libavformat/oggparseogm.c \ - libavformat/oggparsetheora.c \ - libavformat/oggparsevorbis.c \ libavformat/os_support.c \ libavformat/pnm.c \ libavformat/psxstr.c \
--- a/src/ffmpeg/libavformat/gxf.c Mon Mar 12 14:43:32 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,516 +0,0 @@ -/* - * GXF demuxer. - * Copyright (c) 2006 Reimar Doeffinger. - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ -#include "avformat.h" -#include "common.h" - -typedef enum { - PKT_MAP = 0xbc, - PKT_MEDIA = 0xbf, - PKT_EOS = 0xfb, - PKT_FLT = 0xfc, - PKT_UMF = 0xfd -} pkt_type_t; - -typedef enum { - MAT_NAME = 0x40, - MAT_FIRST_FIELD = 0x41, - MAT_LAST_FIELD = 0x42, - MAT_MARK_IN = 0x43, - MAT_MARK_OUT = 0x44, - MAT_SIZE = 0x45 -} mat_tag_t; - -typedef enum { - TRACK_NAME = 0x4c, - TRACK_AUX = 0x4d, - TRACK_VER = 0x4e, - TRACK_MPG_AUX = 0x4f, - TRACK_FPS = 0x50, - TRACK_LINES = 0x51, - TRACK_FPF = 0x52 -} track_tag_t; - -typedef struct { - int64_t first_field; - int64_t last_field; - AVRational frames_per_second; - int32_t fields_per_frame; -} st_info_t; - -/** - * \brief parses a packet header, extracting type and length - * \param pb ByteIOContext to read header from - * \param type detected packet type is stored here - * \param length detected packet length, excluding header is stored here - * \return 0 if header not found or contains invalid data, 1 otherwise - */ -static int parse_packet_header(ByteIOContext *pb, pkt_type_t *type, int *length) { - if (get_be32(pb)) - return 0; - if (get_byte(pb) != 1) - return 0; - *type = get_byte(pb); - *length = get_be32(pb); - if ((*length >> 24) || *length < 16) - return 0; - *length -= 16; - if (get_be32(pb)) - return 0; - if (get_byte(pb) != 0xe1) - return 0; - if (get_byte(pb) != 0xe2) - return 0; - return 1; -} - -/** - * \brief check if file starts with a PKT_MAP header - */ -static int gxf_probe(AVProbeData *p) { - static const uint8_t startcode[] = {0, 0, 0, 0, 1, 0xbc}; // start with map packet - static const uint8_t endcode[] = {0, 0, 0, 0, 0xe1, 0xe2}; - if (p->buf_size < 16) - return 0; - if (!memcmp(p->buf, startcode, sizeof(startcode)) && - !memcmp(&p->buf[16 - sizeof(endcode)], endcode, sizeof(endcode))) - return AVPROBE_SCORE_MAX; - return 0; -} - -/** - * \brief gets the stream index for the track with the specified id, creates new - * stream if not found - * \param stream id of stream to find / add - * \param format stream format identifier - */ -static int get_sindex(AVFormatContext *s, int id, int format) { - int i; - AVStream *st = NULL; - for (i = 0; i < s->nb_streams; i++) { - if (s->streams[i]->id == id) - return i; - } - st = av_new_stream(s, id); - switch (format) { - case 3: - case 4: - st->codec->codec_type = CODEC_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_MJPEG; - break; - case 13: - case 15: - st->codec->codec_type = CODEC_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_DVVIDEO; - break; - case 14: - case 16: - st->codec->codec_type = CODEC_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_DVVIDEO; - break; - case 11: - case 12: - case 20: - st->codec->codec_type = CODEC_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_MPEG2VIDEO; - break; - case 22: - case 23: - st->codec->codec_type = CODEC_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_MPEG1VIDEO; - break; - case 9: - st->codec->codec_type = CODEC_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_PCM_S24LE; - st->codec->channels = 1; - st->codec->sample_rate = 48000; - st->codec->bit_rate = 3 * 1 * 48000 * 8; - st->codec->block_align = 3 * 1; - st->codec->bits_per_sample = 24; - break; - case 10: - st->codec->codec_type = CODEC_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_PCM_S16LE; - st->codec->channels = 1; - st->codec->sample_rate = 48000; - st->codec->bit_rate = 2 * 1 * 48000 * 8; - st->codec->block_align = 2 * 1; - st->codec->bits_per_sample = 16; - break; - case 17: - st->codec->codec_type = CODEC_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_AC3; - st->codec->channels = 2; - st->codec->sample_rate = 48000; - break; - default: - st->codec->codec_type = CODEC_TYPE_UNKNOWN; - st->codec->codec_id = CODEC_ID_NONE; - break; - } - return s->nb_streams - 1; -} - -/** - * \brief filters out interesting tags from material information. - * \param len lenght of tag section, will be adjusted to contain remaining bytes - * \param si struct to store collected information into - */ -static void gxf_material_tags(ByteIOContext *pb, int *len, st_info_t *si) { - si->first_field = AV_NOPTS_VALUE; - si->last_field = AV_NOPTS_VALUE; - while (*len >= 2) { - mat_tag_t tag = get_byte(pb); - int tlen = get_byte(pb); - *len -= 2; - if (tlen > *len) - return; - *len -= tlen; - if (tlen == 4) { - uint32_t value = get_be32(pb); - if (tag == MAT_FIRST_FIELD) - si->first_field = value; - else if (tag == MAT_LAST_FIELD) - si->last_field = value; - } else - url_fskip(pb, tlen); - } -} - -/** - * \brief convert fps tag value to AVRational fps - * \param fps fps value from tag - * \return fps as AVRational, or 0 / 0 if unknown - */ -static AVRational fps_tag2avr(int32_t fps) { - extern const AVRational ff_frame_rate_tab[]; - if (fps < 1 || fps > 9) fps = 9; - return ff_frame_rate_tab[9 - fps]; // values have opposite order -} - -/** - * \brief convert UMF attributes flags to AVRational fps - * \param fps fps value from flags - * \return fps as AVRational, or 0 / 0 if unknown - */ -static AVRational fps_umf2avr(uint32_t flags) { - static const AVRational map[] = {{50, 1}, {60000, 1001}, {24, 1}, - {25, 1}, {30000, 1001}}; - int idx = av_log2((flags & 0x7c0) >> 6); - return map[idx]; -} - -/** - * \brief filters out interesting tags from track information. - * \param len length of tag section, will be adjusted to contain remaining bytes - * \param si struct to store collected information into - */ -static void gxf_track_tags(ByteIOContext *pb, int *len, st_info_t *si) { - si->frames_per_second = (AVRational){0, 0}; - si->fields_per_frame = 0; - while (*len >= 2) { - track_tag_t tag = get_byte(pb); - int tlen = get_byte(pb); - *len -= 2; - if (tlen > *len) - return; - *len -= tlen; - if (tlen == 4) { - uint32_t value = get_be32(pb); - if (tag == TRACK_FPS) - si->frames_per_second = fps_tag2avr(value); - else if (tag == TRACK_FPF && (value == 1 || value == 2)) - si->fields_per_frame = value; - } else - url_fskip(pb, tlen); - } -} - -/** - * \brief read index from FLT packet into stream 0 av_index - */ -static void gxf_read_index(AVFormatContext *s, int pkt_len) { - ByteIOContext *pb = &s->pb; - AVStream *st = s->streams[0]; - uint32_t fields_per_map = get_le32(pb); - uint32_t map_cnt = get_le32(pb); - int i; - pkt_len -= 8; - if (map_cnt > 1000) { - av_log(s, AV_LOG_ERROR, "GXF: too many index entries %u (%x)\n", map_cnt, map_cnt); - map_cnt = 1000; - } - if (pkt_len < 4 * map_cnt) { - av_log(s, AV_LOG_ERROR, "GXF: invalid index length\n"); - url_fskip(pb, pkt_len); - return; - } - pkt_len -= 4 * map_cnt; - av_add_index_entry(st, 0, 0, 0, 0, 0); - for (i = 0; i < map_cnt; i++) - av_add_index_entry(st, (uint64_t)get_le32(pb) * 1024, - i * (uint64_t)fields_per_map + 1, 0, 0, 0); - url_fskip(pb, pkt_len); -} - -static int gxf_header(AVFormatContext *s, AVFormatParameters *ap) { - ByteIOContext *pb = &s->pb; - pkt_type_t pkt_type; - int map_len; - int len; - AVRational main_timebase = {0, 0}; - st_info_t si; - int i; - if (!parse_packet_header(pb, &pkt_type, &map_len) || pkt_type != PKT_MAP) { - av_log(s, AV_LOG_ERROR, "GXF: map packet not found\n"); - return 0; - } - map_len -= 2; - if (get_byte(pb) != 0x0e0 || get_byte(pb) != 0xff) { - av_log(s, AV_LOG_ERROR, "GXF: unknown version or invalid map preamble\n"); - return 0; - } - map_len -= 2; - len = get_be16(pb); // length of material data section - if (len > map_len) { - av_log(s, AV_LOG_ERROR, "GXF: material data longer than map data\n"); - return 0; - } - map_len -= len; - gxf_material_tags(pb, &len, &si); - url_fskip(pb, len); - map_len -= 2; - len = get_be16(pb); // length of track description - if (len > map_len) { - av_log(s, AV_LOG_ERROR, "GXF: track description longer than map data\n"); - return 0; - } - map_len -= len; - while (len > 0) { - int track_type, track_id, track_len; - AVStream *st; - int idx; - len -= 4; - track_type = get_byte(pb); - track_id = get_byte(pb); - track_len = get_be16(pb); - len -= track_len; - gxf_track_tags(pb, &track_len, &si); - url_fskip(pb, track_len); - if (!(track_type & 0x80)) { - av_log(s, AV_LOG_ERROR, "GXF: invalid track type %x\n", track_type); - continue; - } - track_type &= 0x7f; - if ((track_id & 0xc0) != 0xc0) { - av_log(s, AV_LOG_ERROR, "GXF: invalid track id %x\n", track_id); - continue; - } - track_id &= 0x3f; - idx = get_sindex(s, track_id, track_type); - if (idx < 0) continue; - st = s->streams[idx]; - if (!main_timebase.num || !main_timebase.den) { - main_timebase.num = si.frames_per_second.den; - main_timebase.den = si.frames_per_second.num * si.fields_per_frame; - } - st->start_time = si.first_field; - if (si.first_field != AV_NOPTS_VALUE && si.last_field != AV_NOPTS_VALUE) - st->duration = si.last_field - si.first_field; - } - if (len < 0) - av_log(s, AV_LOG_ERROR, "GXF: invalid track description length specified\n"); - if (map_len) - url_fskip(pb, map_len); - if (!parse_packet_header(pb, &pkt_type, &len)) { - av_log(s, AV_LOG_ERROR, "GXF: sync lost in header\n"); - return -1; - } - if (pkt_type == PKT_FLT) { - gxf_read_index(s, len); - if (!parse_packet_header(pb, &pkt_type, &len)) { - av_log(s, AV_LOG_ERROR, "GXF: sync lost in header\n"); - return -1; - } - } - if (pkt_type == PKT_UMF) { - if (len >= 9) { - AVRational fps; - len -= 9; - url_fskip(pb, 5); - fps = fps_umf2avr(get_le32(pb)); - if (!main_timebase.num || !main_timebase.den) { - // this may not always be correct, but simply the best we can get - main_timebase.num = fps.den; - main_timebase.den = fps.num; - } - } else - av_log(s, AV_LOG_INFO, "GXF: UMF packet too short\n"); - } else - av_log(s, AV_LOG_INFO, "GXF: UMF packet missing\n"); - url_fskip(pb, len); - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - if (main_timebase.num && main_timebase.den) - st->time_base = main_timebase; - else { - st->start_time = st->duration = AV_NOPTS_VALUE; - } - } - return 0; -} - -#define READ_ONE() \ - { \ - if (!max_interval-- || url_feof(pb)) \ - goto out; \ - tmp = tmp << 8 | get_byte(pb); \ - } - -/** - * \brief resync the stream on the next media packet with specified properties - * \param max_interval how many bytes to search for matching packet at most - * \param track track id the media packet must belong to, -1 for any - * \param timestamp minimum timestamp (== field number) the packet must have, -1 for any - * \return timestamp of packet found - */ -static int64_t gxf_resync_media(AVFormatContext *s, uint64_t max_interval, int track, int timestamp) { - uint32_t tmp; - uint64_t last_pos; - uint64_t last_found_pos = 0; - int cur_track; - int64_t cur_timestamp = AV_NOPTS_VALUE; - int len; - ByteIOContext *pb = &s->pb; - pkt_type_t type; - tmp = get_be32(pb); -start: - while (tmp) - READ_ONE(); - READ_ONE(); - if (tmp != 1) - goto start; - last_pos = url_ftell(pb); - url_fseek(pb, -5, SEEK_CUR); - if (!parse_packet_header(pb, &type, &len) || type != PKT_MEDIA) { - url_fseek(pb, last_pos, SEEK_SET); - goto start; - } - get_byte(pb); - cur_track = get_byte(pb); - cur_timestamp = get_be32(pb); - last_found_pos = url_ftell(pb) - 16 - 6; - if ((track >= 0 && track != cur_track) || (timestamp >= 0 && timestamp > cur_timestamp)) { - url_fseek(pb, last_pos, SEEK_SET); - goto start; - } -out: - if (last_found_pos) - url_fseek(pb, last_found_pos, SEEK_SET); - return cur_timestamp; -} - -static int gxf_packet(AVFormatContext *s, AVPacket *pkt) { - ByteIOContext *pb = &s->pb; - pkt_type_t pkt_type; - int pkt_len; - while (!url_feof(pb)) { - int track_type, track_id, ret; - int field_nr; - if (!parse_packet_header(pb, &pkt_type, &pkt_len)) { - if (!url_feof(pb)) - av_log(s, AV_LOG_ERROR, "GXF: sync lost\n"); - return -1; - } - if (pkt_type == PKT_FLT) { - gxf_read_index(s, pkt_len); - continue; - } - if (pkt_type != PKT_MEDIA) { - url_fskip(pb, pkt_len); - continue; - } - if (pkt_len < 16) { - av_log(s, AV_LOG_ERROR, "GXF: invalid media packet length\n"); - continue; - } - pkt_len -= 16; - track_type = get_byte(pb); - track_id = get_byte(pb); - field_nr = get_be32(pb); - get_be32(pb); // field information - get_be32(pb); // "timeline" field number - get_byte(pb); // flags - get_byte(pb); // reserved - // NOTE: there is also data length information in the - // field information, it might be better to take this into account - // as well. - ret = av_get_packet(pb, pkt, pkt_len); - pkt->stream_index = get_sindex(s, track_id, track_type); - pkt->dts = field_nr; - return ret; - } - return AVERROR_IO; -} - -static int gxf_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { - uint64_t pos; - uint64_t maxlen = 100 * 1024 * 1024; - AVStream *st = s->streams[0]; - int64_t start_time = s->streams[stream_index]->start_time; - int64_t found; - int idx; - if (timestamp < start_time) timestamp = start_time; - idx = av_index_search_timestamp(st, timestamp - start_time, - AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD); - if (idx < 0) - return -1; - pos = st->index_entries[idx].pos; - if (idx < st->nb_index_entries - 2) - maxlen = st->index_entries[idx + 2].pos - pos; - maxlen = FFMAX(maxlen, 200 * 1024); - url_fseek(&s->pb, pos, SEEK_SET); - found = gxf_resync_media(s, maxlen, -1, timestamp); - if (FFABS(found - timestamp) > 4) - return -1; - return 0; -} - -static int64_t gxf_read_timestamp(AVFormatContext *s, int stream_index, - int64_t *pos, int64_t pos_limit) { - ByteIOContext *pb = &s->pb; - int64_t res; - url_fseek(pb, *pos, SEEK_SET); - res = gxf_resync_media(s, pos_limit - *pos, -1, -1); - *pos = url_ftell(pb); - return res; -} - -AVInputFormat gxf_demuxer = { - "gxf", - "GXF format", - 0, - gxf_probe, - gxf_header, - gxf_packet, - NULL, - gxf_seek, - gxf_read_timestamp, -};
--- a/src/ffmpeg/libavformat/gxf.h Mon Mar 12 14:43:32 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -/* - * GXF demuxer - * copyright (c) 2006 Reimar Doeffinger - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef FFMPEG_GXF_H -#define FFMPEG_GXF_H - -/* gxf.c */ -typedef enum { - PKT_MAP = 0xbc, - PKT_MEDIA = 0xbf, - PKT_EOS = 0xfb, - PKT_FLT = 0xfc, - PKT_UMF = 0xfd -} pkt_type_t; - -#endif /* FFMPEG_GXF_H */
--- a/src/ffmpeg/libavformat/gxfenc.c Mon Mar 12 14:43:32 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,819 +0,0 @@ -/* - * GXF muxer. - * Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier <baptiste dot coudurier at smartjog dot com>. - * - * This file is part of FFmpeg. - * - * FFmpeg 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. - * - * FFmpeg 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "avformat.h" -#include "gxf.h" -#include "riff.h" -#include "fifo.h" - -#define GXF_AUDIO_PACKET_SIZE 65536 - -typedef struct GXFStreamContext { - AVCodecContext *codec; - AVFifoBuffer audio_buffer; - uint32_t track_type; - uint32_t sample_size; - uint32_t sample_rate; - uint16_t media_type; - uint16_t media_info; - uint8_t index; - int frame_rate_index; - int lines_index; - int fields; - int iframes; - int pframes; - int bframes; - int p_per_gop; - int b_per_gop; - int first_gop_closed; - int64_t current_dts; -} GXFStreamContext; - -typedef struct GXFContext { - uint32_t nb_frames; - uint32_t material_flags; - uint16_t audio_tracks; - uint16_t mpeg_tracks; - int64_t creation_time; - uint32_t umf_start_offset; - uint32_t umf_track_offset; - uint32_t umf_media_offset; - uint32_t umf_user_data_offset; - uint32_t umf_user_data_size; - uint32_t umf_length; - uint16_t umf_track_size; - uint16_t umf_media_size; - int audio_written; - int sample_rate; - int flags; - AVFormatContext *fc; - GXFStreamContext streams[48]; -} GXFContext; - -typedef struct GXF_Lines { - int height; - int index; -} GXF_Lines; - - -/* FIXME check if it is relevant */ -static const GXF_Lines gxf_lines_tab[] = { - { 480, 1 }, /* NTSC */ - { 512, 1 }, /* NTSC + VBI */ - { 576, 2 }, /* PAL */ - { 608, 2 }, /* PAL + VBI */ - { 1080, 4 }, - { 720, 6 }, -}; - -static const CodecTag gxf_media_types[] = { - { CODEC_ID_MJPEG , 3 }, /* NTSC */ - { CODEC_ID_MJPEG , 4 }, /* PAL */ - { CODEC_ID_PCM_S24LE , 9 }, - { CODEC_ID_PCM_S16LE , 10 }, - { CODEC_ID_MPEG2VIDEO, 11 }, /* NTSC */ - { CODEC_ID_MPEG2VIDEO, 12 }, /* PAL */ - { CODEC_ID_DVVIDEO , 13 }, /* NTSC */ - { CODEC_ID_DVVIDEO , 14 }, /* PAL */ - { CODEC_ID_DVVIDEO , 15 }, /* 50M NTSC */ - { CODEC_ID_DVVIDEO , 16 }, /* 50M PAL */ - { CODEC_ID_AC3 , 17 }, - //{ CODEC_ID_NONE, , 18 }, /* Non compressed 24 bit audio */ - { CODEC_ID_MPEG2VIDEO, 20 }, /* MPEG HD */ - { CODEC_ID_MPEG1VIDEO, 22 }, /* NTSC */ - { CODEC_ID_MPEG1VIDEO, 23 }, /* PAL */ - { 0, 0 }, -}; - -#define SERVER_PATH "/space/" -#define ES_NAME_PATTERN "ES." - -static int gxf_find_lines_index(GXFStreamContext *ctx) -{ - int i; - - for (i = 0; i < 6; ++i) { - if (ctx->codec->height == gxf_lines_tab[i].height) { - ctx->lines_index = gxf_lines_tab[i].index; - return 0; - } - } - return -1; -} - -static void gxf_write_padding(ByteIOContext *pb, offset_t to_pad) -{ - for (; to_pad > 0; to_pad--) { - put_byte(pb, 0); - } -} - -static offset_t updatePacketSize(ByteIOContext *pb, offset_t pos) -{ - offset_t curpos; - int size; - - size = url_ftell(pb) - pos; - if (size % 4) { - gxf_write_padding(pb, 4 - size % 4); - size = url_ftell(pb) - pos; - } - curpos = url_ftell(pb); - url_fseek(pb, pos + 6, SEEK_SET); - put_be32(pb, size); - url_fseek(pb, curpos, SEEK_SET); - return curpos - pos; -} - -static offset_t updateSize(ByteIOContext *pb, offset_t pos) -{ - offset_t curpos; - - curpos = url_ftell(pb); - url_fseek(pb, pos, SEEK_SET); - put_be16(pb, curpos - pos - 2); - url_fseek(pb, curpos, SEEK_SET); - return curpos - pos; -} - -static void gxf_write_packet_header(ByteIOContext *pb, pkt_type_t type) -{ - put_be32(pb, 0); /* packet leader for synchro */ - put_byte(pb, 1); - put_byte(pb, type); /* map packet */ - put_be32(pb, 0); /* size */ - put_be32(pb, 0); /* reserved */ - put_byte(pb, 0xE1); /* trailer 1 */ - put_byte(pb, 0xE2); /* trailer 2 */ -} - -static int gxf_write_mpeg_auxiliary(ByteIOContext *pb, GXFStreamContext *ctx) -{ - char buffer[1024]; - int size; - - if (ctx->iframes) { - ctx->p_per_gop = ctx->pframes / ctx->iframes; - if (ctx->pframes % ctx->iframes) - ctx->p_per_gop++; - if (ctx->pframes) - ctx->b_per_gop = ctx->bframes / ctx->pframes; - if (ctx->p_per_gop > 9) - ctx->p_per_gop = 9; /* ensure value won't take more than one char */ - if (ctx->b_per_gop > 9) - ctx->b_per_gop = 9; /* ensure value won't take more than one char */ - } - size = snprintf(buffer, 1024, "Ver 1\nBr %.6f\nIpg 1\nPpi %d\nBpiop %d\n" - "Pix 0\nCf %d\nCg %d\nSl 7\nnl16 %d\nVi 1\nf1 1\n", - (float)ctx->codec->bit_rate, ctx->p_per_gop, ctx->b_per_gop, - ctx->codec->pix_fmt == PIX_FMT_YUV422P ? 2 : 1, ctx->first_gop_closed == 1, - ctx->codec->height / 16); - put_byte(pb, 0x4F); - put_byte(pb, size + 1); - put_buffer(pb, (uint8_t *)buffer, size + 1); - return size + 3; -} - -static int gxf_write_timecode_auxiliary(ByteIOContext *pb, GXFStreamContext *ctx) -{ - /* FIXME implement that */ - put_byte(pb, 0); /* fields */ - put_byte(pb, 0); /* seconds */ - put_byte(pb, 0); /* minutes */ - put_byte(pb, 0); /* flags + hours */ - /* reserved */ - put_be32(pb, 0); - return 8; -} - -static int gxf_write_track_description(ByteIOContext *pb, GXFStreamContext *stream) -{ - offset_t pos; - - /* track description section */ - put_byte(pb, stream->media_type + 0x80); - put_byte(pb, stream->index + 0xC0); - - pos = url_ftell(pb); - put_be16(pb, 0); /* size */ - - /* media file name */ - put_byte(pb, 0x4C); - put_byte(pb, strlen(ES_NAME_PATTERN) + 3); - put_tag(pb, ES_NAME_PATTERN); - put_be16(pb, stream->media_info); - put_byte(pb, 0); - - if (stream->codec->codec_id != CODEC_ID_MPEG2VIDEO) { - /* auxiliary information */ - put_byte(pb, 0x4D); - put_byte(pb, 8); - if (stream->codec->codec_id == CODEC_ID_NONE) - gxf_write_timecode_auxiliary(pb, stream); - else - put_le64(pb, 0); - } - - /* file system version */ - put_byte(pb, 0x4E); - put_byte(pb, 4); - put_be32(pb, 0); - - if (stream->codec->codec_id == CODEC_ID_MPEG2VIDEO) - gxf_write_mpeg_auxiliary(pb, stream); - - /* frame rate */ - put_byte(pb, 0x50); - put_byte(pb, 4); - put_be32(pb, stream->frame_rate_index); - - /* lines per frame */ - put_byte(pb, 0x51); - put_byte(pb, 4); - put_be32(pb, stream->lines_index); - - /* fields per frame */ - put_byte(pb, 0x52); - put_byte(pb, 4); - put_be32(pb, stream->fields); - - return updateSize(pb, pos); -} - -static int gxf_write_material_data_section(ByteIOContext *pb, GXFContext *ctx) -{ - offset_t pos; - const char *filename = strrchr(ctx->fc->filename, '/'); - - pos = url_ftell(pb); - put_be16(pb, 0); /* size */ - - /* name */ - if (filename) - filename++; - else - filename = ctx->fc->filename; - put_byte(pb, 0x40); - put_byte(pb, strlen(SERVER_PATH) + strlen(filename) + 1); - put_tag(pb, SERVER_PATH); - put_tag(pb, filename); - put_byte(pb, 0); - - /* first field */ - put_byte(pb, 0x41); - put_byte(pb, 4); - put_be32(pb, 0); - - /* last field */ - put_byte(pb, 0x42); - put_byte(pb, 4); - put_be32(pb, ctx->nb_frames); - - /* reserved */ - put_byte(pb, 0x43); - put_byte(pb, 4); - put_be32(pb, 0); - - put_byte(pb, 0x44); - put_byte(pb, 4); - put_be32(pb, ctx->nb_frames); - - /* estimated size */ - put_byte(pb, 0x45); - put_byte(pb, 4); - put_be32(pb, url_fsize(pb) / 1024); - - return updateSize(pb, pos); -} - -static int gxf_write_track_description_section(ByteIOContext *pb, GXFContext *ctx) -{ - offset_t pos; - int i; - - pos = url_ftell(pb); - put_be16(pb, 0); /* size */ - for (i = 0; i < ctx->fc->nb_streams; ++i) - gxf_write_track_description(pb, &ctx->streams[i]); - return updateSize(pb, pos); -} - -static int gxf_write_map_packet(ByteIOContext *pb, GXFContext *ctx) -{ - offset_t pos = url_ftell(pb); - - gxf_write_packet_header(pb, PKT_MAP); - - /* preamble */ - put_byte(pb, 0xE0); /* version */ - put_byte(pb, 0xFF); /* reserved */ - - gxf_write_material_data_section(pb, ctx); - gxf_write_track_description_section(pb, ctx); - - return updatePacketSize(pb, pos); -} - -#if 0 -static int gxf_write_flt_packet(ByteIOContext *pb, GXFContext *ctx) -{ - offset_t pos = url_ftell(pb); - int i; - - gxf_write_packet_header(pb, PKT_FLT); - - put_le32(pb, 1000); /* number of fields */ - put_le32(pb, 0); /* number of active flt entries */ - - for (i = 0; i < 1000; ++i) { - put_le32(pb, 0); - } - return updatePacketSize(pb, pos); -} -#endif - -static int gxf_write_umf_material_description(ByteIOContext *pb, GXFContext *ctx) -{ - put_le32(pb, ctx->flags); - put_le32(pb, ctx->nb_frames); /* length of the longest track */ - put_le32(pb, ctx->nb_frames); /* length of the shortest track */ - put_le32(pb, 0); /* mark in */ - put_le32(pb, ctx->nb_frames); /* mark out */ - put_le32(pb, 0); /* timecode mark in */ - put_le32(pb, ctx->nb_frames); /* timecode mark out */ - put_le64(pb, ctx->fc->timestamp); /* modification time */ - put_le64(pb, ctx->fc->timestamp); /* creation time */ - put_le16(pb, 0); /* reserved */ - put_le16(pb, 0); /* reserved */ - put_le16(pb, ctx->audio_tracks); - put_le16(pb, 0); /* timecode track count */ - put_le16(pb, 0); /* reserved */ - put_le16(pb, ctx->mpeg_tracks); - return 48; -} - -static int gxf_write_umf_payload(ByteIOContext *pb, GXFContext *ctx) -{ - put_le32(pb, ctx->umf_length); /* total length of the umf data */ - put_le32(pb, 3); /* version */ - put_le32(pb, ctx->fc->nb_streams); - put_le32(pb, ctx->umf_track_offset); /* umf track section offset */ - put_le32(pb, ctx->umf_track_size); - put_le32(pb, ctx->fc->nb_streams); - put_le32(pb, ctx->umf_media_offset); - put_le32(pb, ctx->umf_media_size); - put_le32(pb, ctx->umf_user_data_offset); /* user data offset */ - put_le32(pb, ctx->umf_user_data_size); /* user data size */ - put_le32(pb, 0); /* reserved */ - put_le32(pb, 0); /* reserved */ - return 48; -} - -static int gxf_write_umf_track_description(ByteIOContext *pb, GXFContext *ctx) -{ - offset_t pos = url_ftell(pb); - int tracks[255]={0}; - int i; - - ctx->umf_track_offset = pos - ctx->umf_start_offset; - for (i = 0; i < ctx->fc->nb_streams; ++i) { - AVStream *st = ctx->fc->streams[i]; - GXFStreamContext *sc = &ctx->streams[i]; - int id = 0; - - switch (st->codec->codec_id) { - case CODEC_ID_MPEG1VIDEO: id= 'L'; break; - case CODEC_ID_MPEG2VIDEO: id= 'M'; break; - case CODEC_ID_PCM_S16LE: id= 'A'; break; - case CODEC_ID_DVVIDEO: id= sc->track_type == 6 ? 'E' : 'D'; break; - case CODEC_ID_MJPEG: id= 'V'; break; - default: break; - } - sc->media_info= id << 8; - /* FIXME first 10 audio tracks are 0 to 9 next 22 are A to V */ - sc->media_info |= '0' + (tracks[id]++); - put_le16(pb, sc->media_info); - put_le16(pb, 1); - } - return url_ftell(pb) - pos; -} - -static int gxf_write_umf_media_mpeg(ByteIOContext *pb, GXFStreamContext *stream) -{ - if (stream->codec->pix_fmt == PIX_FMT_YUV422P) - put_le32(pb, 2); - else - put_le32(pb, 1); /* default to 420 */ - put_le32(pb, stream->first_gop_closed == 1); /* closed = 1, open = 0, unknown = 255 */ - put_le32(pb, 3); /* top = 1, bottom = 2, frame = 3, unknown = 0 */ - put_le32(pb, 1); /* I picture per GOP */ - put_le32(pb, stream->p_per_gop); - put_le32(pb, stream->b_per_gop); - if (stream->codec->codec_id == CODEC_ID_MPEG2VIDEO) - put_le32(pb, 2); - else if (stream->codec->codec_id == CODEC_ID_MPEG1VIDEO) - put_le32(pb, 1); - else - put_le32(pb, 0); - put_le32(pb, 0); /* reserved */ - return 32; -} - -static int gxf_write_umf_media_timecode(ByteIOContext *pb, GXFStreamContext *track) -{ - /* FIXME implement */ - put_be32(pb, 0); /* drop frame flag */ - put_be32(pb, 0); /* reserved */ - put_be32(pb, 0); /* reserved */ - put_be32(pb, 0); /* reserved */ - put_be32(pb, 0); /* reserved */ - put_be32(pb, 0); /* reserved */ - put_be32(pb, 0); /* reserved */ - put_be32(pb, 0); /* reserved */ - return 32; -} - -static int gxf_write_umf_media_dv(ByteIOContext *pb, GXFStreamContext *track) -{ - int i; - - for (i = 0; i < 8; i++) { - put_be32(pb, 0); - } - return 32; -} - -static int gxf_write_umf_media_audio(ByteIOContext *pb, GXFStreamContext *track) -{ - put_le64(pb, av_dbl2int(1)); /* sound level to begin to */ - put_le64(pb, av_dbl2int(1)); /* sound level to begin to */ - put_le32(pb, 0); /* number of fields over which to ramp up sound level */ - put_le32(pb, 0); /* number of fields over which to ramp down sound level */ - put_le32(pb, 0); /* reserved */ - put_le32(pb, 0); /* reserved */ - return 32; -} - -#if 0 -static int gxf_write_umf_media_mjpeg(ByteIOContext *pb, GXFStreamContext *track) -{ - put_be64(pb, 0); /* FIXME FLOAT max chroma quant level */ - put_be64(pb, 0); /* FIXME FLOAT max luma quant level */ - put_be64(pb, 0); /* FIXME FLOAT min chroma quant level */ - put_be64(pb, 0); /* FIXME FLOAT min luma quant level */ - return 32; -} -#endif - -static int gxf_write_umf_media_description(ByteIOContext *pb, GXFContext *ctx) -{ - offset_t pos; - int i; - - pos = url_ftell(pb); - ctx->umf_media_offset = pos - ctx->umf_start_offset; - for (i = 0; i < ctx->fc->nb_streams; ++i) { - GXFStreamContext *sc = &ctx->streams[i]; - char buffer[88]; - offset_t startpos, curpos; - int path_size = strlen(ES_NAME_PATTERN); - - memset(buffer, 0, 88); - startpos = url_ftell(pb); - put_le16(pb, 0); /* length */ - put_le16(pb, sc->media_info); - put_le16(pb, 0); /* reserved */ - put_le16(pb, 0); /* reserved */ - put_le32(pb, ctx->nb_frames); - put_le32(pb, 0); /* attributes rw, ro */ - put_le32(pb, 0); /* mark in */ - put_le32(pb, ctx->nb_frames); /* mark out */ - strncpy(buffer, ES_NAME_PATTERN, path_size); - put_buffer(pb, (uint8_t *)buffer, path_size); - put_be16(pb, sc->media_info); - put_buffer(pb, (uint8_t *)buffer + path_size + 2, 88 - path_size - 2); - put_le32(pb, sc->track_type); - put_le32(pb, sc->sample_rate); - put_le32(pb, sc->sample_size); - put_le32(pb, 0); /* reserved */ - switch (sc->codec->codec_id) { - case CODEC_ID_MPEG2VIDEO: - gxf_write_umf_media_mpeg(pb, sc); - break; - case CODEC_ID_PCM_S16LE: - gxf_write_umf_media_audio(pb, sc); - break; - case CODEC_ID_DVVIDEO: - gxf_write_umf_media_dv(pb, sc); - break; - default: - gxf_write_umf_media_timecode(pb, sc); /* 8 0bytes */ - } - curpos = url_ftell(pb); - url_fseek(pb, startpos, SEEK_SET); - put_le16(pb, curpos - startpos); - url_fseek(pb, curpos, SEEK_SET); - } - return url_ftell(pb) - pos; -} - -static int gxf_write_umf_user_data(ByteIOContext *pb, GXFContext *ctx) -{ - offset_t pos = url_ftell(pb); - ctx->umf_user_data_offset = pos - ctx->umf_start_offset; - put_le32(pb, 20); - put_le32(pb, 0); - put_le16(pb, 0); - put_le16(pb, 0); - put_le32(pb, 0); - put_byte(pb, 0); - put_byte(pb, 0); - put_byte(pb, 0); - put_byte(pb, 0); - return 20; -} - -static int gxf_write_umf_packet(ByteIOContext *pb, GXFContext *ctx) -{ - offset_t pos = url_ftell(pb); - - gxf_write_packet_header(pb, PKT_UMF); - - /* preamble */ - put_byte(pb, 3); /* first and last (only) packet */ - put_be32(pb, ctx->umf_length); /* data length */ - - ctx->umf_start_offset = url_ftell(pb); - gxf_write_umf_payload(pb, ctx); - gxf_write_umf_material_description(pb, ctx); - ctx->umf_track_size = gxf_write_umf_track_description(pb, ctx); - ctx->umf_media_size = gxf_write_umf_media_description(pb, ctx); - ctx->umf_user_data_size = gxf_write_umf_user_data(pb, ctx); - ctx->umf_length = url_ftell(pb) - ctx->umf_start_offset; - return updatePacketSize(pb, pos); -} - -static int gxf_write_header(AVFormatContext *s) -{ - ByteIOContext *pb = &s->pb; - GXFContext *gxf = s->priv_data; - int i; - - gxf->fc = s; - gxf->flags |= 0x00080000; /* material is simple clip */ - for (i = 0; i < s->nb_streams; ++i) { - AVStream *st = s->streams[i]; - GXFStreamContext *sc = &gxf->streams[i]; - - sc->codec = st->codec; - sc->index = i; - sc->media_type = codec_get_tag(gxf_media_types, sc->codec->codec_id); - if (st->codec->codec_type == CODEC_TYPE_AUDIO) { - if (st->codec->codec_id != CODEC_ID_PCM_S16LE) { - av_log(s, AV_LOG_ERROR, "only 16 BIT PCM LE allowed for now\n"); - return -1; - } - if (st->codec->sample_rate != 48000) { - av_log(s, AV_LOG_ERROR, "only 48000hz sampling rate is allowed\n"); - return -1; - } - if (st->codec->channels != 1) { - av_log(s, AV_LOG_ERROR, "only mono tracks are allowed\n"); - return -1; - } - sc->track_type = 2; - sc->sample_rate = st->codec->sample_rate; - av_set_pts_info(st, 64, 1, sc->sample_rate); - sc->sample_size = 16; - sc->frame_rate_index = -2; - sc->lines_index = -2; - sc->fields = -2; - gxf->audio_tracks++; - gxf->flags |= 0x04000000; /* audio is 16 bit pcm */ - av_fifo_init(&sc->audio_buffer, 3*GXF_AUDIO_PACKET_SIZE); - } else if (sc->codec->codec_type == CODEC_TYPE_VIDEO) { - /* FIXME check from time_base ? */ - if (sc->codec->height == 480 || sc->codec->height == 512) { /* NTSC or NTSC+VBI */ - sc->frame_rate_index = 5; - sc->sample_rate = 60; - gxf->flags |= 0x00000080; - } else { /* assume PAL */ - sc->frame_rate_index = 6; - sc->media_type++; - sc->sample_rate = 50; - gxf->flags |= 0x00000040; - } - gxf->sample_rate = sc->sample_rate; - av_set_pts_info(st, 64, 1, sc->sample_rate); - if (gxf_find_lines_index(sc) < 0) - sc->lines_index = -1; - sc->sample_size = st->codec->bit_rate; - sc->fields = 2; /* interlaced */ - switch (sc->codec->codec_id) { - case CODEC_ID_MPEG2VIDEO: - sc->first_gop_closed = -1; - sc->track_type = 4; - gxf->mpeg_tracks++; - gxf->flags |= 0x00008000; - break; - case CODEC_ID_DVVIDEO: - if (sc->codec->pix_fmt == PIX_FMT_YUV422P) { - sc->media_type += 2; - sc->track_type = 6; - gxf->flags |= 0x00002000; - } else { - sc->track_type = 5; - gxf->flags |= 0x00001000; - } - break; - default: - av_log(s, AV_LOG_ERROR, "video codec not supported\n"); - return -1; - } - } - } - gxf_write_map_packet(pb, gxf); - //gxf_write_flt_packet(pb, gxf); - gxf_write_umf_packet(pb, gxf); - put_flush_packet(pb); - return 0; -} - -static int gxf_write_eos_packet(ByteIOContext *pb, GXFContext *ctx) -{ - offset_t pos = url_ftell(pb); - - gxf_write_packet_header(pb, PKT_EOS); - return updatePacketSize(pb, pos); -} - -static int gxf_write_trailer(AVFormatContext *s) -{ - ByteIOContext *pb = &s->pb; - GXFContext *gxf = s->priv_data; - offset_t end; - int i; - - for (i = 0; i < s->nb_streams; ++i) { - if (s->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) { - av_fifo_free(&gxf->streams[i].audio_buffer); - } - if (s->streams[i]->codec->frame_number > gxf->nb_frames) - gxf->nb_frames = 2 * s->streams[i]->codec->frame_number; - } - - gxf_write_eos_packet(pb, gxf); - end = url_ftell(pb); - url_fseek(pb, 0, SEEK_SET); - /* overwrite map and umf packets with new values */ - gxf_write_map_packet(pb, gxf); - //gxf_write_flt_packet(pb, gxf); - gxf_write_umf_packet(pb, gxf); - url_fseek(pb, end, SEEK_SET); - return 0; -} - -static int gxf_parse_mpeg_frame(GXFStreamContext *sc, const uint8_t *buf, int size) -{ - uint32_t c=-1; - int i; - for(i=0; i<size-4 && c!=0x100; i++){ - c = (c<<8) + buf[i]; - if(c == 0x1B8 && sc->first_gop_closed == -1) /* GOP start code */ - sc->first_gop_closed= (buf[i+4]>>6)&1; - } - return (buf[i+1]>>3)&7; -} - -static int gxf_write_media_preamble(ByteIOContext *pb, GXFContext *ctx, AVPacket *pkt, int size) -{ - GXFStreamContext *sc = &ctx->streams[pkt->stream_index]; - int64_t dts = av_rescale(pkt->dts, ctx->sample_rate, sc->sample_rate); - - put_byte(pb, sc->media_type); - put_byte(pb, sc->index); - put_be32(pb, dts); - if (sc->codec->codec_type == CODEC_TYPE_AUDIO) { - put_be16(pb, 0); - put_be16(pb, size / 2); - } else if (sc->codec->codec_id == CODEC_ID_MPEG2VIDEO) { - int frame_type = gxf_parse_mpeg_frame(sc, pkt->data, pkt->size); - if (frame_type == FF_I_TYPE) { - put_byte(pb, 0x0d); - sc->iframes++; - } else if (frame_type == FF_B_TYPE) { - put_byte(pb, 0x0f); - sc->bframes++; - } else { - put_byte(pb, 0x0e); - sc->pframes++; - } - put_be24(pb, size); - } else if (sc->codec->codec_id == CODEC_ID_DVVIDEO) { - put_byte(pb, size / 4096); - put_be24(pb, 0); - } else - put_be32(pb, size); - put_be32(pb, dts); - put_byte(pb, 1); /* flags */ - put_byte(pb, 0); /* reserved */ - return 16; -} - -static int gxf_write_media_packet(ByteIOContext *pb, GXFContext *ctx, AVPacket *pkt) -{ - GXFStreamContext *sc = &ctx->streams[pkt->stream_index]; - offset_t pos = url_ftell(pb); - int padding = 0; - - gxf_write_packet_header(pb, PKT_MEDIA); - if (sc->codec->codec_id == CODEC_ID_MPEG2VIDEO && pkt->size % 4) /* MPEG-2 frames must be padded */ - padding = 4 - pkt->size % 4; - else if (sc->codec->codec_type == CODEC_TYPE_AUDIO) - padding = GXF_AUDIO_PACKET_SIZE - pkt->size; - gxf_write_media_preamble(pb, ctx, pkt, pkt->size + padding); - put_buffer(pb, pkt->data, pkt->size); - gxf_write_padding(pb, padding); - return updatePacketSize(pb, pos); -} - -static int gxf_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - GXFContext *gxf = s->priv_data; - - gxf_write_media_packet(&s->pb, gxf, pkt); - put_flush_packet(&s->pb); - return 0; -} - -static int gxf_new_audio_packet(GXFContext *gxf, GXFStreamContext *sc, AVPacket *pkt, int flush) -{ - int size = flush ? av_fifo_size(&sc->audio_buffer) : GXF_AUDIO_PACKET_SIZE; - - if (!size) - return 0; - av_new_packet(pkt, size); - av_fifo_read(&sc->audio_buffer, pkt->data, size); - pkt->stream_index = sc->index; - pkt->dts = sc->current_dts; - sc->current_dts += size / 2; /* we only support 16 bit pcm mono for now */ - return size; -} - -static int gxf_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush) -{ - GXFContext *gxf = s->priv_data; - AVPacket new_pkt; - int i; - - for (i = 0; i < s->nb_streams; i++) { - if (s->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) { - GXFStreamContext *sc = &gxf->streams[i]; - if (pkt && pkt->stream_index == i) { - av_fifo_write(&sc->audio_buffer, pkt->data, pkt->size); - pkt = NULL; - } - if (flush || av_fifo_size(&sc->audio_buffer) >= GXF_AUDIO_PACKET_SIZE) { - if (!pkt && gxf_new_audio_packet(gxf, sc, &new_pkt, flush) > 0) { - pkt = &new_pkt; - break; /* add pkt right now into list */ - } - } - } - } - return av_interleave_packet_per_dts(s, out, pkt, flush); -} - -AVOutputFormat gxf_muxer = { - "gxf", - "GXF format", - NULL, - "gxf", - sizeof(GXFContext), - CODEC_ID_PCM_S16LE, - CODEC_ID_MPEG2VIDEO, - gxf_write_header, - gxf_write_packet, - gxf_write_trailer, - 0, - NULL, - gxf_interleave_packet, -};
--- a/src/ffmpeg/libavformat/ogg.c Mon Mar 12 14:43:32 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,283 +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 - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <stdio.h> - -#include <ogg/ogg.h> - -#include "avformat.h" - -#undef NDEBUG -#include <assert.h> - -#define DECODER_BUFFER_SIZE 4096 - - -typedef struct OggContext { - /* output */ - ogg_stream_state os ; - int header_handled ; - ogg_packet op; - - /* input */ - ogg_sync_state oy ; -} OggContext ; - - -#ifdef CONFIG_MUXERS -static int ogg_write_header(AVFormatContext *avfcontext) -{ - OggContext *context = avfcontext->priv_data; - ogg_packet *op= &context->op; - int n; - - ogg_stream_init(&context->os, 31415); - - for(n = 0 ; n < avfcontext->nb_streams ; n++) { - AVCodecContext *codec = avfcontext->streams[n]->codec; - uint8_t *headers = codec->extradata; - int headers_len = codec->extradata_size; - uint8_t *header_start[3]; - int header_len[3]; - int i, j; - - av_set_pts_info(avfcontext->streams[n], 60, 1, AV_TIME_BASE); - - for(j=1,i=0;i<2;++i, ++j) { - header_len[i]=0; - while(j<headers_len && headers[j]==0xff) { - header_len[i]+=0xff; - ++j; - } - header_len[i]+=headers[j]; - } - header_len[2]=headers_len-header_len[0]-header_len[1]-j; - headers+=j; - header_start[0] = headers; - header_start[1] = header_start[0] + header_len[0]; - header_start[2] = header_start[1] + header_len[1]; - - for(i=0; i < 3; ++i){ - op->bytes = header_len[i]; - - op->packet= header_start[i]; - op->b_o_s= op->packetno==0; - - ogg_stream_packetin(&context->os, op); - - op->packetno++; //FIXME multiple streams - } - - context->header_handled = 0 ; - } - - return 0 ; -} - -static int ogg_write_packet(AVFormatContext *avfcontext, AVPacket *pkt) -{ - OggContext *context = avfcontext->priv_data ; - AVCodecContext *avctx= avfcontext->streams[pkt->stream_index]->codec; - ogg_packet *op= &context->op; - ogg_page og ; - int64_t pts; - - pts= av_rescale(pkt->pts, avctx->sample_rate, AV_TIME_BASE); - -// av_log(avfcontext, AV_LOG_DEBUG, "M%d\n", size); - - /* 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 ; - } - - op->packet = (uint8_t*) pkt->data; - op->bytes = pkt->size; - op->b_o_s = op->packetno == 0; - op->granulepos= pts; - - /* correct the fields in the packet -- essential for streaming */ - - ogg_stream_packetin(&context->os, op); - - 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); - } - op->packetno++; - - 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 ; -} - - -AVOutputFormat ogg_muxer = { - "ogg", - "Ogg Vorbis", - "audio/x-vorbis", - "ogg", - sizeof(OggContext), - CODEC_ID_VORBIS, - 0, - ogg_write_header, - ogg_write_packet, - ogg_write_trailer, -} ; -#endif //CONFIG_MUXERS - -#if 0 -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 = avfcontext->priv_data; - ogg_packet op ; - char *buf ; - ogg_page og ; - AVStream *ast ; - AVCodecContext *codec; - uint8_t *p; - int i; - - 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 AVERROR_IO ; - - 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 ; - av_set_pts_info(ast, 60, 1, AV_TIME_BASE); - - codec= &ast->codec; - codec->codec_type = CODEC_TYPE_AUDIO; - codec->codec_id = CODEC_ID_VORBIS; - for(i=0; i<3; i++){ - if(next_packet(avfcontext, &op)){ - return -1; - } - if(op.bytes >= (1<<16) || op.bytes < 0) - return -1; - codec->extradata_size+= 2 + op.bytes; - codec->extradata= av_realloc(codec->extradata, codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - memset(codec->extradata + codec->extradata_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); - p= codec->extradata + codec->extradata_size - 2 - op.bytes; - *(p++)= op.bytes>>8; - *(p++)= op.bytes&0xFF; - memcpy(p, op.packet, op.bytes); - } - - return 0 ; -} - - -static int ogg_read_packet(AVFormatContext *avfcontext, AVPacket *pkt) { - ogg_packet op ; - - if(next_packet(avfcontext, &op)) - return AVERROR_IO ; - if(av_new_packet(pkt, op.bytes) < 0) - return AVERROR_IO ; - pkt->stream_index = 0 ; - memcpy(pkt->data, op.packet, op.bytes); - if(avfcontext->streams[0]->codec.sample_rate && op.granulepos!=-1) - pkt->pts= av_rescale(op.granulepos, AV_TIME_BASE, avfcontext->streams[0]->codec.sample_rate); -// printf("%lld %d %d\n", pkt->pts, (int)op.granulepos, avfcontext->streams[0]->codec.sample_rate); - - return 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", -} ; -#endif
--- a/src/ffmpeg/libavformat/ogg2.c Mon Mar 12 14:43:32 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,697 +0,0 @@ -/* - * Ogg bitstream support - * Luca Barbato <lu_zero@gentoo.org> - * Based on tcvp implementation - * - */ - -/** - Copyright (C) 2005 Michael Ahlberg, Måns Rullgård - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -**/ - - -#include <stdio.h> -#include "ogg2.h" -#include "avformat.h" - -#define MAX_PAGE_SIZE 65307 -#define DECODER_BUFFER_SIZE MAX_PAGE_SIZE - -static ogg_codec_t *ogg_codecs[] = { - &vorbis_codec, - &theora_codec, - &flac_codec, - &ogm_video_codec, - &ogm_audio_codec, - &ogm_old_codec, - NULL -}; - -#if 0 // CONFIG_MUXERS -static int -ogg_write_header (AVFormatContext * avfcontext) -{ -} - -static int -ogg_write_packet (AVFormatContext * avfcontext, AVPacket * pkt) -{ -} - - -static int -ogg_write_trailer (AVFormatContext * avfcontext) -{ -} - - -AVOutputFormat ogg_muxer = { - "ogg", - "Ogg Vorbis", - "audio/x-vorbis", - "ogg", - sizeof (OggContext), - CODEC_ID_VORBIS, - 0, - ogg_write_header, - ogg_write_packet, - ogg_write_trailer, -}; -#endif //CONFIG_MUXERS - -//FIXME We could avoid some structure duplication -static int -ogg_save (AVFormatContext * s) -{ - ogg_t *ogg = s->priv_data; - ogg_state_t *ost = - av_malloc(sizeof (*ost) + (ogg->nstreams-1) * sizeof (*ogg->streams)); - int i; - ost->pos = url_ftell (&s->pb);; - ost->curidx = ogg->curidx; - ost->next = ogg->state; - memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams)); - - for (i = 0; i < ogg->nstreams; i++){ - ogg_stream_t *os = ogg->streams + i; - os->buf = av_malloc (os->bufsize); - memset (os->buf, 0, os->bufsize); - memcpy (os->buf, ost->streams[i].buf, os->bufpos); - } - - ogg->state = ost; - - return 0; -} - -static int -ogg_restore (AVFormatContext * s, int discard) -{ - ogg_t *ogg = s->priv_data; - ByteIOContext *bc = &s->pb; - ogg_state_t *ost = ogg->state; - int i; - - if (!ost) - return 0; - - ogg->state = ost->next; - - if (!discard){ - for (i = 0; i < ogg->nstreams; i++) - av_free (ogg->streams[i].buf); - - url_fseek (bc, ost->pos, SEEK_SET); - ogg->curidx = ost->curidx; - memcpy (ogg->streams, ost->streams, - ogg->nstreams * sizeof (*ogg->streams)); - } - - av_free (ost); - - return 0; -} - -static int -ogg_reset (ogg_t * ogg) -{ - int i; - - for (i = 0; i < ogg->nstreams; i++){ - ogg_stream_t *os = ogg->streams + i; - os->bufpos = 0; - os->pstart = 0; - os->psize = 0; - os->granule = -1; - os->lastgp = -1; - os->nsegs = 0; - os->segp = 0; - } - - ogg->curidx = -1; - - return 0; -} - -static ogg_codec_t * -ogg_find_codec (uint8_t * buf, int size) -{ - int i; - - for (i = 0; ogg_codecs[i]; i++) - if (size >= ogg_codecs[i]->magicsize && - !memcmp (buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize)) - return ogg_codecs[i]; - - return NULL; -} - -static int -ogg_find_stream (ogg_t * ogg, int serial) -{ - int i; - - for (i = 0; i < ogg->nstreams; i++) - if (ogg->streams[i].serial == serial) - return i; - - return -1; -} - -static int -ogg_new_stream (AVFormatContext * s, uint32_t serial) -{ - - ogg_t *ogg = s->priv_data; - int idx = ogg->nstreams++; - AVStream *st; - ogg_stream_t *os; - - ogg->streams = av_realloc (ogg->streams, - ogg->nstreams * sizeof (*ogg->streams)); - memset (ogg->streams + idx, 0, sizeof (*ogg->streams)); - os = ogg->streams + idx; - os->serial = serial; - os->bufsize = DECODER_BUFFER_SIZE; - os->buf = av_malloc(os->bufsize); - os->header = -1; - - st = av_new_stream (s, idx); - if (!st) - return AVERROR_NOMEM; - - av_set_pts_info(st, 64, 1, 1000000); - - return idx; -} - -static int -ogg_new_buf(ogg_t *ogg, int idx) -{ - ogg_stream_t *os = ogg->streams + idx; - uint8_t *nb = av_malloc(os->bufsize); - int size = os->bufpos - os->pstart; - if(os->buf){ - memcpy(nb, os->buf + os->pstart, size); - av_free(os->buf); - } - os->buf = nb; - os->bufpos = size; - os->pstart = 0; - - return 0; -} - -static int -ogg_read_page (AVFormatContext * s, int *str) -{ - ByteIOContext *bc = &s->pb; - ogg_t *ogg = s->priv_data; - ogg_stream_t *os; - int i = 0; - int flags, nsegs; - uint64_t gp; - uint32_t serial; - uint32_t seq; - uint32_t crc; - int size, idx; - uint8_t sync[4]; - int sp = 0; - - if (get_buffer (bc, sync, 4) < 4) - return -1; - - do{ - int c; - - if (sync[sp & 3] == 'O' && - sync[(sp + 1) & 3] == 'g' && - sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S') - break; - - c = url_fgetc (bc); - if (c < 0) - return -1; - sync[sp++ & 3] = c; - }while (i++ < MAX_PAGE_SIZE); - - if (i >= MAX_PAGE_SIZE){ - av_log (s, AV_LOG_INFO, "ogg, can't find sync word\n"); - return -1; - } - - if (url_fgetc (bc) != 0) /* version */ - return -1; - - flags = url_fgetc (bc); - gp = get_le64 (bc); - serial = get_le32 (bc); - seq = get_le32 (bc); - crc = get_le32 (bc); - nsegs = url_fgetc (bc); - - idx = ogg_find_stream (ogg, serial); - if (idx < 0){ - idx = ogg_new_stream (s, serial); - if (idx < 0) - return -1; - } - - os = ogg->streams + idx; - - if(os->psize > 0) - ogg_new_buf(ogg, idx); - - if (get_buffer (bc, os->segments, nsegs) < nsegs) - return -1; - - os->nsegs = nsegs; - os->segp = 0; - - size = 0; - for (i = 0; i < nsegs; i++) - size += os->segments[i]; - - if (flags & OGG_FLAG_CONT){ - if (!os->psize){ - while (os->segp < os->nsegs){ - int seg = os->segments[os->segp++]; - os->pstart += seg; - if (seg < 255) - break; - } - } - }else{ - os->psize = 0; - } - - if (os->bufsize - os->bufpos < size){ - uint8_t *nb = av_malloc (os->bufsize *= 2); - memcpy (nb, os->buf, os->bufpos); - av_free (os->buf); - os->buf = nb; - } - - if (get_buffer (bc, os->buf + os->bufpos, size) < size) - return -1; - - os->lastgp = os->granule; - os->bufpos += size; - os->granule = gp; - os->flags = flags; - - if (str) - *str = idx; - - return 0; -} - -static int -ogg_packet (AVFormatContext * s, int *str, int *dstart, int *dsize) -{ - ogg_t *ogg = s->priv_data; - int idx; - ogg_stream_t *os; - int complete = 0; - int segp = 0, psize = 0; - -#if 0 - av_log (s, AV_LOG_DEBUG, "ogg_packet: curidx=%i\n", ogg->curidx); -#endif - - do{ - idx = ogg->curidx; - - while (idx < 0){ - if (ogg_read_page (s, &idx) < 0) - return -1; - } - - os = ogg->streams + idx; - -#if 0 - av_log (s, AV_LOG_DEBUG, - "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n", - idx, os->pstart, os->psize, os->segp, os->nsegs); -#endif - - if (!os->codec){ - if (os->header < 0){ - os->codec = ogg_find_codec (os->buf, os->bufpos); - if (!os->codec){ - os->header = 0; - return 0; - } - }else{ - return 0; - } - } - - segp = os->segp; - psize = os->psize; - - while (os->segp < os->nsegs){ - int ss = os->segments[os->segp++]; - os->psize += ss; - if (ss < 255){ - complete = 1; - break; - } - } - - if (!complete && os->segp == os->nsegs){ - ogg->curidx = -1; - } - }while (!complete); - -#if 0 - av_log (s, AV_LOG_DEBUG, - "ogg_packet: idx %i, frame size %i, start %i\n", - idx, os->psize, os->pstart); -#endif - - ogg->curidx = idx; - - if (os->header < 0){ - int hdr = os->codec->header (s, idx); - if (!hdr){ - os->header = os->seq; - os->segp = segp; - os->psize = psize; - ogg->headers = 1; - }else{ - os->pstart += os->psize; - os->psize = 0; - } - } - - if (os->header > -1 && os->seq > os->header){ - if (os->codec && os->codec->packet) - os->codec->packet (s, idx); - if (str) - *str = idx; - if (dstart) - *dstart = os->pstart; - if (dsize) - *dsize = os->psize; - os->pstart += os->psize; - os->psize = 0; - } - - os->seq++; - if (os->segp == os->nsegs) - ogg->curidx = -1; - - return 0; -} - -static int -ogg_get_headers (AVFormatContext * s) -{ - ogg_t *ogg = s->priv_data; - - do{ - if (ogg_packet (s, NULL, NULL, NULL) < 0) - return -1; - }while (!ogg->headers); - -#if 0 - av_log (s, AV_LOG_DEBUG, "found headers\n"); -#endif - - return 0; -} - -static uint64_t -ogg_gptopts (AVFormatContext * s, int i, uint64_t gp) -{ - ogg_t *ogg = s->priv_data; - ogg_stream_t *os = ogg->streams + i; - uint64_t pts = AV_NOPTS_VALUE; - - if(os->codec->gptopts){ - pts = os->codec->gptopts(s, i, gp); - } else { - pts = gp; - } - - return pts; -} - - -static int -ogg_get_length (AVFormatContext * s) -{ - ogg_t *ogg = s->priv_data; - int idx = -1, i; - offset_t size, end; - - if(s->pb.is_streamed) - return 0; - -// already set - if (s->duration != AV_NOPTS_VALUE) - return 0; - - size = url_fsize(&s->pb); - if(size < 0) - return 0; - end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: size; - - ogg_save (s); - url_fseek (&s->pb, end, SEEK_SET); - - while (!ogg_read_page (s, &i)){ - if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0) - idx = i; - } - - if (idx != -1){ - s->streams[idx]->duration = - ogg_gptopts (s, idx, ogg->streams[idx].granule); - } - - ogg->size = size; - ogg_restore (s, 0); - ogg_save (s); - while (!ogg_read_page (s, &i)) { - if (i == idx && ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0) - break; - } - if (i == idx) { - s->streams[idx]->start_time = ogg_gptopts (s, idx, ogg->streams[idx].granule); - s->streams[idx]->duration -= s->streams[idx]->start_time; - } - ogg_restore (s, 0); - - return 0; -} - - -static int -ogg_read_header (AVFormatContext * s, AVFormatParameters * ap) -{ - ogg_t *ogg = s->priv_data; - ogg->curidx = -1; - //linear headers seek from start - if (ogg_get_headers (s) < 0){ - return -1; - } - - //linear granulepos seek from end - ogg_get_length (s); - - //fill the extradata in the per codec callbacks - return 0; -} - - -static int -ogg_read_packet (AVFormatContext * s, AVPacket * pkt) -{ - ogg_t *ogg; - ogg_stream_t *os; - int idx = -1; - int pstart, psize; - - //Get an ogg packet - do{ - if (ogg_packet (s, &idx, &pstart, &psize) < 0) - return AVERROR_IO; - }while (idx < 0 || !s->streams[idx]); - - ogg = s->priv_data; - os = ogg->streams + idx; - - //Alloc a pkt - if (av_new_packet (pkt, psize) < 0) - return AVERROR_IO; - pkt->stream_index = idx; - memcpy (pkt->data, os->buf + pstart, psize); - if (os->lastgp != -1LL){ - pkt->pts = ogg_gptopts (s, idx, os->lastgp); - os->lastgp = -1; - } - - return psize; -} - - -static int -ogg_read_close (AVFormatContext * s) -{ - ogg_t *ogg = s->priv_data; - int i; - - for (i = 0; i < ogg->nstreams; i++){ - av_free (ogg->streams[i].buf); - av_free (ogg->streams[i].private); - } - av_free (ogg->streams); - return 0; -} - - -static int -ogg_read_seek (AVFormatContext * s, int stream_index, int64_t target_ts, - int flags) -{ - AVStream *st = s->streams[stream_index]; - ogg_t *ogg = s->priv_data; - ByteIOContext *bc = &s->pb; - uint64_t min = 0, max = ogg->size; - uint64_t tmin = st->start_time, tmax = st->start_time + st->duration; - int64_t pts = AV_NOPTS_VALUE; - - ogg_save (s); - - if ((uint64_t)target_ts < tmin || target_ts < 0) - target_ts = tmin; - while (min <= max && tmin < tmax){ - uint64_t p = min + (max - min) * (target_ts - tmin) / (tmax - tmin); - int i = -1; - - url_fseek (bc, p, SEEK_SET); - - while (!ogg_read_page (s, &i)){ - if (i == stream_index && ogg->streams[i].granule != 0 && - ogg->streams[i].granule != -1) - break; - } - - if (i == -1) - break; - - pts = ogg_gptopts (s, i, ogg->streams[i].granule); - p = url_ftell (bc); - - if (FFABS (pts - target_ts) * st->time_base.num < st->time_base.den) - break; - - if (pts > target_ts){ - if (max == p && tmax == pts) { - // probably our tmin is wrong, causing us to always end up too late in the file - tmin = (target_ts + tmin + 1) / 2; - if (tmin == target_ts) { - url_fseek(bc, min, SEEK_SET); - break; - } - } - max = p; - tmax = pts; - }else{ - if (min == p && tmin == pts) { - // probably our tmax is wrong, causing us to always end up too early in the file - tmax = (target_ts + tmax) / 2; - if (tmax == target_ts) { - url_fseek(bc, max, SEEK_SET); - break; - } - } - min = p; - tmin = pts; - } - } - - if (FFABS (pts - target_ts) * st->time_base.num < st->time_base.den){ - ogg_restore (s, 1); - ogg_reset (ogg); - }else{ - ogg_restore (s, 0); - pts = AV_NOPTS_VALUE; - } - - av_update_cur_dts(s, st, pts); - return 0; - -#if 0 - //later... - int64_t pos; - if (av_seek_frame_binary (s, stream_index, target_ts, flags) < 0) - return -1; - pos = url_ftell (&s->pb); - ogg_read_timestamp (s, stream_index, &pos, pos - 1); -#endif - -} - -#if 0 -static int64_t -ogg_read_timestamp (AVFormatContext * s, int stream_index, int64_t * pos_arg, - int64_t pos_limit) -{ - ogg_t *ogg = s->priv_data; - ByteIOContext *bc = &s->pb; - int64_t pos, pts; - - if (*pos_arg < 0) - return AV_NOPTS_VALUE; - - pos = *pos_arg; -} -#endif - -static int ogg_probe(AVProbeData *p) -{ - if (p->buf_size < 6) - return 0; - if (p->buf[0] == 'O' && p->buf[1] == 'g' && - p->buf[2] == 'g' && p->buf[3] == 'S' && - p->buf[4] == 0x0 && p->buf[5] <= 0x7 ) - return AVPROBE_SCORE_MAX; - else - return 0; -} - -AVInputFormat ogg_demuxer = { - "ogg", - "Ogg", - sizeof (ogg_t), - ogg_probe, - ogg_read_header, - ogg_read_packet, - ogg_read_close, - ogg_read_seek, -// ogg_read_timestamp, - .extensions = "ogg", -};
--- a/src/ffmpeg/libavformat/ogg2.h Mon Mar 12 14:43:32 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +0,0 @@ -/** - Copyright (C) 2005 Michael Ahlberg, Måns Rullgård - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -**/ - -#ifndef OGG_H -#define OGG_H - -#include "avformat.h" - -typedef struct ogg_codec { - int8_t *magic; - uint8_t magicsize; - int8_t *name; - int (*header)(AVFormatContext *, int); - int (*packet)(AVFormatContext *, int); - uint64_t (*gptopts)(AVFormatContext *, int, uint64_t); -} ogg_codec_t; - -typedef struct ogg_stream { - uint8_t *buf; - unsigned int bufsize; - unsigned int bufpos; - unsigned int pstart; - unsigned int psize; - uint32_t serial; - uint32_t seq; - uint64_t granule, lastgp; - int flags; - ogg_codec_t *codec; - int header; - int nsegs, segp; - uint8_t segments[255]; - void *private; -} ogg_stream_t; - -typedef struct ogg_state { - uint64_t pos; - int curidx; - struct ogg_state *next; - ogg_stream_t streams[1]; -} ogg_state_t; - -typedef struct ogg { - ogg_stream_t *streams; - int nstreams; - int headers; - int curidx; - uint64_t size; - ogg_state_t *state; -} ogg_t; - -#define OGG_FLAG_CONT 1 -#define OGG_FLAG_BOS 2 -#define OGG_FLAG_EOS 4 - -extern ogg_codec_t vorbis_codec; -extern ogg_codec_t theora_codec; -extern ogg_codec_t flac_codec; -extern ogg_codec_t ogm_video_codec; -extern ogg_codec_t ogm_audio_codec; -extern ogg_codec_t ogm_old_codec; - -extern int vorbis_comment(AVFormatContext *ms, uint8_t *buf, int size); - -#endif
--- a/src/ffmpeg/libavformat/oggparseflac.c Mon Mar 12 14:43:32 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2005 Matthieu CASTET - * - * This file is part of FFmpeg. - * - * FFmpeg 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.1 of the License, or (at your option) any later version. - * - * FFmpeg 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 FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <stdlib.h> -#include "avformat.h" -#include "bitstream.h" -#include "ogg2.h" - -#define FLAC_STREAMINFO_SIZE 0x22 - -static int -flac_header (AVFormatContext * s, int idx) -{ - ogg_t *ogg = s->priv_data; - ogg_stream_t *os = ogg->streams + idx; - AVStream *st = s->streams[idx]; - GetBitContext gb; - int mdt; - - if (os->buf[os->pstart] == 0xff) - return 0; - - init_get_bits(&gb, os->buf + os->pstart, os->psize*8); - get_bits(&gb, 1); /* metadata_last */ - mdt = get_bits(&gb, 7); - - if (mdt == 0x7f) { - skip_bits(&gb, 4*8); /* "FLAC" */ - if(get_bits(&gb, 8) != 1) /* unsupported major version */ - return -1; - skip_bits(&gb, 8 + 16); /* minor version + header count */ - skip_bits(&gb, 4*8); /* "fLaC" */ - - /* METADATA_BLOCK_HEADER */ - if (get_bits(&gb, 32) != FLAC_STREAMINFO_SIZE) - return -1; - - skip_bits(&gb, 16*2+24*2); - - st->codec->sample_rate = get_bits_long(&gb, 20); - st->codec->channels = get_bits(&gb, 3) + 1; - - st->codec->codec_type = CODEC_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_FLAC; - - st->codec->extradata = - av_malloc(FLAC_STREAMINFO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); - memcpy (st->codec->extradata, os->buf + os->pstart + 5 + 4 + 4 + 4, - FLAC_STREAMINFO_SIZE); - st->codec->extradata_size = FLAC_STREAMINFO_SIZE; - - st->time_base.num = 1; - st->time_base.den = st->codec->sample_rate; - } else if (mdt == 4) { - vorbis_comment (s, os->buf + os->pstart + 4, os->psize - 4); - } - - return 1; -} - -ogg_codec_t flac_codec = { - .magic = "\177FLAC", - .magicsize = 5, - .header = flac_header -};
--- a/src/ffmpeg/libavformat/oggparseogm.c Mon Mar 12 14:43:32 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,166 +0,0 @@ -/** - Copyright (C) 2005 Michael Ahlberg, Måns Rullgård - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -**/ - -#include <stdlib.h> -#include "avformat.h" -#include "bitstream.h" -#include "bswap.h" -#include "ogg2.h" -#include "riff.h" - -static int -ogm_header(AVFormatContext *s, int idx) -{ - ogg_t *ogg = s->priv_data; - ogg_stream_t *os = ogg->streams + idx; - AVStream *st = s->streams[idx]; - uint8_t *p = os->buf + os->pstart; - uint64_t time_unit; - uint64_t spu; - uint32_t default_len; - - if(!(*p & 1)) - return 0; - if(*p != 1) - return 1; - - p++; - - if(*p == 'v'){ - int tag; - st->codec->codec_type = CODEC_TYPE_VIDEO; - p += 8; - tag = le2me_32(unaligned32(p)); - st->codec->codec_id = codec_get_bmp_id(tag); - st->codec->codec_tag = tag; - } else { - int cid; - st->codec->codec_type = CODEC_TYPE_AUDIO; - p += 8; - p[4] = 0; - cid = strtol(p, NULL, 16); - st->codec->codec_id = codec_get_wav_id(cid); - } - - p += 4; - p += 4; /* useless size field */ - - time_unit = le2me_64(unaligned64(p)); - p += 8; - spu = le2me_64(unaligned64(p)); - p += 8; - default_len = le2me_32(unaligned32(p)); - p += 4; - - p += 8; /* buffersize + bits_per_sample */ - - if(st->codec->codec_type == CODEC_TYPE_VIDEO){ - st->codec->width = le2me_32(unaligned32(p)); - p += 4; - st->codec->height = le2me_32(unaligned32(p)); - st->codec->time_base.den = spu * 10000000; - st->codec->time_base.num = time_unit; - st->time_base = st->codec->time_base; - } else { - st->codec->channels = le2me_16(unaligned16(p)); - p += 2; - p += 2; /* block_align */ - st->codec->bit_rate = le2me_32(unaligned32(p)) * 8; - st->codec->sample_rate = spu * 10000000 / time_unit; - st->time_base.num = 1; - st->time_base.den = st->codec->sample_rate; - } - - return 1; -} - -static int -ogm_dshow_header(AVFormatContext *s, int idx) -{ - ogg_t *ogg = s->priv_data; - ogg_stream_t *os = ogg->streams + idx; - AVStream *st = s->streams[idx]; - uint8_t *p = os->buf + os->pstart; - uint32_t t; - - if(!(*p & 1)) - return 0; - if(*p != 1) - return 1; - - t = le2me_32(unaligned32(p + 96)); - - if(t == 0x05589f80){ - st->codec->codec_type = CODEC_TYPE_VIDEO; - st->codec->codec_id = codec_get_bmp_id(le2me_32(unaligned32(p + 68))); - st->codec->time_base.den = 10000000; - st->codec->time_base.num = le2me_64(unaligned64(p + 164)); - st->codec->width = le2me_32(unaligned32(p + 176)); - st->codec->height = le2me_32(unaligned32(p + 180)); - } else if(t == 0x05589f81){ - st->codec->codec_type = CODEC_TYPE_AUDIO; - st->codec->codec_id = codec_get_wav_id(le2me_16(unaligned16(p+124))); - st->codec->channels = le2me_16(unaligned16(p + 126)); - st->codec->sample_rate = le2me_32(unaligned32(p + 128)); - st->codec->bit_rate = le2me_32(unaligned32(p + 132)) * 8; - } - - return 1; -} - -static int -ogm_packet(AVFormatContext *s, int idx) -{ - ogg_t *ogg = s->priv_data; - ogg_stream_t *os = ogg->streams + idx; - uint8_t *p = os->buf + os->pstart; - int lb; - - lb = ((*p & 2) << 1) | ((*p >> 6) & 3); - os->pstart += lb + 1; - os->psize -= lb + 1; - - return 0; -} - -ogg_codec_t ogm_video_codec = { - .magic = "\001video", - .magicsize = 6, - .header = ogm_header, - .packet = ogm_packet -}; - -ogg_codec_t ogm_audio_codec = { - .magic = "\001audio", - .magicsize = 6, - .header = ogm_header, - .packet = ogm_packet -}; - -ogg_codec_t ogm_old_codec = { - .magic = "\001Direct Show Samples embedded in Ogg", - .magicsize = 35, - .header = ogm_dshow_header, - .packet = ogm_packet -};
--- a/src/ffmpeg/libavformat/oggparsetheora.c Mon Mar 12 14:43:32 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,129 +0,0 @@ -/** - Copyright (C) 2005 Matthieu CASTET, Alex Beregszaszi - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -**/ - -#include <stdlib.h> -#include "avformat.h" -#include "bitstream.h" -#include "bswap.h" -#include "ogg2.h" - -typedef struct theora_params { - int gpshift; - int gpmask; -} theora_params_t; - -static int -theora_header (AVFormatContext * s, int idx) -{ - ogg_t *ogg = s->priv_data; - ogg_stream_t *os = ogg->streams + idx; - AVStream *st = s->streams[idx]; - theora_params_t *thp = os->private; - int cds = st->codec->extradata_size + os->psize + 2; - uint8_t *cdp; - - if(!(os->buf[os->pstart] & 0x80)) - return 0; - - if(!thp){ - thp = av_mallocz(sizeof(*thp)); - os->private = thp; - } - - if (os->buf[os->pstart] == 0x80) { - GetBitContext gb; - int version; - - init_get_bits(&gb, os->buf + os->pstart, os->psize*8); - - skip_bits(&gb, 7*8); /* 0x80"theora" */ - - version = get_bits(&gb, 8) << 16; - version |= get_bits(&gb, 8) << 8; - version |= get_bits(&gb, 8); - - if (version < 0x030100) - { - av_log(s, AV_LOG_ERROR, - "Too old or unsupported Theora (%x)\n", version); - return -1; - } - - st->codec->width = get_bits(&gb, 16) << 4; - st->codec->height = get_bits(&gb, 16) << 4; - - if (version >= 0x030400) - skip_bits(&gb, 164); - else if (version >= 0x030200) - skip_bits(&gb, 64); - st->codec->time_base.den = get_bits(&gb, 32); - st->codec->time_base.num = get_bits(&gb, 32); - st->time_base = st->codec->time_base; - - st->codec->sample_aspect_ratio.num = get_bits(&gb, 24); - st->codec->sample_aspect_ratio.den = get_bits(&gb, 24); - - if (version >= 0x030200) - skip_bits(&gb, 38); - if (version >= 0x304000) - skip_bits(&gb, 2); - - thp->gpshift = get_bits(&gb, 5); - thp->gpmask = (1 << thp->gpshift) - 1; - - st->codec->codec_type = CODEC_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_THEORA; - - } else if (os->buf[os->pstart] == 0x83) { - vorbis_comment (s, os->buf + os->pstart + 7, os->psize - 8); - } - - st->codec->extradata = av_realloc (st->codec->extradata, cds); - cdp = st->codec->extradata + st->codec->extradata_size; - *cdp++ = os->psize >> 8; - *cdp++ = os->psize & 0xff; - memcpy (cdp, os->buf + os->pstart, os->psize); - st->codec->extradata_size = cds; - - return 1; -} - -static uint64_t -theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp) -{ - ogg_t *ogg = ctx->priv_data; - ogg_stream_t *os = ogg->streams + idx; - theora_params_t *thp = os->private; - uint64_t iframe = gp >> thp->gpshift; - uint64_t pframe = gp & thp->gpmask; - - return iframe + pframe; -} - -ogg_codec_t theora_codec = { - .magic = "\200theora", - .magicsize = 7, - .header = theora_header, - .gptopts = theora_gptopts -};
--- a/src/ffmpeg/libavformat/oggparsevorbis.c Mon Mar 12 14:43:32 2007 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,205 +0,0 @@ -/** - Copyright (C) 2005 Michael Ahlberg, Måns Rullgård - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -**/ - -#include <stdlib.h> -#include "avformat.h" -#include "bitstream.h" -#include "bswap.h" -#include "ogg2.h" - -extern int -vorbis_comment (AVFormatContext * as, uint8_t *buf, int size) -{ - char *p = buf; - int s, n, j; - - if (size < 4) - return -1; - - s = le2me_32 (unaligned32 (p)); - p += 4; - size -= 4; - - if (size < s + 4) - return -1; - - p += s; - size -= s; - - n = le2me_32 (unaligned32 (p)); - p += 4; - size -= 4; - - while (size >= 4){ - char *t, *v; - int tl, vl; - - s = le2me_32 (unaligned32 (p)); - p += 4; - size -= 4; - - if (size < s) - break; - - t = p; - p += s; - size -= s; - n--; - - v = memchr (t, '=', s); - if (!v) - continue; - - tl = v - t; - vl = s - tl - 1; - v++; - - if (tl && vl){ - char tt[tl + 1]; - char ct[vl + 1]; - - for (j = 0; j < tl; j++) - tt[j] = toupper (t[j]); - tt[tl] = 0; - - memcpy (ct, v, vl); - ct[vl] = 0; - - // took from Vorbis_I_spec - if (!strcmp (tt, "AUTHOR")) - strncpy (as->author, ct, FFMIN(sizeof (as->author), vl)); - else if (!strcmp (tt, "TITLE")) - strncpy (as->title, ct, FFMIN(sizeof (as->title), vl)); - else if (!strcmp (tt, "COPYRIGHT")) - strncpy (as->copyright, ct, FFMIN(sizeof (as->copyright), vl)); - else if (!strcmp (tt, "DESCRIPTION")) - strncpy (as->comment, ct, FFMIN(sizeof (as->comment), vl)); - else if (!strcmp (tt, "GENRE")) - strncpy (as->genre, ct, FFMIN(sizeof (as->genre), vl)); - else if (!strcmp (tt, "TRACKNUMBER")) - as->track = atoi (ct); - //Too bored to add others for today - } - } - - if (size > 0) - av_log (as, AV_LOG_INFO, "%i bytes of comment header remain\n", size); - if (n > 0) - av_log (as, AV_LOG_INFO, - "truncated comment header, %i comments not found\n", n); - - return 0; -} - - -/** Parse the vorbis header - * Vorbis Identification header from Vorbis_I_spec.html#vorbis-spec-codec - * [vorbis_version] = read 32 bits as unsigned integer | Not used - * [audio_channels] = read 8 bit integer as unsigned | Used - * [audio_sample_rate] = read 32 bits as unsigned integer | Used - * [bitrate_maximum] = read 32 bits as signed integer | Not used yet - * [bitrate_nominal] = read 32 bits as signed integer | Not used yet - * [bitrate_minimum] = read 32 bits as signed integer | Used as bitrate - * [blocksize_0] = read 4 bits as unsigned integer | Not Used - * [blocksize_1] = read 4 bits as unsigned integer | Not Used - * [framing_flag] = read one bit | Not Used - * */ - -typedef struct { - unsigned int len[3]; - unsigned char *packet[3]; -} oggvorbis_private_t; - - -static unsigned int -fixup_vorbis_headers(AVFormatContext * as, oggvorbis_private_t *priv, - void **buf) -{ - int i,offset, len; - unsigned char *ptr; - - len = priv->len[0] + priv->len[1] + priv->len[2]; - ptr = *buf = av_mallocz(len + len/255 + 64); - - ptr[0] = 2; - offset = 1; - offset += av_xiphlacing(&ptr[offset], priv->len[0]); - offset += av_xiphlacing(&ptr[offset], priv->len[1]); - for(i = 0; i < 3; i++) { - memcpy(&ptr[offset], priv->packet[i], priv->len[i]); - offset += priv->len[i]; - } - *buf = av_realloc(*buf, offset); - return offset; -} - - -static int -vorbis_header (AVFormatContext * s, int idx) -{ - ogg_t *ogg = s->priv_data; - ogg_stream_t *os = ogg->streams + idx; - AVStream *st = s->streams[idx]; - oggvorbis_private_t *priv; - - if (os->seq > 2) - return 0; - - if(os->seq == 0) { - os->private = av_mallocz(sizeof(oggvorbis_private_t)); - if(!os->private) - return 0; - } - - priv = os->private; - priv->len[os->seq] = os->psize; - priv->packet[os->seq] = av_mallocz(os->psize); - memcpy(priv->packet[os->seq], os->buf + os->pstart, os->psize); - if (os->buf[os->pstart] == 1) { - uint8_t *p = os->buf + os->pstart + 11; //skip up to the audio channels - st->codec->channels = *p++; - st->codec->sample_rate = le2me_32 (unaligned32 (p)); - p += 8; //skip maximum and and nominal bitrate - st->codec->bit_rate = le2me_32 (unaligned32 (p)); //Minimum bitrate - - st->codec->codec_type = CODEC_TYPE_AUDIO; - st->codec->codec_id = CODEC_ID_VORBIS; - - st->time_base.num = 1; - st->time_base.den = st->codec->sample_rate; - } else if (os->buf[os->pstart] == 3) { - vorbis_comment (s, os->buf + os->pstart + 7, os->psize - 8); - } else { - st->codec->extradata_size = - fixup_vorbis_headers(s, priv, &st->codec->extradata); - } - - return os->seq < 3; -} - -ogg_codec_t vorbis_codec = { - .magic = "\001vorbis", - .magicsize = 7, - .header = vorbis_header -};