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

📄 nut.c

📁 arm平台下的H264编码和解码源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    if (class == 32) /* AUDIO */    {        st->codec.sample_rate = (get_v(bc) * nom) / denom;        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;    }    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, 8, 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;        av_set_pts_info(s, 60, 1, AV_TIME_BASE);    /* 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(NUTContext *nut, AVPacket *pkt, int frame_code, int frame_type){    AVFormatContext *s= nut->avf;    StreamContext *stream;    ByteIOContext *bc = &s->pb;    int size, flags, size_mul, size_lsb, stream_id;    int key_frame = 0;    int64_t pts = 0;    const int prefix_len= frame_type == 2 ? 8+1 : 1;    const int64_t frame_start= url_ftell(bc) - prefix_len;    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;    if(flags & FLAG_FRAME_TYPE){        reset(s);        if(get_packetheader(nut, bc, prefix_len, 0) < 0)            return -1;        if(frame_type!=2)            frame_type= 1;    }    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= !!(flags & FLAG_KEY_FRAME);    if(flags & FLAG_PTS){        if(flags & FLAG_FULL_PTS){            pts= get_v(bc);            if(frame_type && key_frame){                int64_t av_pts= pts * AV_TIME_BASE * stream->rate_den / stream->rate_num;                av_add_index_entry(                    s->streams[stream_id],                     frame_start,                     av_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);            }        }else{            int64_t mask = (1<<stream->msb_timestamp_shift)-1;            int64_t delta= stream->last_pts - mask/2;            pts= ((get_v(bc) - delta)&mask) + delta;        }    }else{        pts= stream->last_pts + stream->lru_pts_delta[(flags&12)>>2];    }      if(size_mul <= size_lsb){        size= stream->lru_size[size_lsb - size_mul];    }else{        if(flags & FLAG_DATA_SIZE)            size= size_mul*get_v(bc) + size_lsb;        else            size= size_lsb;    }      //av_log(s, AV_LOG_DEBUG, "fs:%lld fc:%d ft:%d kf:%d pts:%lld size:%d\n", frame_start, frame_code, frame_type, key_frame, pts, size);    if(url_ftell(bc) - nut->packet_start + size > nut->written_packet_size){        av_log(s, AV_LOG_ERROR, "frame size too large\n");        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 * AV_TIME_BASE * stream->rate_den / stream->rate_num;    update(nut, stream_id, frame_start, frame_type, frame_code, key_frame, size, pts);        return 0;}static int nut_read_packet(AVFormatContext *s, AVPacket *pkt){    NUTContext *nut = s->priv_data;    ByteIOContext *bc = &s->pb;    int size, i, frame_code=0;    int64_t pos;    for(;;){        int frame_type= 0;        uint64_t tmp= nut->next_startcode;        nut->next_startcode=0;        if (url_feof(bc))            return -1;        if(!tmp){            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, 8, 0);            url_fseek(bc, nut->written_packet_size + nut->packet_start, SEEK_SET);            break;        case INFO_STARTCODE:            if(decode_info_header(nut)<0)                goto resync;            break;        case KEYFRAME_STARTCODE:            frame_type = 2;            frame_code = get_byte(bc);        case 0:            if(decode_frame(nut, pkt, frame_code, frame_type)>=0)                return 0;        default:resync:av_log(s, AV_LOG_DEBUG, "syncing from %lld\n", nut->packet_start+1);            tmp= find_any_startcode(bc, nut->packet_start+1);            if(tmp==0)                return -1;av_log(s, AV_LOG_DEBUG, "sync\n");            if(url_is_streamed(bc)){                nut->next_startcode= tmp;                break;            }            pos= url_ftell(bc) - 8;av_log(s, AV_LOG_DEBUG, "at %lld code=%llX\n", pos, tmp);            if(tmp==KEYFRAME_STARTCODE){                get_byte(bc);            }            get_v(bc);            size= get_v(bc);                        while(size > 2 && size < 100000 && nut->packet_start < pos - size){                url_fseek(bc, pos - size, SEEK_SET);                frame_code= get_byte(bc);                if(!(nut->frame_code[ frame_code ].flags & FLAG_FRAME_TYPE))                    break;                if(get_v(bc) != size)                    break;                pos -= size;                size= get_v(bc);av_log(s, AV_LOG_DEBUG, "steping back to %lld next %d\n", pos, size);            }            url_fseek(bc, pos, SEEK_SET);                        nut->written_packet_size= -1;        }    }}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, flags, stream_id, i;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;    // find a previous startcode, FIXME use forward search and follow backward pointers if undamaged stream    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(;;){        int64_t pos= url_ftell(bc);        uint64_t tmp=0;        int prefix_len=1;                if(pos > pos_limit)            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:            nut->written_packet_size= -1;            get_packetheader(nut, bc, 8, 0);            url_fseek(bc, nut->written_packet_size + nut->packet_start, SEEK_SET);            break;        case KEYFRAME_STARTCODE:            nut->written_packet_size= -1;            prefix_len+=8;            frame_code = get_byte(bc);        case 0:            flags= nut->frame_code[frame_code].flags;            stream_id= nut->frame_code[frame_code].stream_id_plus1 - 1;            if(get_packetheader(nut, bc, prefix_len, 0) < 0)                goto resync;            if(!(flags & FLAG_FRAME_TYPE) || !(flags & FLAG_PTS) || !(flags & FLAG_FULL_PTS))                goto resync;            if(stream_id==-1)                stream_id= get_v(bc);            if(stream_id >= s->nb_streams)                goto resync;                            stream= &nut->stream[stream_id];            pts= get_v(bc) * AV_TIME_BASE * stream->rate_den / stream->rate_num;                if(flags & FLAG_KEY_FRAME){                av_add_index_entry(                    s->streams[stream_id],                     pos,                     pts,                     pos - nut->stream[stream_id].last_sync_pos,                    AVINDEX_KEYFRAME);                nut->stream[stream_id].last_sync_pos= pos;            }            if(stream_id != stream_index || !(flags & FLAG_KEY_FRAME) || nut->packet_start < *pos_arg){                url_fseek(bc, nut->written_packet_size + nut->packet_start, SEEK_SET);                break;            }             *pos_arg= nut->packet_start;            assert(nut->packet_start == pos);            return pts;        default:resync:av_log(s, AV_LOG_DEBUG, "syncing from %lld\n", nut->packet_start+1);            if(!find_any_startcode(bc, nut->packet_start+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;    int i;    if(av_seek_frame_binary(s, stream_index, target_ts) < 0)        return -1;    nut->written_packet_size= -1;    pos= url_ftell(&s->pb);    for(i=0; i<s->nb_streams; i++)        nut->stream[i].last_sync_pos= pos;    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 + -