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

📄 movenc.c

📁 pmpmodavc102_sub_src,psp下很好的播放器源码
💻 C
📖 第 1 页 / 共 4 页
字号:
    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) {            /* 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]));        }    }    mov_write_udta_tag(pb, mov, s);    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){    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        put_tag(pb, "isom");    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        put_tag(pb, "mp41");    return 0x14;}static void mov_write_uuidprof_tag(ByteIOContext *pb, AVFormatContext *s){    int AudioRate = s->streams[1]->codec->sample_rate;    int FrameRate = ((s->streams[0]->codec->time_base.den) * (0x10000))/ (s->streams[0]->codec->time_base.num);     //printf("audiorate = %d\n",AudioRate);    //printf("framerate = %d / %d = 0x%x\n",s->streams[0]->codec->time_base.den,s->streams[0]->codec->time_base.num,FrameRate);    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 );    put_tag(pb, "mp4a");    put_be32(pb, 0x20f );    put_be32(pb, 0x0 );    put_be32(pb, 0x40 );    put_be32(pb, 0x40 );    put_be32(pb, AudioRate ); //24000   ... audio rate?    put_be32(pb, 0x2 );    put_be32(pb, 0x34 );  /* size */    put_tag(pb, "VPRF");   /* video */    put_be32(pb, 0x0 );    put_be32(pb, 0x1 );    put_tag(pb, "mp4v");    put_be32(pb, 0x103 );    put_be32(pb, 0x0 );    put_be32(pb, 0xc0 );    put_be32(pb, 0xc0 );    put_be32(pb, FrameRate);  // was 0xefc29       put_be32(pb, FrameRate );  // was 0xefc29    put_be16(pb, s->streams[0]->codec->width);    put_be16(pb, s->streams[0]->codec->height);    put_be32(pb, 0x010001 );}static int mov_write_header(AVFormatContext *s){    ByteIOContext *pb = &s->pb;    MOVContext *mov = s->priv_data;    int i;    for(i=0; i<s->nb_streams; i++){        AVCodecContext *c= s->streams[i]->codec;        if      (c->codec_type == CODEC_TYPE_VIDEO){            if (!codec_get_tag(codec_movvideo_tags, c->codec_id)){                if(!codec_get_tag(codec_bmp_tags, c->codec_id))                    return -1;                else                    av_log(s, AV_LOG_INFO, "Warning, using MS style video codec tag, the file may be unplayable!\n");            }        }else if(c->codec_type == CODEC_TYPE_AUDIO){            if (!codec_get_tag(codec_movaudio_tags, c->codec_id)){                if(!codec_get_tag(codec_wav_tags, c->codec_id))                    return -1;                else                    av_log(s, AV_LOG_INFO, "Warning, using MS style audio codec tag, the file may be unplayable!\n");            }        }    }    /* 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;        if ( mov->mode == MODE_3GP || mov->mode == MODE_3G2 ||             mov->mode == MODE_MP4 || 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<MAX_STREAMS; i++) {        mov->tracks[i].mode = mov->mode;    }    put_flush_packet(pb);    return 0;}static int mov_write_packet(AVFormatContext *s, AVPacket *pkt){    MOVContext *mov = s->priv_data;    ByteIOContext *pb = &s->pb;    AVCodecContext *enc = s->streams[pkt->stream_index]->codec;    MOVTrack* trk = &mov->tracks[pkt->stream_index];    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_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[(pkt->data[len] >> 3) & 0x0F];                samplesInChunk++;            }        }        else if(enc->codec_id == CODEC_ID_PCM_ALAW) {            samplesInChunk = size/enc->channels;        }	else if(enc->codec_id == CODEC_ID_PCM_S16BE || enc->codec_id == CODEC_ID_PCM_S16LE) {	    samplesInChunk = size/(2*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 = s->timestamp + 0x7C25B080; //1970 based -> 1904 based    }    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) {        trk->cluster[cl][id].key_frame = !!(pkt->flags & PKT_FLAG_KEY);        if(trk->cluster[cl][id].key_frame)            trk->hasKeyframes = 1;    }    trk->enc = enc;    trk->entry++;    trk->sampleCount += samplesInChunk;    trk->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 */    for (i=0, j=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, 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 + -