⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 avienc.c.svn-base

📁 mediastreamer2是开源的网络传输媒体流的库
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
/* * AVI muxer * Copyright (c) 2000 Fabrice Bellard. * * 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 "avi.h"#include "riff.h"/* * TODO: *  - fill all fields if non streamed (nb_frames for example) */#ifdef CONFIG_AVI_MUXERtypedef struct AVIIentry {    unsigned int flags, pos, len;} AVIIentry;#define AVI_INDEX_CLUSTER_SIZE 16384typedef struct AVIIndex {    offset_t    indx_start;    int         entry;    int         ents_allocated;    AVIIentry** cluster;} AVIIndex;typedef struct {    offset_t riff_start, movi_list, odml_list;    offset_t frames_hdr_all, frames_hdr_strm[MAX_STREAMS];    int audio_strm_length[MAX_STREAMS];    int riff_id;    int packet_count[MAX_STREAMS];    AVIIndex indexes[MAX_STREAMS];} AVIContext;static inline AVIIentry* avi_get_ientry(AVIIndex* idx, int ent_id){    int cl = ent_id / AVI_INDEX_CLUSTER_SIZE;    int id = ent_id % AVI_INDEX_CLUSTER_SIZE;    return &idx->cluster[cl][id];}static offset_t avi_start_new_riff(AVIContext *avi, ByteIOContext *pb,                                   const char* riff_tag, const char* list_tag){    offset_t loff;    int i;    avi->riff_id++;    for (i=0; i<MAX_STREAMS; i++)         avi->indexes[i].entry = 0;    avi->riff_start = start_tag(pb, "RIFF");    put_tag(pb, riff_tag);    loff = start_tag(pb, "LIST");    put_tag(pb, list_tag);    return loff;}static char* avi_stream2fourcc(char* tag, int index, enum CodecType type){    tag[0] = '0';    tag[1] = '0' + index;    if (type == CODEC_TYPE_VIDEO) {        tag[2] = 'd';        tag[3] = 'c';    } else {        tag[2] = 'w';        tag[3] = 'b';    }    tag[4] = '\0';    return tag;}static void avi_write_info_tag(ByteIOContext *pb, const char *tag, const char *str){    int len = strlen(str);    if (len > 0) {        len++;        put_tag(pb, tag);        put_le32(pb, len);        put_strz(pb, str);        if (len & 1)            put_byte(pb, 0);    }}static int avi_write_counters(AVFormatContext* s, int riff_id){    ByteIOContext *pb = s->pb;    AVIContext *avi = s->priv_data;    int n, au_byterate, au_ssize, au_scale, nb_frames = 0;    offset_t file_size;    AVCodecContext* stream;    file_size = url_ftell(pb);    for(n = 0; n < s->nb_streams; n++) {        assert(avi->frames_hdr_strm[n]);        stream = s->streams[n]->codec;        url_fseek(pb, avi->frames_hdr_strm[n], SEEK_SET);        ff_parse_specific_params(stream, &au_byterate, &au_ssize, &au_scale);        if(au_ssize == 0) {            put_le32(pb, avi->packet_count[n]);        } else {            put_le32(pb, avi->audio_strm_length[n] / au_ssize);        }        if(stream->codec_type == CODEC_TYPE_VIDEO)            nb_frames = FFMAX(nb_frames, avi->packet_count[n]);    }    if(riff_id == 1) {        assert(avi->frames_hdr_all);        url_fseek(pb, avi->frames_hdr_all, SEEK_SET);        put_le32(pb, nb_frames);    }    url_fseek(pb, file_size, SEEK_SET);    return 0;}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;    /* header list */    avi->riff_id = 0;    list1 = avi_start_new_riff(avi, pb, "AVI ", "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;    }    nb_frames = 0;    if(video_enc){        put_le32(pb, (uint32_t)(INT64_C(1000000) * video_enc->time_base.num / video_enc->time_base.den));    } else {        put_le32(pb, 0);    }    put_le32(pb, bitrate / 8); /* XXX: not quite exact */    put_le32(pb, 0); /* padding */    if (url_is_streamed(pb))        put_le32(pb, AVIF_TRUSTCKTYPE | AVIF_ISINTERLEAVED); /* flags */    else        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 */    if(video_enc){        put_le32(pb, video_enc->width);        put_le32(pb, video_enc->height);    } else {        put_le32(pb, 0);        put_le32(pb, 0);    }    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"); break;        case CODEC_TYPE_AUDIO: put_tag(pb, "auds"); break;//        case CODEC_TYPE_TEXT : put_tag(pb, "txts"); break;        case CODEC_TYPE_DATA : put_tag(pb, "dats"); break;        }        if(stream->codec_type == CODEC_TYPE_VIDEO)            put_le32(pb, stream->codec_tag);        else            put_le32(pb, 1);        put_le32(pb, 0); /* flags */        put_le16(pb, 0); /* priority */        put_le16(pb, 0); /* language */        put_le32(pb, 0); /* initial frame */        ff_parse_specific_params(stream, &au_byterate, &au_ssize, &au_scale);        put_le32(pb, au_scale); /* scale */        put_le32(pb, au_byterate); /* rate */        av_set_pts_info(s->streams[i], 64, au_scale, au_byterate);        put_le32(pb, 0); /* start */        avi->frames_hdr_strm[i] = url_ftell(pb); /* remember this offset to fill later */        if (url_is_streamed(pb))            put_le32(pb, AVI_MAX_RIFF_SIZE); /* FIXME: this may be broken, but who cares */        else            put_le32(pb, 0); /* length, XXX: filled later */        /* suggested buffer size */ //FIXME set at the end to largest chunk        if(stream->codec_type == CODEC_TYPE_VIDEO)            put_le32(pb, 1024 * 1024);        else if(stream->codec_type == CODEC_TYPE_AUDIO)            put_le32(pb, 12 * 1024);        else            put_le32(pb, 0);        put_le32(pb, -1); /* quality */        put_le32(pb, au_ssize); /* sample size */        put_le32(pb, 0);        put_le16(pb, stream->width);        put_le16(pb, stream->height);        end_tag(pb, strh);      if(stream->codec_type != CODEC_TYPE_DATA){        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:            return -1;        }        end_tag(pb, strf);      }        if (!url_is_streamed(pb)) {            unsigned char tag[5];            int j;            /* Starting to lay out AVI OpenDML master index.             * We want to make it JUNK entry for now, since we'd             * like to get away without making AVI an OpenDML one             * for compatibility reasons.             */            avi->indexes[i].entry = avi->indexes[i].ents_allocated = 0;            avi->indexes[i].indx_start = start_tag(pb, "JUNK");            put_le16(pb, 4);        /* wLongsPerEntry */            put_byte(pb, 0);        /* bIndexSubType (0 == frame index) */            put_byte(pb, 0);        /* bIndexType (0 == AVI_INDEX_OF_INDEXES) */            put_le32(pb, 0);        /* nEntriesInUse (will fill out later on) */            put_tag(pb, avi_stream2fourcc(&tag[0], i, stream->codec_type));                                    /* dwChunkId */            put_le64(pb, 0);        /* dwReserved[3]            put_le32(pb, 0);           Must be 0.    */            for (j=0; j < AVI_MASTER_INDEX_SIZE * 2; j++)                 put_le64(pb, 0);            end_tag(pb, avi->indexes[i].indx_start);        }        end_tag(pb, list2);    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -