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

📄 nut.c

📁 FFmpeg is an audio/video conversion tool. It includes libavcodec, the leading open source codec libr
💻 C
📖 第 1 页 / 共 3 页
字号:
            st->codec.codec_type = CODEC_TYPE_AUDIO;            st->codec.codec_id = codec_get_wav_id(tmp);            if (st->codec.codec_id == CODEC_ID_NONE)                av_log(s, AV_LOG_ERROR, "Unknown codec?!\n");            break;        default:            av_log(s, AV_LOG_ERROR, "Unknown stream class (%d)\n", class);            return -1;    }    s->bit_rate += get_v(bc);    get_vb(bc); /* language code */    nom = get_v(bc);    denom = get_v(bc);    nut->stream[stream_id].msb_timestamp_shift = get_v(bc);    nut->stream[stream_id].decode_delay= get_v(bc);    get_byte(bc); /* flags */    /* codec specific data headers */    while(get_v(bc) != 0){        st->codec.extradata_size= get_v(bc);        st->codec.extradata= av_mallocz(st->codec.extradata_size);        get_buffer(bc, st->codec.extradata, st->codec.extradata_size);            //	    url_fskip(bc, get_v(bc));    }        if (class == 0) /* VIDEO */    {        st->codec.width = get_v(bc);        st->codec.height = get_v(bc);        st->codec.sample_aspect_ratio.num= get_v(bc);        st->codec.sample_aspect_ratio.den= get_v(bc);        get_v(bc); /* csp type */        st->codec.frame_rate = nom;        st->codec.frame_rate_base = denom;    }    if (class == 32) /* AUDIO */    {        st->codec.sample_rate = get_v(bc);        get_v(bc); // samplerate_den        st->codec.channels = get_v(bc);    }    if(check_checksum(bc)){        av_log(s, AV_LOG_ERROR, "Stream header %d checksum missmatch\n", stream_id);        return -1;    }    av_set_pts_info(s->streams[stream_id], 60, denom, nom);    nut->stream[stream_id].rate_num= nom;    nut->stream[stream_id].rate_den= denom;    return 0;}static int decode_info_header(NUTContext *nut){    AVFormatContext *s= nut->avf;    ByteIOContext *bc = &s->pb;        get_packetheader(nut, bc, 1);    for(;;){        int id= get_v(bc);        char *name, *type, custom_name[256], custom_type[256];        if(!id)            break;        else if(id >= sizeof(info_table)/sizeof(info_table[0])){            av_log(s, AV_LOG_ERROR, "info id is too large %d %d\n", id, sizeof(info_table)/sizeof(info_table[0]));            return -1;        }        type= info_table[id][1];        name= info_table[id][0];//av_log(s, AV_LOG_DEBUG, "%d %s %s\n", id, type, name);        if(!type){            get_str(bc, custom_type, sizeof(custom_type));            type= custom_type;        }        if(!name){            get_str(bc, custom_name, sizeof(custom_name));            name= custom_name;        }                if(!strcmp(type, "v")){            int value= get_v(bc);        }else{            if(!strcmp(name, "Author"))                get_str(bc, s->author, sizeof(s->author));            else if(!strcmp(name, "Title"))                get_str(bc, s->title, sizeof(s->title));            else if(!strcmp(name, "Copyright"))                get_str(bc, s->copyright, sizeof(s->copyright));            else if(!strcmp(name, "Description"))                get_str(bc, s->comment, sizeof(s->comment));            else                get_str(bc, NULL, 0);        }    }    if(check_checksum(bc)){        av_log(s, AV_LOG_ERROR, "Info header checksum missmatch\n");        return -1;    }    return 0;}static int nut_read_header(AVFormatContext *s, AVFormatParameters *ap){    NUTContext *nut = s->priv_data;    ByteIOContext *bc = &s->pb;    int64_t pos;    int inited_stream_count;    nut->avf= s;        /* main header */    pos=0;    for(;;){        pos= find_startcode(bc, MAIN_STARTCODE, pos)+1;        if (pos<0){            av_log(s, AV_LOG_ERROR, "no main startcode found\n");            return -1;        }        if(decode_main_header(nut) >= 0)            break;    }            s->bit_rate = 0;    nut->stream = av_malloc(sizeof(StreamContext)*nut->stream_count);    /* stream headers */    pos=0;    for(inited_stream_count=0; inited_stream_count < nut->stream_count;){        pos= find_startcode(bc, STREAM_STARTCODE, pos)+1;        if (pos<0){            av_log(s, AV_LOG_ERROR, "not all stream headers found\n");            return -1;        }        if(decode_stream_header(nut) >= 0)            inited_stream_count++;    }    /* info headers */    pos=0;    for(;;){        uint64_t startcode= find_any_startcode(bc, pos);        pos= url_ftell(bc);        if(startcode==0){            av_log(s, AV_LOG_ERROR, "EOF before video frames\n");            return -1;        }else if(startcode == KEYFRAME_STARTCODE){            nut->next_startcode= startcode;            break;        }else if(startcode != INFO_STARTCODE){            continue;        }        decode_info_header(nut);    }    return 0;}static int decode_frame_header(NUTContext *nut, int *key_frame_ret, int64_t *pts_ret, int *stream_id_ret, int frame_code, int frame_type, int64_t frame_start){    AVFormatContext *s= nut->avf;    StreamContext *stream;    ByteIOContext *bc = &s->pb;    int size, flags, size_mul, size_lsb, stream_id, time_delta;    int64_t pts = 0;    if(frame_type < 2 && frame_start - nut->packet_start[2] > nut->max_distance){        av_log(s, AV_LOG_ERROR, "last frame must have been damaged\n");        return -1;    }    if(frame_type)        nut->packet_start[ frame_type ]= frame_start; //otherwise 1 goto 1 may happen        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;    stream_id= nut->frame_code[frame_code].stream_id_plus1 - 1;    time_delta= nut->frame_code[frame_code].timestamp_delta;        if(stream_id==-1)        stream_id= get_v(bc);    if(stream_id >= s->nb_streams){        av_log(s, AV_LOG_ERROR, "illegal stream_id\n");        return -1;    }    stream= &nut->stream[stream_id];//    av_log(s, AV_LOG_DEBUG, "ft:%d ppts:%d %d %d\n", frame_type, stream->lru_pts_delta[0], stream->lru_pts_delta[1], stream->lru_pts_delta[2]);    *key_frame_ret= !!(flags & FLAG_KEY_FRAME);    if(!time_delta){        int64_t mask = (1<<stream->msb_timestamp_shift)-1;        pts= get_v(bc);        if(pts > mask){            pts -= mask+1;        }else{            if(stream->last_pts == AV_NOPTS_VALUE){                av_log(s, AV_LOG_ERROR, "no reference pts available\n");                return -1;            }            pts= lsb2full(stream, pts);        }    }else{        if(stream->last_pts == AV_NOPTS_VALUE){            av_log(s, AV_LOG_ERROR, "no reference pts available\n");            return -1;        }        pts= stream->last_pts + time_delta;    }    if(*key_frame_ret){//        av_log(s, AV_LOG_DEBUG, "stream:%d start:%lld pts:%lld length:%lld\n",stream_id, frame_start, av_pts, frame_start - nut->stream[stream_id].last_sync_pos);        av_add_index_entry(            s->streams[stream_id],             frame_start,             pts,             frame_start - nut->stream[stream_id].last_sync_pos,            AVINDEX_KEYFRAME);        nut->stream[stream_id].last_sync_pos= frame_start;//                assert(nut->packet_start == frame_start);    }    assert(size_mul > size_lsb);    size= size_lsb;    if(flags & FLAG_DATA_SIZE)        size+= size_mul*get_v(bc);      #ifdef TRACEav_log(s, AV_LOG_DEBUG, "fs:%lld fc:%d ft:%d kf:%d pts:%lld size:%d mul:%d lsb:%d flags:%d delta:%d\n", frame_start, frame_code, frame_type, *key_frame_ret, pts, size, size_mul, size_lsb, flags, time_delta);#endif    if(frame_type==0 && url_ftell(bc) - nut->packet_start[2] + size > nut->max_distance){        av_log(s, AV_LOG_ERROR, "frame size too large\n");        return -1;    }        *stream_id_ret = stream_id;    *pts_ret = pts;    update(nut, stream_id, frame_start, frame_type, frame_code, *key_frame_ret, size, pts);    return size;}static int decode_frame(NUTContext *nut, AVPacket *pkt, int frame_code, int frame_type, int64_t frame_start){    AVFormatContext *s= nut->avf;    ByteIOContext *bc = &s->pb;    int size, stream_id, key_frame;    int64_t pts;        size= decode_frame_header(nut, &key_frame, &pts, &stream_id, frame_code, frame_type, frame_start);    if(size < 0)        return -1;    av_new_packet(pkt, size);    get_buffer(bc, pkt->data, size);    pkt->stream_index = stream_id;    if (key_frame)	pkt->flags |= PKT_FLAG_KEY;    pkt->pts = pts;    return 0;}static int nut_read_packet(AVFormatContext *s, AVPacket *pkt){    NUTContext *nut = s->priv_data;    ByteIOContext *bc = &s->pb;    int i, frame_code=0;    for(;;){        int64_t pos= url_ftell(bc);        int frame_type= 0;        uint64_t tmp= nut->next_startcode;        nut->next_startcode=0;        if (url_feof(bc))            return -1;        if(tmp){            pos-=8;        }else{            frame_code = get_byte(bc);            if(frame_code == 'N'){                tmp= frame_code;                for(i=1; i<8; i++)                    tmp = (tmp<<8) + get_byte(bc);            }        }        switch(tmp){        case MAIN_STARTCODE:        case STREAM_STARTCODE:        case INDEX_STARTCODE:            get_packetheader(nut, bc, 0);            assert(nut->packet_start[2] == pos);            url_fseek(bc, nut->written_packet_size + nut->packet_start[2], SEEK_SET);            break;        case INFO_STARTCODE:            if(decode_info_header(nut)<0)                goto resync;            break;        case KEYFRAME_STARTCODE:            frame_type = 2;            reset(s, get_v(bc));            frame_code = get_byte(bc);        case 0:            if(decode_frame(nut, pkt, frame_code, frame_type, pos)>=0)                return 0;        default:resync:av_log(s, AV_LOG_DEBUG, "syncing from %lld\n", nut->packet_start[2]+1);            tmp= find_any_startcode(bc, nut->packet_start[2]+1);            if(tmp==0)                return -1;av_log(s, AV_LOG_DEBUG, "sync\n");            nut->next_startcode= tmp;        }    }}static int64_t nut_read_timestamp(AVFormatContext *s, int stream_index, int64_t *pos_arg, int64_t pos_limit){    NUTContext *nut = s->priv_data;    StreamContext *stream;    ByteIOContext *bc = &s->pb;    int64_t pos, pts;    uint64_t code;    int frame_code,step, stream_id, i,size, key_frame;av_log(s, AV_LOG_DEBUG, "read_timestamp(X,%d,%lld,%lld)\n", stream_index, *pos_arg, pos_limit);    if(*pos_arg < 0)        return AV_NOPTS_VALUE;    pos= *pos_arg;    step= FFMIN(16*1024, pos);    do{        pos-= step;        code= find_any_startcode(bc, pos);        if(code && url_ftell(bc) - 8 <= *pos_arg)            break;        step= FFMIN(2*step, pos);    }while(step);    if(!code) //nothing found, not even after pos_arg        return AV_NOPTS_VALUE;    url_fseek(bc, -8, SEEK_CUR);    for(i=0; i<s->nb_streams; i++)        nut->stream[i].last_sync_pos= url_ftell(bc);            for(;;){        int frame_type=0;        int64_t pos= url_ftell(bc);        uint64_t tmp=0;                if(pos > pos_limit || url_feof(bc))            return AV_NOPTS_VALUE;        frame_code = get_byte(bc);        if(frame_code == 'N'){            tmp= frame_code;            for(i=1; i<8; i++)                tmp = (tmp<<8) + get_byte(bc);        }//av_log(s, AV_LOG_DEBUG, "before switch %llX at=%lld\n", tmp, pos);        switch(tmp){        case MAIN_STARTCODE:        case STREAM_STARTCODE:        case INDEX_STARTCODE:        case INFO_STARTCODE:            get_packetheader(nut, bc, 0);            assert(nut->packet_start[2]==pos);            url_fseek(bc, nut->written_packet_size + pos, SEEK_SET);            break;        case KEYFRAME_STARTCODE:            frame_type=2;            reset(s, get_v(bc));            frame_code = get_byte(bc);        case 0:            size= decode_frame_header(nut, &key_frame, &pts, &stream_id, frame_code, frame_type, pos);            if(size < 0)                goto resync;                            stream= &nut->stream[stream_id];            if(stream_id != stream_index || !key_frame || pos < *pos_arg){                url_fseek(bc, size, SEEK_CUR);                break;            }             *pos_arg= pos;            return pts;        default:resync:av_log(s, AV_LOG_DEBUG, "syncing from %lld\n", nut->packet_start[2]+1);            if(!find_any_startcode(bc, nut->packet_start[2]+1))                return AV_NOPTS_VALUE;            url_fseek(bc, -8, SEEK_CUR);        }    }    return AV_NOPTS_VALUE;}static int nut_read_seek(AVFormatContext *s, int stream_index, int64_t target_ts){//    NUTContext *nut = s->priv_data;    int64_t pos;    if(av_seek_frame_binary(s, stream_index, target_ts) < 0)        return -1;    pos= url_ftell(&s->pb);    nut_read_timestamp(s, stream_index, &pos, pos-1);    return 0;}static int nut_read_close(AVFormatContext *s){    NUTContext *nut = s->priv_data;    int i;    for(i=0;i<s->nb_streams;i++) {        av_freep(&s->streams[i]->codec.extradata);    }    av_freep(&nut->stream);    return 0;}static AVInputFormat nut_iformat = {    "nut",    "nut format",    sizeof(NUTContext),    nut_probe,    nut_read_header,    nut_read_packet,    nut_read_close,    nut_read_seek,    nut_read_timestamp,    .extensions = "nut",};#ifdef CONFIG_ENCODERSstatic AVOutputFormat nut_oformat = {    "nut",    "nut format",    "video/x-nut",    "nut",    sizeof(NUTContext),#ifdef CONFIG_VORBIS    CODEC_ID_VORBIS,#elif defined(CONFIG_MP3LAME)    CODEC_ID_MP3,#else    CODEC_ID_MP2, /* AC3 needs liba52 decoder */#endif    CODEC_ID_MPEG4,    nut_write_header,    nut_write_packet,    nut_write_trailer,};#endif //CONFIG_ENCODERSint nut_init(void){    av_register_input_format(&nut_iformat);#ifdef CONFIG_ENCODERS    av_register_output_format(&nut_oformat);#endif //CONFIG_ENCODERS    return 0;}

⌨️ 快捷键说明

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