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

📄 movenc.c.svn-base

📁 mediastreamer2是开源的网络传输媒体流的库
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:
static int mov_write_avid_tag(ByteIOContext *pb, MOVTrack *track){    int i;    put_be32(pb, 24); /* size */    put_tag(pb, "ACLR");    put_tag(pb, "ACLR");    put_tag(pb, "0001");    put_be32(pb, 1); /* yuv 1 / rgb 2 ? */    put_be32(pb, 0); /* unknown */    put_be32(pb, 24); /* size */    put_tag(pb, "APRG");    put_tag(pb, "APRG");    put_tag(pb, "0001");    put_be32(pb, 1); /* unknown */    put_be32(pb, 0); /* unknown */    put_be32(pb, 120); /* size */    put_tag(pb, "ARES");    put_tag(pb, "ARES");    put_tag(pb, "0001");    put_be32(pb, AV_RB32(track->vosData + 0x28)); /* dnxhd cid, some id ? */    put_be32(pb, track->enc->width);    /* values below are based on samples created with quicktime and avid codecs */    if (track->vosData[5] & 2) { // interlaced        put_be32(pb, track->enc->height/2);        put_be32(pb, 2); /* unknown */        put_be32(pb, 0); /* unknown */        put_be32(pb, 4); /* unknown */    } else {        put_be32(pb, track->enc->height);        put_be32(pb, 1); /* unknown */        put_be32(pb, 0); /* unknown */        if (track->enc->height == 1080)            put_be32(pb, 5); /* unknown */        else            put_be32(pb, 6); /* unknown */    }    /* padding */    for (i = 0; i < 10; i++)        put_be64(pb, 0);    /* extra padding for stsd needed */    put_be32(pb, 0);    return 0;}static const AVCodecTag codec_3gp_tags[] = {    { CODEC_ID_H263,   MKTAG('s','2','6','3') },    { CODEC_ID_H264,   MKTAG('a','v','c','1') },    { CODEC_ID_MPEG4,  MKTAG('m','p','4','v') },    { CODEC_ID_AAC,    MKTAG('m','p','4','a') },    { CODEC_ID_AMR_NB, MKTAG('s','a','m','r') },    { CODEC_ID_AMR_WB, MKTAG('s','a','w','b') },};static const AVCodecTag mov_pix_fmt_tags[] = {    { PIX_FMT_YUYV422, MKTAG('y','u','v','s') },    { PIX_FMT_UYVY422, MKTAG('2','v','u','y') },    { PIX_FMT_BGR555,  MKTAG('r','a','w',' ') },    { PIX_FMT_RGB24,   MKTAG('r','a','w',' ') },    { PIX_FMT_BGR32_1, MKTAG('r','a','w',' ') },};static int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track){    int tag = track->enc->codec_tag;    if (track->mode == MODE_MP4 || track->mode == MODE_PSP) {        if (!codec_get_tag(ff_mp4_obj_type, track->enc->codec_id))            return 0;        if (track->enc->codec_id == CODEC_ID_H264)           tag = MKTAG('a','v','c','1');        else if (track->enc->codec_type == CODEC_TYPE_VIDEO) tag = MKTAG('m','p','4','v');        else if (track->enc->codec_type == CODEC_TYPE_AUDIO) tag = MKTAG('m','p','4','a');    } else if (track->mode == MODE_3GP || track->mode == MODE_3G2) {        tag = codec_get_tag(codec_3gp_tags, track->enc->codec_id);    } else if (!tag || (track->enc->strict_std_compliance >= FF_COMPLIANCE_NORMAL &&                        (tag == MKTAG('d','v','c','p') ||                         track->enc->codec_id == CODEC_ID_RAWVIDEO))) {        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 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 if (track->enc->codec_id == CODEC_ID_RAWVIDEO) {            tag = codec_get_tag(mov_pix_fmt_tags, track->enc->pix_fmt);            if (!tag) // restore tag                tag = track->enc->codec_tag;        } else {            if (track->enc->codec_type == CODEC_TYPE_VIDEO) {                tag = codec_get_tag(codec_movvideo_tags, track->enc->codec_id);                if (!tag) { // if no mac fcc found, try with Microsoft tags                    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");                }            } else if (track->enc->codec_type == CODEC_TYPE_AUDIO) {                tag = codec_get_tag(codec_movaudio_tags, track->enc->codec_id);                if (!tag) { // if no mac fcc found, try with Microsoft tags                    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");                    }                }            }        }    }    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) */    if (track->mode == MODE_MOV) {        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 */        }    } else {        put_be32(pb, 0); /* Reserved */        put_be32(pb, 0); /* Reserved */        put_be32(pb, 0); /* Reserved */    }    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);    /* FIXME not sure, ISO 14496-1 draft where it shall be set to 0 */    if (track->mode == MODE_MOV && 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);    if (track->mode == MODE_MOV && track->enc->bits_per_sample)        put_be16(pb, track->enc->bits_per_sample);    else        put_be16(pb, 0x18); /* Reserved */    put_be16(pb, 0xffff); /* Reserved */    if(track->tag == MKTAG('m','p','4','v'))        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);    else if(track->enc->codec_id == CODEC_ID_DNXHD)        mov_write_avid_tag(pb, track);    else if(track->vosLen > 0)        mov_write_glbl_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){    MOV_stts_t *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].cts;    for (i=1; i<track->entry; i++) {        if (track->cluster[i].cts == ctts_entries[entries].duration) {            ctts_entries[entries].count++; /* compress */        } else {            entries++;            ctts_entries[entries].duration = track->cluster[i].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;}/* Time to sample atom */static int mov_write_stts_tag(ByteIOContext *pb, MOVTrack* track){    MOV_stts_t *stts_entries;    uint32_t entries = -1;    uint32_t atom_size;    int i;    if (track->enc->codec_type == CODEC_TYPE_AUDIO && !track->audio_vbr) {        stts_entries = av_malloc(sizeof(*stts_entries)); /* one entry */        stts_entries[0].count = track->sampleCount;        stts_entries[0].duration = 1;        entries = 1;    } else {        stts_entries = av_malloc(track->entry * sizeof(*stts_entries)); /* worst case */        for (i=0; i<track->entry; i++) {            int64_t duration = i + 1 == track->entry ?                track->trackDuration - track->cluster[i].dts + track->cluster[0].dts : /* readjusting */                track->cluster[i+1].dts - track->cluster[i].dts;            if (i && duration == stts_entries[entries].duration) {                stts_entries[entries].count++; /* compress */            } else {                entries++;                stts_entries[entries].duration = duration;                stts_entries[entries].count = 1;            }        }        entries++; /* last one */    }    atom_size = 16 + (entries * 8);    put_be32(pb, atom_size); /* size */    put_tag(pb, "stts");    put_be32(pb, 0); /* version & flags */    put_be32(pb, entries); /* entry count */    for (i=0; i<entries; i++) {        put_be32(pb, stts_entries[i].count);        put_be32(pb, stts_entries[i].duration);    }    av_free(stts_entries);    return atom_size;}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){    const 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) */    if(version!=0 && track->mode == MODE_MOV){        av_log(NULL, AV_LOG_ERROR,            "FATAL error, file duration too long for timebase, this file will not be\n"            "playable with quicktime. Choose a different timebase or a different\n"            "container format\n");    }    return 32;}static int mov_write_mdia_tag(ByteIOContext *pb, MOVTrack* track){    offset_t 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 duration = av_rescale_rnd(track->trackDuration, globalTimescale, track->timescale, AV_ROUND_UP);    int version = duration < INT32_MAX ? 0 : 1;    (version == 1) ? put_be32(pb, 104) : put_be32(pb, 92); /* size */    put_tag(pb, "tkhd");    put_byte(pb, version);    put_be24(pb, 0xf); /* flags (track enabled) */    if (version == 1) {        put_be64(pb, track->time);        put_be64(pb, track->time);    } else {

⌨️ 快捷键说明

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