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

📄 movenc.c.svn-base

📁 mediastreamer2是开源的网络传输媒体流的库
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
        url_fseek(pb, pos, SEEK_SET);        put_be32(pb, size);        url_fseek(pb, pos+24, SEEK_SET);        put_be32(pb, size-24);        url_fseek(pb, curpos, SEEK_SET);    }    return size;not_utf8:    av_log(s, AV_LOG_ERROR, "not utf8\n");    return -1;}static int mov_write_moov_tag(ByteIOContext *pb, MOVContext *mov,                              AVFormatContext *s){    int i;    offset_t pos = url_ftell(pb);    put_be32(pb, 0); /* size placeholder*/    put_tag(pb, "moov");    mov->timescale = globalTimescale;    for (i=0; i<mov->nb_streams; i++) {        if(mov->tracks[i].entry <= 0) continue;        mov->tracks[i].time = mov->time;        mov->tracks[i].trackID = i+1;    }    mov_write_mvhd_tag(pb, mov);    //mov_write_iods_tag(pb, mov);    for (i=0; i<mov->nb_streams; i++) {        if(mov->tracks[i].entry > 0) {            mov_write_trak_tag(pb, &(mov->tracks[i]));        }    }    if (mov->mode == MODE_PSP)        mov_write_uuidusmt_tag(pb, s);    else if (mov->mode != MODE_3GP && mov->mode != MODE_3G2)        mov_write_udta_tag(pb, mov, s);    return updateSize(pb, pos);}static int mov_write_mdat_tag(ByteIOContext *pb, MOVContext* mov){    put_be32(pb, 8);    // placeholder for extended size field (64 bit)    put_tag(pb, mov->mode == MODE_MOV ? "wide" : "free");    mov->mdat_pos = url_ftell(pb);    put_be32(pb, 0); /* size placeholder*/    put_tag(pb, "mdat");    return 0;}/* TODO: This needs to be more general */static void mov_write_ftyp_tag (ByteIOContext *pb, AVFormatContext *s){    MOVContext *mov = s->priv_data;    put_be32(pb, 0x14); /* size */    put_tag(pb, "ftyp");    if (mov->mode == MODE_3GP)        put_tag(pb, "3gp4");    else if (mov->mode == MODE_3G2)        put_tag(pb, "3g2a");    else if (mov->mode == MODE_PSP)        put_tag(pb, "MSNV");    else if (mov->mode == MODE_MP4)        put_tag(pb, "isom");    else        put_tag(pb, "qt  ");    put_be32(pb, 0x200);    if (mov->mode == MODE_3GP)        put_tag(pb, "3gp4");    else if (mov->mode == MODE_3G2)        put_tag(pb, "3g2a");    else if (mov->mode == MODE_PSP)        put_tag(pb, "MSNV");    else if (mov->mode == MODE_MP4)        put_tag(pb, "mp41");    else        put_tag(pb, "qt  ");}static void mov_write_uuidprof_tag(ByteIOContext *pb, AVFormatContext *s){    AVCodecContext *VideoCodec = s->streams[0]->codec;    AVCodecContext *AudioCodec = s->streams[1]->codec;    int AudioRate = AudioCodec->sample_rate;    int FrameRate = ((VideoCodec->time_base.den) * (0x10000))/ (VideoCodec->time_base.num);    int audio_kbitrate= AudioCodec->bit_rate / 1000;    int video_kbitrate= FFMIN(VideoCodec->bit_rate / 1000, 800 - audio_kbitrate);    put_be32(pb, 0x94); /* size */    put_tag(pb, "uuid");    put_tag(pb, "PROF");    put_be32(pb, 0x21d24fce); /* 96 bit UUID */    put_be32(pb, 0xbb88695c);    put_be32(pb, 0xfac9c740);    put_be32(pb, 0x0);  /* ? */    put_be32(pb, 0x3);  /* 3 sections ? */    put_be32(pb, 0x14); /* size */    put_tag(pb, "FPRF");    put_be32(pb, 0x0);  /* ? */    put_be32(pb, 0x0);  /* ? */    put_be32(pb, 0x0);  /* ? */    put_be32(pb, 0x2c);  /* size */    put_tag(pb, "APRF");   /* audio */    put_be32(pb, 0x0);    put_be32(pb, 0x2);   /* TrackID */    put_tag(pb, "mp4a");    put_be32(pb, 0x20f);    put_be32(pb, 0x0);    put_be32(pb, audio_kbitrate);    put_be32(pb, audio_kbitrate);    put_be32(pb, AudioRate);    put_be32(pb, AudioCodec->channels);    put_be32(pb, 0x34);  /* size */    put_tag(pb, "VPRF");   /* video */    put_be32(pb, 0x0);    put_be32(pb, 0x1);    /* TrackID */    if (VideoCodec->codec_id == CODEC_ID_H264) {        put_tag(pb, "avc1");        put_be16(pb, 0x014D);        put_be16(pb, 0x0015);    } else {        put_tag(pb, "mp4v");        put_be16(pb, 0x0000);        put_be16(pb, 0x0103);    }    put_be32(pb, 0x0);    put_be32(pb, video_kbitrate);    put_be32(pb, video_kbitrate);    put_be32(pb, FrameRate);    put_be32(pb, FrameRate);    put_be16(pb, VideoCodec->width);    put_be16(pb, VideoCodec->height);    put_be32(pb, 0x010001); /* ? */}static int mov_write_header(AVFormatContext *s){    ByteIOContext *pb = s->pb;    MOVContext *mov = s->priv_data;    int i;    if (url_is_streamed(s->pb)) {        av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");        return -1;    }    /* Default mode == MP4 */    mov->mode = MODE_MP4;    if (s->oformat != NULL) {        if (!strcmp("3gp", s->oformat->name)) mov->mode = MODE_3GP;        else if (!strcmp("3g2", s->oformat->name)) mov->mode = MODE_3G2;        else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV;        else if (!strcmp("psp", s->oformat->name)) mov->mode = MODE_PSP;        mov_write_ftyp_tag(pb,s);        if (mov->mode == MODE_PSP) {            if (s->nb_streams != 2) {                av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n");                return -1;            }            mov_write_uuidprof_tag(pb,s);        }    }    for(i=0; i<s->nb_streams; i++){        AVStream *st= s->streams[i];        MOVTrack *track= &mov->tracks[i];        track->enc = st->codec;        track->language = ff_mov_iso639_to_lang(st->language, mov->mode != MODE_MOV);        track->mode = mov->mode;        track->tag = mov_find_codec_tag(s, track);        if (!track->tag) {            av_log(s, AV_LOG_ERROR, "track %d: could not find tag for codec\n", i);            return -1;        }        if(st->codec->codec_type == CODEC_TYPE_VIDEO){            track->timescale = st->codec->time_base.den;            av_set_pts_info(st, 64, 1, st->codec->time_base.den);            if (track->mode == MODE_MOV && track->timescale > 100000)                av_log(s, AV_LOG_WARNING,                       "WARNING codec timebase is very high. If duration is too long,\n"                       "file may not be playable by quicktime. Specify a shorter timebase\n"                       "or choose different container.\n");        }else if(st->codec->codec_type == CODEC_TYPE_AUDIO){            track->timescale = st->codec->sample_rate;            av_set_pts_info(st, 64, 1, st->codec->sample_rate);            if(!st->codec->frame_size){                av_log(s, AV_LOG_ERROR, "track %d: codec frame size is not set\n", i);                return -1;            }else if(st->codec->frame_size > 1){ /* assume compressed audio */                track->audio_vbr = 1;            }else{                track->sampleSize = (av_get_bits_per_sample(st->codec->codec_id) >> 3) * st->codec->channels;            }        }    }    mov_write_mdat_tag(pb, mov);    mov->time = s->timestamp + 0x7C25B080; //1970 based -> 1904 based    mov->nb_streams = s->nb_streams;    put_flush_packet(pb);    return 0;}static int mov_write_packet(AVFormatContext *s, AVPacket *pkt){    MOVContext *mov = s->priv_data;    ByteIOContext *pb = s->pb;    MOVTrack *trk = &mov->tracks[pkt->stream_index];    AVCodecContext *enc = trk->enc;    unsigned int samplesInChunk = 0;    int size= pkt->size;    if (url_is_streamed(s->pb)) return 0; /* Can't handle that */    if (!size) return 0; /* Discard 0 sized packets */    if (enc->codec_id == CODEC_ID_AMR_NB) {        /* We must find out how many AMR blocks there are in one packet */        static uint16_t packed_size[16] =            {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 0};        int len = 0;        while (len < size && samplesInChunk < 100) {            len += packed_size[(pkt->data[len] >> 3) & 0x0F];            samplesInChunk++;        }        if(samplesInChunk > 1){            av_log(s, AV_LOG_ERROR, "fatal error, input is not a single packet, implement a AVParser for it\n");            return -1;        }    } else if (trk->sampleSize)        samplesInChunk = size/trk->sampleSize;    else        samplesInChunk = 1;    /* copy extradata if it exists */    if (trk->vosLen == 0 && enc->extradata_size > 0) {        trk->vosLen = enc->extradata_size;        trk->vosData = av_malloc(trk->vosLen);        memcpy(trk->vosData, enc->extradata, trk->vosLen);    }    if (enc->codec_id == CODEC_ID_H264 && trk->vosLen > 0 && *(uint8_t *)trk->vosData != 1) {        /* from x264 or from bytestream h264 */        /* nal reformating needed */        int ret = ff_avc_parse_nal_units(pkt->data, &pkt->data, &pkt->size);        if (ret < 0)            return ret;        assert(pkt->size);        size = pkt->size;    } else if (enc->codec_id == CODEC_ID_DNXHD && !trk->vosLen) {        /* copy frame header to create needed atoms */        if (size < 640)            return -1;        trk->vosLen = 640;        trk->vosData = av_malloc(trk->vosLen);        memcpy(trk->vosData, pkt->data, 640);    }    if (!(trk->entry % MOV_INDEX_CLUSTER_SIZE)) {        trk->cluster = av_realloc(trk->cluster, (trk->entry + MOV_INDEX_CLUSTER_SIZE) * sizeof(*trk->cluster));        if (!trk->cluster)            return -1;    }    trk->cluster[trk->entry].pos = url_ftell(pb);    trk->cluster[trk->entry].samplesInChunk = samplesInChunk;    trk->cluster[trk->entry].size = size;    trk->cluster[trk->entry].entries = samplesInChunk;    trk->cluster[trk->entry].dts = pkt->dts;    trk->trackDuration = pkt->dts - trk->cluster[0].dts + pkt->duration;    if(enc->codec_type == CODEC_TYPE_VIDEO) {        if (pkt->dts != pkt->pts)            trk->hasBframes = 1;        trk->cluster[trk->entry].cts = pkt->pts - pkt->dts;        trk->cluster[trk->entry].key_frame = !!(pkt->flags & PKT_FLAG_KEY);        if(trk->cluster[trk->entry].key_frame)            trk->hasKeyframes++;    }    trk->entry++;    trk->sampleCount += samplesInChunk;    mov->mdat_size += size;    put_buffer(pb, pkt->data, size);    put_flush_packet(pb);    return 0;}static int mov_write_trailer(AVFormatContext *s){    MOVContext *mov = s->priv_data;    ByteIOContext *pb = s->pb;    int res = 0;    int i;    offset_t moov_pos = url_ftell(pb);    /* Write size of mdat tag */    if (mov->mdat_size+8 <= UINT32_MAX) {        url_fseek(pb, mov->mdat_pos, SEEK_SET);        put_be32(pb, mov->mdat_size+8);    } else {        /* overwrite 'wide' placeholder atom */        url_fseek(pb, mov->mdat_pos - 8, SEEK_SET);        put_be32(pb, 1); /* special value: real atom size will be 64 bit value after tag field */        put_tag(pb, "mdat");        put_be64(pb, mov->mdat_size+16);    }    url_fseek(pb, moov_pos, SEEK_SET);    mov_write_moov_tag(pb, mov, s);    for (i=0; i<mov->nb_streams; i++) {        av_freep(&mov->tracks[i].cluster);        if(mov->tracks[i].vosLen) av_free(mov->tracks[i].vosData);    }    put_flush_packet(pb);    return res;}#ifdef CONFIG_MOV_MUXERAVOutputFormat mov_muxer = {    "mov",    "mov format",    NULL,    "mov",    sizeof(MOVContext),    CODEC_ID_AAC,    CODEC_ID_MPEG4,    mov_write_header,    mov_write_packet,    mov_write_trailer,    .flags = AVFMT_GLOBALHEADER,    .codec_tag = (const AVCodecTag*[]){codec_movvideo_tags, codec_movaudio_tags, 0},};#endif#ifdef CONFIG_TGP_MUXERAVOutputFormat tgp_muxer = {    "3gp",    "3gp format",    NULL,    "3gp",    sizeof(MOVContext),    CODEC_ID_AMR_NB,    CODEC_ID_H263,    mov_write_header,    mov_write_packet,    mov_write_trailer,    .flags = AVFMT_GLOBALHEADER,    .codec_tag = (const AVCodecTag*[]){codec_3gp_tags, 0},};#endif#ifdef CONFIG_MP4_MUXERAVOutputFormat mp4_muxer = {    "mp4",    "mp4 format",    "application/mp4",    "mp4,m4a",    sizeof(MOVContext),    CODEC_ID_AAC,    CODEC_ID_MPEG4,    mov_write_header,    mov_write_packet,    mov_write_trailer,    .flags = AVFMT_GLOBALHEADER,    .codec_tag = (const AVCodecTag*[]){ff_mp4_obj_type, 0},};#endif#ifdef CONFIG_PSP_MUXERAVOutputFormat psp_muxer = {    "psp",    "psp mp4 format",    NULL,    "mp4,psp",    sizeof(MOVContext),    CODEC_ID_AAC,    CODEC_ID_MPEG4,    mov_write_header,    mov_write_packet,    mov_write_trailer,    .flags = AVFMT_GLOBALHEADER,    .codec_tag = (const AVCodecTag*[]){ff_mp4_obj_type, 0},};#endif#ifdef CONFIG_TG2_MUXERAVOutputFormat tg2_muxer = {    "3g2",    "3gp2 format",    NULL,    "3g2",    sizeof(MOVContext),    CODEC_ID_AMR_NB,    CODEC_ID_H263,    mov_write_header,    mov_write_packet,    mov_write_trailer,    .flags = AVFMT_GLOBALHEADER,    .codec_tag = (const AVCodecTag*[]){codec_3gp_tags, 0},};#endif

⌨️ 快捷键说明

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