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

📄 movenc.c

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.10平台上编译为嵌入式图形界面操作系统。
💻 C
📖 第 1 页 / 共 2 页
字号:
        track->hasKeyframes)        mov_write_stss_tag(pb, track);    mov_write_stsc_tag(pb, track);    mov_write_stsz_tag(pb, track);    mov_write_stco_tag(pb, track);    return updateSize(pb, pos);}static int mov_write_dinf_tag(ByteIOContext *pb){    int pos = url_ftell(pb);    put_be32(pb, 0); /* size */    put_tag(pb, "dinf");    mov_write_dref_tag(pb);    return updateSize(pb, pos);}static int mov_write_smhd_tag(ByteIOContext *pb){    put_be32(pb, 16); /* size */    put_tag(pb, "smhd");    put_be32(pb, 0); /* version & flags */    put_be16(pb, 0); /* reserved (balance, normally = 0) */    put_be16(pb, 0); /* reserved */    return 16;}static int mov_write_vmhd_tag(ByteIOContext *pb){    put_be32(pb, 0x14); /* size (always 0x14) */    put_tag(pb, "vmhd");    put_be32(pb, 0x01); /* version & flags */    put_be64(pb, 0); /* reserved (graphics mode = copy) */    return 0x14;}static int mov_write_minf_tag(ByteIOContext *pb, MOVTrack* track){    int pos = url_ftell(pb);    put_be32(pb, 0); /* size */    put_tag(pb, "minf");    if(track->enc->codec_type == CODEC_TYPE_VIDEO)        mov_write_vmhd_tag(pb);    else        mov_write_smhd_tag(pb);    mov_write_dinf_tag(pb);    mov_write_stbl_tag(pb, track);    return updateSize(pb, pos);}static int mov_write_hdlr_tag(ByteIOContext *pb, MOVTrack* track){    char *str;    int pos = url_ftell(pb);    put_be32(pb, 0); /* size */    put_tag(pb, "hdlr");    put_be32(pb, 0); /* Version & flags */    put_be32(pb, 0); /* reserved */    if(track->enc->codec_type == CODEC_TYPE_VIDEO)        put_tag(pb, "vide"); /* handler type */    else        put_tag(pb, "soun"); /* handler type */    put_be32(pb ,0); /* reserved */    put_be32(pb ,0); /* reserved */    put_be32(pb ,0); /* reserved */    if(track->enc->codec_type == CODEC_TYPE_VIDEO)        str = "VideoHandler";    else        str = "SoundHandler";    put_byte(pb, strlen(str)); /* string counter */    put_buffer(pb, str, strlen(str));    return updateSize(pb, pos);}static int mov_write_mdhd_tag(ByteIOContext *pb, MOVTrack* track){    put_be32(pb, 32); /* size */    put_tag(pb, "mdhd");    put_be32(pb, 0); /* Version & flags */    put_be32(pb, track->time); /* creation time */    put_be32(pb, track->time); /* modification time */    put_be32(pb, track->timescale); /* time scale (sample rate for audio) */     put_be32(pb, track->trackDuration); /* duration */    put_be16(pb, 0); /* language, 0 = english */    put_be16(pb, 0); /* reserved (quality) */    return 32;}static int mov_write_mdia_tag(ByteIOContext *pb, MOVTrack* track){    int pos = url_ftell(pb);    put_be32(pb, 0); /* size */    put_tag(pb, "mdia");    mov_write_mdhd_tag(pb, track);    mov_write_hdlr_tag(pb, track);    mov_write_minf_tag(pb, track);    return updateSize(pb, pos);}static int mov_write_tkhd_tag(ByteIOContext *pb, MOVTrack* track){    int64_t maxTrackLenTemp;    put_be32(pb, 0x5c); /* size (always 0x5c) */    put_tag(pb, "tkhd");    put_be32(pb, 0xf); /* version & flags (track enabled) */    put_be32(pb, track->time); /* creation time */    put_be32(pb, track->time); /* modification time */    put_be32(pb, track->trackID); /* track-id */    put_be32(pb, 0); /* reserved */    maxTrackLenTemp = ((int64_t)globalTimescale*(int64_t)track->trackDuration)/(int64_t)track->timescale;    put_be32(pb, (long)maxTrackLenTemp); /* duration */    put_be32(pb, 0); /* reserved */    put_be32(pb, 0); /* reserved */    put_be32(pb, 0x0); /* reserved (Layer & Alternate group) */    /* Volume, only for audio */    if(track->enc->codec_type == CODEC_TYPE_AUDIO)        put_be16(pb, 0x0100);    else        put_be16(pb, 0);    put_be16(pb, 0); /* reserved */    /* Matrix structure */    put_be32(pb, 0x00010000); /* reserved */    put_be32(pb, 0x0); /* reserved */    put_be32(pb, 0x0); /* reserved */    put_be32(pb, 0x0); /* reserved */    put_be32(pb, 0x00010000); /* reserved */    put_be32(pb, 0x0); /* reserved */    put_be32(pb, 0x0); /* reserved */    put_be32(pb, 0x0); /* reserved */    put_be32(pb, 0x40000000); /* reserved */    /* Track width and height, for visual only */    if(track->enc->codec_type == CODEC_TYPE_VIDEO) {        put_be32(pb, track->enc->width*0x10000);        put_be32(pb, track->enc->height*0x10000);    }    else {        put_be32(pb, 0);        put_be32(pb, 0);    }    return 0x5c;}static int mov_write_trak_tag(ByteIOContext *pb, MOVTrack* track){    int pos = url_ftell(pb);    put_be32(pb, 0); /* size */    put_tag(pb, "trak");    mov_write_tkhd_tag(pb, track);    mov_write_mdia_tag(pb, track);    return updateSize(pb, pos);}/* TODO: Not sorted out, but not necessary either */static int mov_write_iods_tag(ByteIOContext *pb, MOVContext *mov){    put_be32(pb, 0x15); /* size */    put_tag(pb, "iods");    put_be32(pb, 0);    /* version & flags */    put_be16(pb, 0x1007);    put_byte(pb, 0);    put_be16(pb, 0x4fff);    put_be16(pb, 0xfffe);    put_be16(pb, 0x01ff);    return 0x15;}static int mov_write_mvhd_tag(ByteIOContext *pb, MOVContext *mov){    int maxTrackID = 1, maxTrackLen = 0, i;    int64_t maxTrackLenTemp;    put_be32(pb, 0x6c); /* size (always 0x6c) */    put_tag(pb, "mvhd");    put_be32(pb, 0); /* version & flags */    put_be32(pb, mov->time); /* creation time */    put_be32(pb, mov->time); /* modification time */    put_be32(pb, mov->timescale); /* timescale */    for (i=0; i<MAX_STREAMS; i++) {        if(mov->tracks[i].entry > 0) {            maxTrackLenTemp = ((int64_t)globalTimescale*(int64_t)mov->tracks[i].trackDuration)/(int64_t)mov->tracks[i].timescale;            if(maxTrackLen < maxTrackLenTemp)                maxTrackLen = maxTrackLenTemp;            if(maxTrackID < mov->tracks[i].trackID)                maxTrackID = mov->tracks[i].trackID;        }    }    put_be32(pb, maxTrackLen); /* duration of longest track */    put_be32(pb, 0x00010000); /* reserved (preferred rate) 1.0 = normal */    put_be16(pb, 0x0100); /* reserved (preferred volume) 1.0 = normal */    put_be16(pb, 0); /* reserved */    put_be32(pb, 0); /* reserved */    put_be32(pb, 0); /* reserved */    /* Matrix structure */    put_be32(pb, 0x00010000); /* reserved */    put_be32(pb, 0x0); /* reserved */    put_be32(pb, 0x0); /* reserved */    put_be32(pb, 0x0); /* reserved */    put_be32(pb, 0x00010000); /* reserved */    put_be32(pb, 0x0); /* reserved */    put_be32(pb, 0x0); /* reserved */    put_be32(pb, 0x0); /* reserved */    put_be32(pb, 0x40000000); /* reserved */    put_be32(pb, 0); /* reserved (preview time) */    put_be32(pb, 0); /* reserved (preview duration) */    put_be32(pb, 0); /* reserved (poster time) */    put_be32(pb, 0); /* reserved (selection time) */    put_be32(pb, 0); /* reserved (selection duration) */    put_be32(pb, 0); /* reserved (current time) */    put_be32(pb, maxTrackID+1); /* Next track id */    return 0x6c;}static int mov_write_moov_tag(ByteIOContext *pb, MOVContext *mov){    int pos, i;    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->frame_rate;            mov->tracks[i].sampleDuration = mov->tracks[i].enc->frame_rate_base;        }        else if(mov->tracks[i].enc->codec_type == CODEC_TYPE_AUDIO) {            /* If AMR, track timescale = 8000, AMR_WB = 16000 */            if(mov->tracks[i].enc->codec_id == CODEC_ID_AMR_NB) {                mov->tracks[i].sampleDuration = 160;  // Bytes per chunk                mov->tracks[i].timescale = 8000;            }            else {                mov->tracks[i].timescale = mov->tracks[i].enc->sample_rate;                mov->tracks[i].sampleDuration = mov->tracks[i].enc->frame_size;            }        }        mov->tracks[i].trackDuration =             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]));        }    }    return updateSize(pb, pos);}int mov_write_mdat_tag(ByteIOContext *pb, MOVContext* mov){    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 */int mov_write_ftyp_tag(ByteIOContext *pb, AVFormatContext *s){    put_be32(pb, 0x14 ); /* size */    put_tag(pb, "ftyp");    if (!strcmp("3gp", s->oformat->name))        put_tag(pb, "3gp4");    else        put_tag(pb, "isom");    put_be32(pb, 0x200 );    if (!strcmp("3gp", s->oformat->name))        put_tag(pb, "3gp4");    else        put_tag(pb, "mp41");    return 0x14;}static int mov_write_header(AVFormatContext *s){    ByteIOContext *pb = &s->pb;    if(s->oformat != NULL) {    if(!strcmp("3gp", s->oformat->name) || !strcmp("mp4", s->oformat->name))        mov_write_ftyp_tag(pb,s);    }    put_flush_packet(pb);    return 0;}static int Timestamp() {    return 1067949799U+(24107*86400); //its the modification time of this line :)}static int mov_write_packet(AVFormatContext *s, int stream_index,                            const uint8_t *buf, int size, int64_t pts){    MOVContext *mov = s->priv_data;    ByteIOContext *pb = &s->pb;    AVCodecContext *enc = &s->streams[stream_index]->codec;    MOVTrack* trk = &mov->tracks[stream_index];    int cl, id;    unsigned int samplesInChunk = 0;    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_VIDEO ) {        samplesInChunk = 1;    }    else if (enc->codec_type == CODEC_TYPE_AUDIO ) {        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[(buf[len] >> 3) & 0x0F];                samplesInChunk++;            }        }        else if(enc->codec_id == CODEC_ID_PCM_ALAW) {            samplesInChunk = size/enc->channels;        }        else {            samplesInChunk = 1;        }    }    if ((enc->codec_id == CODEC_ID_MPEG4 || enc->codec_id == CODEC_ID_AAC)        && trk->vosLen == 0) {        assert(enc->extradata_size);        trk->vosLen = enc->extradata_size;        trk->vosData = av_malloc(trk->vosLen);        memcpy(trk->vosData, enc->extradata, trk->vosLen);    }    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;    }    if (mov->mdat_written == 0) {        mov_write_mdat_tag(pb, mov);        mov->mdat_written = 1;        mov->time = Timestamp();    }    trk->cluster[cl][id].pos = url_ftell(pb) - mov->movi_list;    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) {        trk->cluster[cl][id].key_frame = enc->coded_frame->key_frame;        if(enc->coded_frame->pict_type == FF_I_TYPE)            trk->hasKeyframes = 1;    }    trk->enc = enc;    trk->entry++;    trk->sampleCount += samplesInChunk;    trk->mdat_size += size;    put_buffer(pb, buf, 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 file_size;    file_size = url_ftell(pb);    j = 0;    /* Write size of mdat tag */    for (i=0; i<MAX_STREAMS; i++) {        if(mov->tracks[i].ents_allocated > 0) {            j += mov->tracks[i].mdat_size;        }    }    url_fseek(pb, mov->mdat_pos, SEEK_SET);    put_be32(pb, j+8);    url_fseek(pb, file_size, SEEK_SET);    mov_write_moov_tag(pb, mov);    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);        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_PCM_ALAW,    CODEC_ID_MPEG4,    mov_write_header,    mov_write_packet,    mov_write_trailer,};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,};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,};int movenc_init(void){    av_register_output_format(&mov_oformat);    av_register_output_format(&_3gp_oformat);    av_register_output_format(&mp4_oformat);    return 0;}

⌨️ 快捷键说明

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