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

📄 movenc.c.svn-base

📁 ffmpeg是一个大项目
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
    put_tag(pb, "SMI ");    put_tag(pb, "SEQH");    put_be32(pb, 0x5);    put_be32(pb, 0xe2c0211d);    put_be32(pb, 0xc0000000);    put_byte(pb, 0);    return 0x15;}static uint8_t *avc_find_startcode( uint8_t *p, uint8_t *end ){    uint8_t *a = p + 4 - ((int)p & 3);    for( end -= 3; p < a && p < end; p++ ) {        if( p[0] == 0 && p[1] == 0 && p[2] == 1 )            return p;    }    for( end -= 3; p < end; p += 4 ) {        uint32_t x = *(uint32_t*)p;//      if( (x - 0x01000100) & (~x) & 0x80008000 ) // little endian//      if( (x - 0x00010001) & (~x) & 0x00800080 ) // big endian        if( (x - 0x01010101) & (~x) & 0x80808080 ) { // generic            if( p[1] == 0 ) {                if( p[0] == 0 && p[2] == 1 )                    return p-1;                if( p[2] == 0 && p[3] == 1 )                    return p;            }            if( p[3] == 0 ) {                if( p[2] == 0 && p[4] == 1 )                    return p+1;                if( p[4] == 0 && p[5] == 1 )                    return p+2;            }        }    }    for( end += 3; p < end; p++ ) {        if( p[0] == 0 && p[1] == 0 && p[2] == 1 )            return p;    }    return end + 3;}static void avc_parse_nal_units(uint8_t **buf, int *size){    ByteIOContext pb;    uint8_t *p = *buf;    uint8_t *end = p + *size;    uint8_t *nal_start, *nal_end;    url_open_dyn_buf(&pb);    nal_start = avc_find_startcode(p, end);    while (nal_start < end) {        while(!*(nal_start++));        nal_end = avc_find_startcode(nal_start, end);        put_be32(&pb, nal_end - nal_start);        put_buffer(&pb, nal_start, nal_end - nal_start);        nal_start = nal_end;    }    av_freep(buf);    *size = url_close_dyn_buf(&pb, buf);}static int mov_write_avcc_tag(ByteIOContext *pb, MOVTrack *track){    offset_t pos = url_ftell(pb);    put_be32(pb, 0);    put_tag(pb, "avcC");    if (track->vosLen > 6) {        /* check for h264 start code */        if (BE_32(track->vosData) == 0x00000001) {            uint8_t *buf, *end;            uint32_t sps_size=0, pps_size=0;            uint8_t *sps=0, *pps=0;            avc_parse_nal_units(&track->vosData, &track->vosLen);            buf = track->vosData;            end = track->vosData + track->vosLen;            /* look for sps and pps */            while (buf < end) {                unsigned int size;                uint8_t nal_type;                size = BE_32(buf);                nal_type = buf[4] & 0x1f;                if (nal_type == 7) { /* SPS */                    sps = buf + 4;                    sps_size = size;                } else if (nal_type == 8) { /* PPS */                    pps = buf + 4;                    pps_size = size;                }                buf += size + 4;            }            assert(sps);            assert(pps);            put_byte(pb, 1); /* version */            put_byte(pb, sps[1]); /* profile */            put_byte(pb, sps[2]); /* profile compat */            put_byte(pb, sps[3]); /* level */            put_byte(pb, 0xff); /* 6 bits reserved (111111) + 2 bits nal size length - 1 (11) */            put_byte(pb, 0xe1); /* 3 bits reserved (111) + 5 bits number of sps (00001) */            put_be16(pb, sps_size);            put_buffer(pb, sps, sps_size);            put_byte(pb, 1); /* number of pps */            put_be16(pb, pps_size);            put_buffer(pb, pps, pps_size);        } else {            put_buffer(pb, track->vosData, track->vosLen);        }    }    return updateSize(pb, pos);}static const CodecTag codec_movvideo_tags[] = {    { CODEC_ID_SVQ1, MKTAG('S', 'V', 'Q', '1') },    { CODEC_ID_SVQ3, MKTAG('S', 'V', 'Q', '3') },    { CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') },    { CODEC_ID_H263, MKTAG('s', '2', '6', '3') },    { CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') },    /* special handling in mov_find_video_codec_tag */    { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', ' ') }, /* DV NTSC */    { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', 'p') }, /* DV PAL */    { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'p', 'p') }, /* DVCPRO PAL */    { CODEC_ID_DVVIDEO, MKTAG('d', 'v', '5', 'n') }, /* DVCPRO50 NTSC */    { CODEC_ID_DVVIDEO, MKTAG('d', 'v', '5', 'p') }, /* DVCPRO50 PAL */    { CODEC_ID_NONE, 0 },};static int mov_find_video_codec_tag(AVFormatContext *s, MOVTrack *track){    int tag = track->enc->codec_tag;    if (!tag) {        if (track->enc->codec_id == CODEC_ID_DVVIDEO) {            if (track->enc->height == 480) { /* NTSC */                if (track->enc->pix_fmt == PIX_FMT_YUV422P)                    tag = MKTAG('d', 'v', '5', 'n');                else                    tag = MKTAG('d', 'v', 'c', ' ');            } else { /* assume PAL */                if (track->enc->pix_fmt == PIX_FMT_YUV422P)                    tag = MKTAG('d', 'v', '5', 'p');                else if (track->enc->pix_fmt == PIX_FMT_YUV420P)                    tag = MKTAG('d', 'v', 'c', 'p');                else                    tag = MKTAG('d', 'v', 'p', 'p');            }        } else {            tag = codec_get_tag(codec_movvideo_tags, track->enc->codec_id);        }    }    // if no mac fcc found, try with Microsoft tags    if (!tag) {        tag = codec_get_tag(codec_bmp_tags, track->enc->codec_id);        if (tag) {            av_log(s, AV_LOG_INFO, "Warning, using MS style video codec tag, the file may be unplayable!\n");        }    }    assert(tag);    return tag;}static int mov_find_audio_codec_tag(AVFormatContext *s, MOVTrack *track){    int tag = track->enc->codec_tag;    if (!tag) {        tag = codec_get_tag(codec_movaudio_tags, track->enc->codec_id);    }    // if no mac fcc found, try with Microsoft tags    if (!tag) {        int ms_tag = codec_get_tag(codec_wav_tags, track->enc->codec_id);        if (ms_tag) {            tag = MKTAG('m', 's', ((ms_tag >> 8) & 0xff), (ms_tag & 0xff));            av_log(s, AV_LOG_INFO, "Warning, using MS style audio codec tag, the file may be unplayable!\n");        }    }    assert(tag);    return tag;}static int mov_write_video_tag(ByteIOContext *pb, MOVTrack* track){    offset_t pos = url_ftell(pb);    char compressor_name[32];    put_be32(pb, 0); /* size */    put_le32(pb, track->tag); // store it byteswapped    put_be32(pb, 0); /* Reserved */    put_be16(pb, 0); /* Reserved */    put_be16(pb, 1); /* Data-reference index */    put_be16(pb, 0); /* Codec stream version */    put_be16(pb, 0); /* Codec stream revision (=0) */    put_tag(pb, "FFMP"); /* Vendor */    if(track->enc->codec_id == CODEC_ID_RAWVIDEO) {        put_be32(pb, 0); /* Temporal Quality */        put_be32(pb, 0x400); /* Spatial Quality = lossless*/    } else {        put_be32(pb, 0x200); /* Temporal Quality = normal */        put_be32(pb, 0x200); /* Spatial Quality = normal */    }    put_be16(pb, track->enc->width); /* Video width */    put_be16(pb, track->enc->height); /* Video height */    put_be32(pb, 0x00480000); /* Horizontal resolution 72dpi */    put_be32(pb, 0x00480000); /* Vertical resolution 72dpi */    put_be32(pb, 0); /* Data size (= 0) */    put_be16(pb, 1); /* Frame count (= 1) */    memset(compressor_name,0,32);    if (track->enc->codec && track->enc->codec->name)        strncpy(compressor_name,track->enc->codec->name,31);    put_byte(pb, strlen(compressor_name));    put_buffer(pb, compressor_name, 31);    put_be16(pb, 0x18); /* Reserved */    put_be16(pb, 0xffff); /* Reserved */    if(track->enc->codec_id == CODEC_ID_MPEG4)        mov_write_esds_tag(pb, track);    else if(track->enc->codec_id == CODEC_ID_H263)        mov_write_d263_tag(pb);    else if(track->enc->codec_id == CODEC_ID_SVQ3)        mov_write_svq3_tag(pb);    else if(track->enc->codec_id == CODEC_ID_H264)        mov_write_avcc_tag(pb, track);    return updateSize (pb, pos);}static int mov_write_stsd_tag(ByteIOContext *pb, MOVTrack* track){    offset_t pos = url_ftell(pb);    put_be32(pb, 0); /* size */    put_tag(pb, "stsd");    put_be32(pb, 0); /* version & flags */    put_be32(pb, 1); /* entry count */    if (track->enc->codec_type == CODEC_TYPE_VIDEO)        mov_write_video_tag(pb, track);    else if (track->enc->codec_type == CODEC_TYPE_AUDIO)        mov_write_audio_tag(pb, track);    return updateSize(pb, pos);}static int mov_write_ctts_tag(ByteIOContext *pb, MOVTrack* track){    Time2Sample *ctts_entries;    uint32_t entries = 0;    uint32_t atom_size;    int i;    ctts_entries = av_malloc((track->entry + 1) * sizeof(*ctts_entries)); /* worst case */    ctts_entries[0].count = 1;    ctts_entries[0].duration = track->cluster[0][0].cts;    for (i=1; i<track->entry; i++) {        int cl = i / MOV_INDEX_CLUSTER_SIZE;        int id = i % MOV_INDEX_CLUSTER_SIZE;        if (track->cluster[cl][id].cts == ctts_entries[entries].duration) {            ctts_entries[entries].count++; /* compress */        } else {            entries++;            ctts_entries[entries].duration = track->cluster[cl][id].cts;            ctts_entries[entries].count = 1;        }    }    entries++; /* last one */    atom_size = 16 + (entries * 8);    put_be32(pb, atom_size); /* size */    put_tag(pb, "ctts");    put_be32(pb, 0); /* version & flags */    put_be32(pb, entries); /* entry count */    for (i=0; i<entries; i++) {        put_be32(pb, ctts_entries[i].count);        put_be32(pb, ctts_entries[i].duration);    }    av_free(ctts_entries);    return atom_size;}/* TODO: *//* Time to sample atom */static int mov_write_stts_tag(ByteIOContext *pb, MOVTrack* track){    put_be32(pb, 0x18); /* size */    put_tag(pb, "stts");    put_be32(pb, 0); /* version & flags */    put_be32(pb, 1); /* entry count */    put_be32(pb, track->sampleCount); /* sample count */    put_be32(pb, track->sampleDuration); /* sample duration */    return 0x18;}static int mov_write_dref_tag(ByteIOContext *pb){    put_be32(pb, 28); /* size */    put_tag(pb, "dref");    put_be32(pb, 0); /* version & flags */    put_be32(pb, 1); /* entry count */    put_be32(pb, 0xc); /* size */    put_tag(pb, "url ");    put_be32(pb, 1); /* version & flags */    return 28;}static int mov_write_stbl_tag(ByteIOContext *pb, MOVTrack* track){    offset_t pos = url_ftell(pb);    put_be32(pb, 0); /* size */    put_tag(pb, "stbl");    mov_write_stsd_tag(pb, track);    mov_write_stts_tag(pb, track);    if (track->enc->codec_type == CODEC_TYPE_VIDEO &&        track->hasKeyframes < track->entry)        mov_write_stss_tag(pb, track);    if (track->enc->codec_type == CODEC_TYPE_VIDEO &&        track->hasBframes)        mov_write_ctts_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){    offset_t 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_hdlr_tag(ByteIOContext *pb, MOVTrack* track){    char *descr, *hdlr, *hdlr_type;    offset_t pos = url_ftell(pb);    if (!track) { /* no media --> data handler */        hdlr = "dhlr";        hdlr_type = "url ";        descr = "DataHandler";    } else {        hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";        if (track->enc->codec_type == CODEC_TYPE_VIDEO) {            hdlr_type = "vide";            descr = "VideoHandler";        } else {            hdlr_type = "soun";            descr = "SoundHandler";        }    }    put_be32(pb, 0); /* size */    put_tag(pb, "hdlr");    put_be32(pb, 0); /* Version & flags */    put_buffer(pb, hdlr, 4); /* handler */    put_tag(pb, hdlr_type); /* handler type */    put_be32(pb ,0); /* reserved */    put_be32(pb ,0); /* reserved */    put_be32(pb ,0); /* reserved */    put_byte(pb, strlen(descr)); /* string counter */    put_buffer(pb, descr, strlen(descr)); /* handler description */    return updateSize(pb, pos);}static int mov_write_minf_tag(ByteIOContext *pb, MOVTrack* track){    offset_t 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);    if (track->mode == MODE_MOV) /* FIXME: Why do it for MODE_MOV only ? */        mov_write_hdlr_tag(pb, NULL);    mov_write_dinf_tag(pb);    mov_write_stbl_tag(pb, track);    return updateSize(pb, pos);}static int mov_write_mdhd_tag(ByteIOContext *pb, MOVTrack* track){    int version = track->trackDuration < INT32_MAX ? 0 : 1;    (version == 1) ? put_be32(pb, 44) : put_be32(pb, 32); /* size */    put_tag(pb, "mdhd");    put_byte(pb, version);    put_be24(pb, 0); /* flags */    if (version == 1) {        put_be64(pb, track->time);        put_be64(pb, track->time);    } else {        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) */    (version == 1) ? put_be64(pb, track->trackDuration) : put_be32(pb, track->trackDuration); /* duration */    put_be16(pb, track->language); /* language */    put_be16(pb, 0); /* reserved (quality) */    return 32;}

⌨️ 快捷键说明

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