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

📄 nut.c

📁 FFmpeg is an audio/video conversion tool. It includes libavcodec, the leading open source codec libr
💻 C
📖 第 1 页 / 共 3 页
字号:
        size += 4;        if(size != nut->written_packet_size){        int i;        assert( size <= nut->written_packet_size );            url_fseek(bc, start + 8, SEEK_SET);        for(i=get_length(size); i < get_length(nut->written_packet_size); i+=7)            put_byte(bc, 0x80);        put_v(bc, size);        url_fseek(bc, cur, SEEK_SET);        nut->written_packet_size= size; //FIXME may fail if multiple updates with differing sizes, as get_length may differ                if(calculate_checksum)            put_be32(bc, get_checksum(bc));    }        return 0;}static int nut_write_header(AVFormatContext *s){    NUTContext *nut = s->priv_data;    ByteIOContext *bc = &s->pb;    AVCodecContext *codec;    int i, j, tmp_time, tmp_flags,tmp_stream, tmp_mul, tmp_size, tmp_fields;    nut->avf= s;        nut->stream =		av_mallocz(sizeof(StreamContext)*s->nb_streams);            put_buffer(bc, ID_STRING, strlen(ID_STRING));    put_byte(bc, 0);    nut->packet_start[2]= url_ftell(bc);        /* main header */    put_be64(bc, MAIN_STARTCODE);    put_packetheader(nut, bc, 120+5*256, 1);    put_v(bc, 2); /* version */    put_v(bc, s->nb_streams);    put_v(bc, MAX_DISTANCE);    put_v(bc, MAX_SHORT_DISTANCE);        put_v(bc, nut->rate_num=1);    put_v(bc, nut->rate_den=2);    put_v(bc, nut->short_startcode=0x4EFE79);        build_frame_code(s);    assert(nut->frame_code['N'].flags == FLAG_INVALID);        tmp_time= tmp_flags= tmp_stream= tmp_mul= tmp_size= /*tmp_res=*/ INT_MAX;    for(i=0; i<256;){        tmp_fields=0;        tmp_size= 0;        if(tmp_time   != nut->frame_code[i].timestamp_delta) tmp_fields=1;        if(tmp_mul    != nut->frame_code[i].size_mul       ) tmp_fields=2;        if(tmp_stream != nut->frame_code[i].stream_id_plus1) tmp_fields=3;        if(tmp_size   != nut->frame_code[i].size_lsb       ) tmp_fields=4;//        if(tmp_res    != nut->frame_code[i].res            ) tmp_fields=5;        tmp_time  = nut->frame_code[i].timestamp_delta;        tmp_flags = nut->frame_code[i].flags;        tmp_stream= nut->frame_code[i].stream_id_plus1;        tmp_mul   = nut->frame_code[i].size_mul;        tmp_size  = nut->frame_code[i].size_lsb;//        tmp_res   = nut->frame_code[i].res;                for(j=0; i<256; j++,i++){            if(nut->frame_code[i].timestamp_delta != tmp_time  ) break;            if(nut->frame_code[i].flags           != tmp_flags ) break;            if(nut->frame_code[i].stream_id_plus1 != tmp_stream) break;            if(nut->frame_code[i].size_mul        != tmp_mul   ) break;            if(nut->frame_code[i].size_lsb        != tmp_size+j) break;//            if(nut->frame_code[i].res             != tmp_res   ) break;        }        if(j != tmp_mul - tmp_size) tmp_fields=6;        put_v(bc, tmp_flags);        put_v(bc, tmp_fields);        if(tmp_fields>0) put_s(bc, tmp_time);        if(tmp_fields>1) put_v(bc, tmp_mul);        if(tmp_fields>2) put_v(bc, tmp_stream);        if(tmp_fields>3) put_v(bc, tmp_size);        if(tmp_fields>4) put_v(bc, 0 /*tmp_res*/);        if(tmp_fields>5) put_v(bc, j);    }    update_packetheader(nut, bc, 0, 1);        /* stream headers */    for (i = 0; i < s->nb_streams; i++)    {	int nom, denom, gcd;	codec = &s->streams[i]->codec;		put_be64(bc, STREAM_STARTCODE);	put_packetheader(nut, bc, 120 + codec->extradata_size, 1);	put_v(bc, i /*s->streams[i]->index*/);	put_v(bc, (codec->codec_type == CODEC_TYPE_AUDIO) ? 32 : 0);	if (codec->codec_tag)	    put_vb(bc, codec->codec_tag);	else if (codec->codec_type == CODEC_TYPE_VIDEO)	{	    put_vb(bc, codec_get_bmp_tag(codec->codec_id));	}	else if (codec->codec_type == CODEC_TYPE_AUDIO)	{	    put_vb(bc, codec_get_wav_tag(codec->codec_id));	}        else            put_vb(bc, 0);	if (codec->codec_type == CODEC_TYPE_VIDEO)	{	    nom = codec->frame_rate;	    denom = codec->frame_rate_base;	}	else	{	    nom = codec->sample_rate;            if(codec->frame_size>0)                denom= codec->frame_size;            else                denom= 1; //unlucky	}        gcd= ff_gcd(nom, denom);        nom   /= gcd;        denom /= gcd;        nut->stream[i].rate_num= nom;        nut->stream[i].rate_den= denom;        av_set_pts_info(s->streams[i], 60, denom, nom);	put_v(bc, codec->bit_rate);	put_vb(bc, 0); /* no language code */	put_v(bc, nom);	put_v(bc, denom);        if(nom / denom < 1000)	    nut->stream[i].msb_timestamp_shift = 7;        else	    nut->stream[i].msb_timestamp_shift = 14;	put_v(bc, nut->stream[i].msb_timestamp_shift);        put_v(bc, codec->has_b_frames);	put_byte(bc, 0); /* flags: 0x1 - fixed_fps, 0x2 - index_present */	        if(codec->extradata_size){            put_v(bc, 1);            put_v(bc, codec->extradata_size);            put_buffer(bc, codec->extradata, codec->extradata_size);                    }	put_v(bc, 0); /* end of codec specific headers */		switch(codec->codec_type)	{	    case CODEC_TYPE_AUDIO:		put_v(bc, codec->sample_rate);		put_v(bc, 1);		put_v(bc, codec->channels);		break;	    case CODEC_TYPE_VIDEO:		put_v(bc, codec->width);		put_v(bc, codec->height);		put_v(bc, codec->sample_aspect_ratio.num);		put_v(bc, codec->sample_aspect_ratio.den);		put_v(bc, 0); /* csp type -- unknown */		break;            default:                break;	}        update_packetheader(nut, bc, 0, 1);    }    /* info header */    put_be64(bc, INFO_STARTCODE);    put_packetheader(nut, bc, 30+strlen(s->author)+strlen(s->title)+        strlen(s->comment)+strlen(s->copyright)+strlen(LIBAVFORMAT_IDENT), 1);     if (s->author[0])    {        put_v(bc, 9); /* type */        put_str(bc, s->author);    }    if (s->title[0])    {        put_v(bc, 10); /* type */        put_str(bc, s->title);    }    if (s->comment[0])    {        put_v(bc, 11); /* type */        put_str(bc, s->comment);    }    if (s->copyright[0])    {        put_v(bc, 12); /* type */        put_str(bc, s->copyright);    }    /* encoder */    if(!(s->streams[0]->codec.flags & CODEC_FLAG_BITEXACT)){        put_v(bc, 13); /* type */        put_str(bc, LIBAVFORMAT_IDENT);    }        put_v(bc, 0); /* eof info */    update_packetheader(nut, bc, 0, 1);            put_flush_packet(bc);        return 0;}static int64_t lsb2full(StreamContext *stream, int64_t lsb){    int64_t mask = (1<<stream->msb_timestamp_shift)-1;    int64_t delta= stream->last_pts - mask/2;    return  ((lsb - delta)&mask) + delta;}static int nut_write_packet(AVFormatContext *s, AVPacket *pkt){    NUTContext *nut = s->priv_data;    StreamContext *stream= &nut->stream[pkt->stream_index];    ByteIOContext *bc = &s->pb;    int key_frame = 0, full_pts=0;    AVCodecContext *enc;    int64_t coded_pts;    int frame_type, best_length, frame_code, flags, i, size_mul, size_lsb, time_delta;    const int64_t frame_start= url_ftell(bc);    int64_t pts= pkt->pts;    int size= pkt->size;    int stream_index= pkt->stream_index;    enc = &s->streams[stream_index]->codec;    key_frame = !!(pkt->flags & PKT_FLAG_KEY);        frame_type=0;    if(frame_start + size + 20 - FFMAX(nut->packet_start[1], nut->packet_start[2]) > MAX_DISTANCE)        frame_type=2;    if(key_frame && !stream->last_key_frame)        frame_type=2;    if(frame_type>1){        int64_t global_ts= av_rescale(pts, stream->rate_den*(int64_t)nut->rate_num, stream->rate_num*(int64_t)nut->rate_den);        reset(s, global_ts);	put_be64(bc, KEYFRAME_STARTCODE);        put_v(bc, global_ts);    }    assert(stream->last_pts != AV_NOPTS_VALUE);    coded_pts = pts & ((1<<stream->msb_timestamp_shift)-1);    if(lsb2full(stream, coded_pts) != pts)        full_pts=1;    if(full_pts)        coded_pts= pts + (1<<stream->msb_timestamp_shift);    best_length=INT_MAX;    frame_code= -1;    for(i=0; i<256; i++){        int stream_id_plus1= nut->frame_code[i].stream_id_plus1;        int fc_key_frame;        int length=0;        size_mul= nut->frame_code[i].size_mul;        size_lsb= nut->frame_code[i].size_lsb;        time_delta= nut->frame_code[i].timestamp_delta;        flags= nut->frame_code[i].flags;        assert(size_mul > size_lsb);                if(stream_id_plus1 == 0) length+= get_length(stream_index);        else if(stream_id_plus1 - 1 != stream_index)            continue;        fc_key_frame= !!(flags & FLAG_KEY_FRAME);        assert(key_frame==0 || key_frame==1);        if(fc_key_frame != key_frame)            continue;        if(flags & FLAG_DATA_SIZE){            if(size % size_mul != size_lsb)                continue;            length += get_length(size / size_mul);        }else if(size != size_lsb)            continue;        if(full_pts && time_delta)            continue;                    if(!time_delta){            length += get_length(coded_pts);        }else{            if(time_delta != pts - stream->last_pts)                continue;        }        if(length < best_length){            best_length= length;            frame_code=i;        }//    av_log(s, AV_LOG_DEBUG, "%d %d %d %d %d %d %d %d %d %d\n", key_frame, frame_type, full_pts, size, stream_index, flags, size_mul, size_lsb, stream_id_plus1, length);    }    assert(frame_code != -1);    flags= nut->frame_code[frame_code].flags;    size_mul= nut->frame_code[frame_code].size_mul;    size_lsb= nut->frame_code[frame_code].size_lsb;    time_delta= nut->frame_code[frame_code].timestamp_delta;#ifdef TRACE    best_length /= 7;    best_length ++; //frame_code    if(frame_type==2){        best_length += 8; // startcode    }    av_log(s, AV_LOG_DEBUG, "kf:%d ft:%d pt:%d fc:%2X len:%2d size:%d stream:%d flag:%d mul:%d lsb:%d s+1:%d pts_delta:%d pts:%lld fs:%lld\n", key_frame, frame_type, full_pts ? 1 : 0, frame_code, best_length, size, stream_index, flags, size_mul, size_lsb, nut->frame_code[frame_code].stream_id_plus1,(int)(pts - stream->last_pts), pts, frame_start);//    av_log(s, AV_LOG_DEBUG, "%d %d %d\n", stream->lru_pts_delta[0], stream->lru_pts_delta[1], stream->lru_pts_delta[2]);#endif    assert(frame_type != 1); //short startcode not implemented yet    put_byte(bc, frame_code);    if(nut->frame_code[frame_code].stream_id_plus1 == 0)        put_v(bc, stream_index);    if (!time_delta){        put_v(bc, coded_pts);    }    if(flags & FLAG_DATA_SIZE)        put_v(bc, size / size_mul);    else        assert(size == size_lsb);    if(size > MAX_DISTANCE){        assert(frame_type > 1);    }        put_buffer(bc, pkt->data, size);    update(nut, stream_index, frame_start, frame_type, frame_code, key_frame, size, pts);        return 0;}static int nut_write_trailer(AVFormatContext *s){    NUTContext *nut = s->priv_data;    ByteIOContext *bc = &s->pb;#if 0    int i;    /* WRITE INDEX */    for (i = 0; s->nb_streams; i++)    {	put_be64(bc, INDEX_STARTCODE);	put_packetheader(nut, bc, 64, 1);	put_v(bc, s->streams[i]->id);	put_v(bc, ...);        update_packetheader(nut, bc, 0, 1);    }#endif    put_flush_packet(bc);        av_freep(&nut->stream);    return 0;}#endif //CONFIG_ENCODERSstatic int nut_probe(AVProbeData *p){    int i;    uint64_t code= 0xff;    for (i = 0; i < p->buf_size; i++) {        code = (code << 8) | p->buf[i];        if (code == MAIN_STARTCODE)            return AVPROBE_SCORE_MAX;    }    return 0;}static int decode_main_header(NUTContext *nut){    AVFormatContext *s= nut->avf;    ByteIOContext *bc = &s->pb;    uint64_t tmp;    int i, j, tmp_stream, tmp_mul, tmp_time, tmp_size, count, tmp_res;        get_packetheader(nut, bc, 1);    tmp = get_v(bc);    if (tmp != 2){	av_log(s, AV_LOG_ERROR, "bad version (%Ld)\n", tmp);        return -1;    }        nut->stream_count = get_v(bc);    nut->max_distance = get_v(bc);    nut->max_short_distance = get_v(bc);    nut->rate_num= get_v(bc);    nut->rate_den= get_v(bc);    nut->short_startcode= get_v(bc);    if(nut->short_startcode>>16 != 'N'){	av_log(s, AV_LOG_ERROR, "invalid short startcode %X\n", nut->short_startcode);        return -1;    }        for(i=0; i<256;){        int tmp_flags = get_v(bc);        int tmp_fields= get_v(bc);        if(tmp_fields>0) tmp_time  = get_s(bc);        if(tmp_fields>1) tmp_mul   = get_v(bc);        if(tmp_fields>2) tmp_stream= get_v(bc);        if(tmp_fields>3) tmp_size  = get_v(bc);        else             tmp_size  = 0;        if(tmp_fields>4) tmp_res   = get_v(bc);        else             tmp_res   = 0;        if(tmp_fields>5) count     = get_v(bc);        else             count     = tmp_mul - tmp_size;                while(tmp_fields-- > 6)            get_v(bc);                if(count == 0 || i+count > 256){            av_log(s, AV_LOG_ERROR, "illegal count %d at %d\n", count, i);            return -1;        }        if(tmp_stream > nut->stream_count + 1){            av_log(s, AV_LOG_ERROR, "illegal stream number\n");            return -1;        }        for(j=0; j<count; j++,i++){            nut->frame_code[i].flags           = tmp_flags ;            nut->frame_code[i].timestamp_delta = tmp_time  ;            nut->frame_code[i].stream_id_plus1 = tmp_stream;            nut->frame_code[i].size_mul        = tmp_mul   ;            nut->frame_code[i].size_lsb        = tmp_size+j;            nut->frame_code[i].reserved_count  = tmp_res   ;        }    }    if(nut->frame_code['N'].flags != FLAG_INVALID){        av_log(s, AV_LOG_ERROR, "illegal frame_code table\n");        return -1;    }    if(check_checksum(bc)){        av_log(s, AV_LOG_ERROR, "Main header checksum missmatch\n");        return -1;    }    return 0;}static int decode_stream_header(NUTContext *nut){    AVFormatContext *s= nut->avf;    ByteIOContext *bc = &s->pb;    int class, nom, denom, stream_id;    uint64_t tmp;    AVStream *st;        get_packetheader(nut, bc, 1);    stream_id= get_v(bc);    if(stream_id >= nut->stream_count || s->streams[stream_id])        return -1;        st = av_new_stream(s, stream_id);    if (!st)        return AVERROR_NOMEM;    class = get_v(bc);    tmp = get_vb(bc);    st->codec.codec_tag= tmp;    switch(class)    {        case 0:            st->codec.codec_type = CODEC_TYPE_VIDEO;            st->codec.codec_id = codec_get_bmp_id(tmp);            if (st->codec.codec_id == CODEC_ID_NONE)                av_log(s, AV_LOG_ERROR, "Unknown codec?!\n");            break;        case 32:

⌨️ 快捷键说明

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