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

📄 movenc.c.svn-base

📁 ffmpeg是一个大项目
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
        // size        curpos = url_ftell(pb);        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;}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<MAX_STREAMS; i++) {        if(mov->tracks[i].entry <= 0) continue;        if(mov->tracks[i].enc->codec_type == CODEC_TYPE_VIDEO) {            mov->tracks[i].timescale = mov->tracks[i].enc->time_base.den;            mov->tracks[i].sampleDuration = mov->tracks[i].enc->time_base.num;        } else if(mov->tracks[i].enc->codec_type == CODEC_TYPE_AUDIO) {            mov->tracks[i].timescale = mov->tracks[i].enc->sample_rate;            mov->tracks[i].sampleDuration = mov->tracks[i].enc->frame_size;        }        mov->tracks[i].trackDuration =            (int64_t)mov->tracks[i].sampleCount * mov->tracks[i].sampleDuration;        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<MAX_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    mov_write_udta_tag(pb, mov, s);    return updateSize(pb, pos);}int mov_write_mdat_tag(ByteIOContext *pb, MOVContext* mov){    put_be32(pb, 8);    // placeholder for extended size field (64 bit)    put_tag(pb, "wide");    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;    /* 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;        if(st->codec->codec_type == CODEC_TYPE_VIDEO){            track->tag = mov_find_video_codec_tag(s, track);            av_set_pts_info(st, 64, 1, st->codec->time_base.den);        }else if(st->codec->codec_type == CODEC_TYPE_AUDIO){            track->tag = mov_find_audio_codec_tag(s, track);            av_set_pts_info(st, 64, 1, st->codec->sample_rate);        }        track->language = ff_mov_iso639_to_lang(st->language, mov->mode != MODE_MOV);        track->mode = mov->mode;    }    mov_write_mdat_tag(pb, mov);    mov->time = s->timestamp + 0x7C25B080; //1970 based -> 1904 based    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;    int cl, id;    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_type == CODEC_TYPE_AUDIO) {        switch (enc->codec_id) {        case 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++;                }            }            break;        case CODEC_ID_PCM_MULAW:        case CODEC_ID_PCM_ALAW:            samplesInChunk = size/enc->channels;            break;        case CODEC_ID_PCM_S16BE:        case CODEC_ID_PCM_S16LE:            samplesInChunk = size/(2*enc->channels);            break;        case CODEC_ID_PCM_S24BE:        case CODEC_ID_PCM_S24LE:            samplesInChunk = size/(3*enc->channels);            break;        case CODEC_ID_PCM_S32BE:        case CODEC_ID_PCM_S32LE:            samplesInChunk = size/(4*enc->channels);            break;        default:            samplesInChunk = 1;        }    } 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 */        avc_parse_nal_units(&pkt->data, &pkt->size);        assert(pkt->size);        size = pkt->size;    }    cl = trk->entry / MOV_INDEX_CLUSTER_SIZE;    id = trk->entry % MOV_INDEX_CLUSTER_SIZE;    if (trk->ents_allocated <= trk->entry) {        trk->cluster = av_realloc(trk->cluster, (cl+1)*sizeof(void*));        if (!trk->cluster)            return -1;        trk->cluster[cl] = av_malloc(MOV_INDEX_CLUSTER_SIZE*sizeof(MOVIentry));        if (!trk->cluster[cl])            return -1;        trk->ents_allocated += MOV_INDEX_CLUSTER_SIZE;    }    trk->cluster[cl][id].pos = url_ftell(pb);    trk->cluster[cl][id].samplesInChunk = samplesInChunk;    trk->cluster[cl][id].size = size;    trk->cluster[cl][id].entries = samplesInChunk;    if(enc->codec_type == CODEC_TYPE_VIDEO) {        if (pkt->dts != pkt->pts)            trk->hasBframes = 1;        trk->cluster[cl][id].cts = pkt->pts - pkt->dts;        trk->cluster[cl][id].key_frame = !!(pkt->flags & PKT_FLAG_KEY);        if(trk->cluster[cl][id].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, j;    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<MAX_STREAMS; i++) {        for (j=0; j<mov->tracks[i].ents_allocated/MOV_INDEX_CLUSTER_SIZE; j++) {            av_free(mov->tracks[i].cluster[j]);        }        av_free(mov->tracks[i].cluster);        if( mov->tracks[i].vosLen ) av_free( mov->tracks[i].vosData );        mov->tracks[i].cluster = NULL;        mov->tracks[i].ents_allocated = mov->tracks[i].entry = 0;    }    put_flush_packet(pb);    return res;}static AVOutputFormat mov_oformat = {    "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,};static AVOutputFormat _3gp_oformat = {    "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,};static AVOutputFormat mp4_oformat = {    "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,};static AVOutputFormat psp_oformat = {    "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,};static AVOutputFormat _3g2_oformat = {    "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,};int movenc_init(void){    av_register_output_format(&mov_oformat);    av_register_output_format(&_3gp_oformat);    av_register_output_format(&mp4_oformat);    av_register_output_format(&psp_oformat);    av_register_output_format(&_3g2_oformat);    return 0;}

⌨️ 快捷键说明

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