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

📄 avidec.c

📁 FFmpeg is an audio/video conversion tool. It includes libavcodec, the leading open source codec libr
💻 C
📖 第 1 页 / 共 2 页
字号:
    memset(d, -1, sizeof(int)*8);       if (avi->dv_demux) {        size = dv_get_packet(avi->dv_demux, pkt);	if (size >= 0)	    return size;    }            for(i=url_ftell(pb); !url_feof(pb); i++) {        int j;	if (i >= avi->movi_end) { /* Let's see if it's an OpenDML AVI */	    uint32_t tag, size, tag2;	    url_fskip(pb, avi->riff_end - url_ftell(pb));	    if (get_riff(avi, pb) < 0)	        return -1;	    	    tag = get_le32(pb);	    size = get_le32(pb);	    tag2 = get_le32(pb);	    if (tag == MKTAG('L','I','S','T') && tag2 == MKTAG('m','o','v','i'))	        avi->movi_end = url_ftell(pb) + size - 4; 	    else	        return -1;	}        for(j=0; j<7; j++)            d[j]= d[j+1];        d[7]= get_byte(pb);                size= d[4] + (d[5]<<8) + (d[6]<<16) + (d[7]<<24);                //parse ix##        n= (d[2] - '0') * 10 + (d[3] - '0');        if(    d[2] >= '0' && d[2] <= '9'            && d[3] >= '0' && d[3] <= '9'            && d[0] == 'i' && d[1] == 'x'            && n < s->nb_streams            && i + size <= avi->movi_end){                        url_fskip(pb, size);        }                //parse ##dc/##wb        n= (d[0] - '0') * 10 + (d[1] - '0');        if(    d[0] >= '0' && d[0] <= '9'            && d[1] >= '0' && d[1] <= '9'            && ((d[2] == 'd' && d[3] == 'c') || 	        (d[2] == 'w' && d[3] == 'b') || 		(d[2] == 'd' && d[3] == 'b') ||		(d[2] == '_' && d[3] == '_'))            && n < s->nb_streams            && i + size <= avi->movi_end) {                    av_new_packet(pkt, size);            get_buffer(pb, pkt->data, size);            if (size & 1) {                get_byte(pb);		size++;	    }		    if (avi->dv_demux) {	        dstr = pkt->destruct;	        size = dv_produce_packet(avi->dv_demux, pkt,		                         pkt->data, pkt->size);		pkt->destruct = dstr;                pkt->flags |= PKT_FLAG_KEY;	    } else {                AVStream *st;                AVIStream *ast;                st = s->streams[n];                ast = st->priv_data;                                /* XXX: how to handle B frames in avi ? */                pkt->dts = ast->frame_offset;//                pkt->dts += ast->start;                if(ast->sample_size)                    pkt->dts /= ast->sample_size;//av_log(NULL, AV_LOG_DEBUG, "dts:%Ld offset:%d %d/%d %d st:%d size:%d\n", pkt->dts, ast->frame_offset, ast->scale, ast->rate, AV_TIME_BASE, n, size);                pkt->stream_index = n;                /* FIXME: We really should read index for that */                if (st->codec.codec_type == CODEC_TYPE_VIDEO) {                    if (ast->frame_offset < ast->nb_index_entries) {                        if (ast->index_entries[ast->frame_offset].flags & AVIIF_INDEX)                            pkt->flags |= PKT_FLAG_KEY;                     } else {                        /* if no index, better to say that all frames                           are key frames */                        pkt->flags |= PKT_FLAG_KEY;                    }                } else {                    pkt->flags |= PKT_FLAG_KEY;                 }                if(ast->sample_size)                    ast->frame_offset += pkt->size;                else                    ast->frame_offset++;	    }            return size;        }    }    return -1;}/* XXX: we make the implicit supposition that the position are sorted   for each stream */static int avi_read_idx1(AVFormatContext *s, int size){    ByteIOContext *pb = &s->pb;    int nb_index_entries, i;    AVStream *st;    AVIStream *ast;    AVIIndexEntry *ie, *entries;    unsigned int index, tag, flags, pos, len;        nb_index_entries = size / 16;    if (nb_index_entries <= 0)        return -1;    /* read the entries and sort them in each stream component */    for(i = 0; i < nb_index_entries; i++) {        tag = get_le32(pb);        flags = get_le32(pb);        pos = get_le32(pb);        len = get_le32(pb);#if defined(DEBUG_SEEK) && 0        printf("%d: tag=0x%x flags=0x%x pos=0x%x len=%d\n",                i, tag, flags, pos, len);#endif        index = ((tag & 0xff) - '0') * 10;        index += ((tag >> 8) & 0xff) - '0';        if (index >= s->nb_streams)            continue;        st = s->streams[index];        ast = st->priv_data;                entries = av_fast_realloc(ast->index_entries,                                  &ast->index_entries_allocated_size,                                  (ast->nb_index_entries + 1) *                                   sizeof(AVIIndexEntry));        if (entries) {            ast->index_entries = entries;            ie = &entries[ast->nb_index_entries++];            ie->flags = flags;            ie->pos = pos;            ie->cum_len = ast->cum_len;            ast->cum_len += len;        }    }    return 0;}static int avi_load_index(AVFormatContext *s){    AVIContext *avi = s->priv_data;    ByteIOContext *pb = &s->pb;    uint32_t tag, size;    offset_t pos= url_ftell(pb);        url_fseek(pb, avi->movi_end, SEEK_SET);#ifdef DEBUG_SEEK    printf("movi_end=0x%llx\n", avi->movi_end);#endif    for(;;) {        if (url_feof(pb))            break;        tag = get_le32(pb);        size = get_le32(pb);#ifdef DEBUG_SEEK        printf("tag=%c%c%c%c size=0x%x\n",               tag & 0xff,               (tag >> 8) & 0xff,               (tag >> 16) & 0xff,               (tag >> 24) & 0xff,               size);#endif        switch(tag) {        case MKTAG('i', 'd', 'x', '1'):            if (avi_read_idx1(s, size) < 0)                goto skip;            else                goto the_end;            break;        default:        skip:            size += (size & 1);            url_fskip(pb, size);            break;        }    } the_end:    url_fseek(pb, pos, SEEK_SET);    return 0;}/* return the index entry whose position is immediately >= 'wanted_pos' */static int locate_frame_in_index(AVIIndexEntry *entries,                                  int nb_entries, int wanted_pos){    int a, b, m, pos;        a = 0;    b = nb_entries - 1;    while (a <= b) {        m = (a + b) >> 1;        pos = entries[m].pos;        if (pos == wanted_pos)            goto found;        else if (pos > wanted_pos) {            b = m - 1;        } else {            a = m + 1;        }    }    m = a;    if (m > 0)        m--; found:    return m;}static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp){    AVIContext *avi = s->priv_data;    AVStream *st;    AVIStream *ast;    int frame_number, i;    int64_t pos;    if (!avi->index_loaded) {        /* we only load the index on demand */        avi_load_index(s);        avi->index_loaded = 1;    }    if (stream_index < 0) {        for(i = 0; i < s->nb_streams; i++) {            st = s->streams[i];            if (st->codec.codec_type == CODEC_TYPE_VIDEO)                goto found;        }        return -1;    found:        stream_index = i;    }    st = s->streams[stream_index];    if (st->codec.codec_type != CODEC_TYPE_VIDEO)        return -1;    ast = st->priv_data;    /* compute the frame number */    frame_number = timestamp;#ifdef DEBUG_SEEK    printf("timestamp=%0.3f nb_indexes=%d frame_number=%d\n",            (double)timestamp / AV_TIME_BASE,           ast->nb_index_entries, frame_number);#endif    /* find a closest key frame before */    if (frame_number >= ast->nb_index_entries)        return -1;    while (frame_number >= 0 &&           !(ast->index_entries[frame_number].flags & AVIIF_INDEX))        frame_number--;    if (frame_number < 0)        return -1;    ast->new_frame_offset = frame_number;    /* find the position */    pos = ast->index_entries[frame_number].pos;#ifdef DEBUG_SEEK    printf("key_frame_number=%d pos=0x%llx\n",            frame_number, pos);#endif        /* update the frame counters for all the other stream by looking       at the positions just after the one found */    for(i = 0; i < s->nb_streams; i++) {        int j;        if (i != stream_index) {            st = s->streams[i];            ast = st->priv_data;            if (ast->nb_index_entries <= 0)                return -1;            j = locate_frame_in_index(ast->index_entries,                                      ast->nb_index_entries,                                      pos);            /* get next frame */            if ((j  + 1) < ast->nb_index_entries)                j++;            /* extract the current frame number */            if (ast->sample_size==0)                ast->new_frame_offset = j;            else                ast->new_frame_offset = ast->index_entries[j].cum_len;        }    }        /* everything is OK now. We can update the frame offsets */    for(i = 0; i < s->nb_streams; i++) {        st = s->streams[i];        ast = st->priv_data;        ast->frame_offset = ast->new_frame_offset;#ifdef DEBUG_SEEK        printf("%d: frame_offset=%d\n", i,                ast->frame_offset);#endif    }    /* do the seek */    pos += avi->movi_list;    url_fseek(&s->pb, pos, SEEK_SET);    return 0;}static int avi_read_close(AVFormatContext *s){    int i;    AVIContext *avi = s->priv_data;    for(i=0;i<s->nb_streams;i++) {        AVStream *st = s->streams[i];        AVIStream *ast = st->priv_data;        if(ast){            av_free(ast->index_entries);            av_free(ast);        }        av_free(st->codec.extradata);        av_free(st->codec.palctrl);    }    if (avi->dv_demux)        av_free(avi->dv_demux);    return 0;}static int avi_probe(AVProbeData *p){    /* check file header */    if (p->buf_size <= 32)        return 0;    if (p->buf[0] == 'R' && p->buf[1] == 'I' &&        p->buf[2] == 'F' && p->buf[3] == 'F' &&        p->buf[8] == 'A' && p->buf[9] == 'V' &&        p->buf[10] == 'I' && p->buf[11] == ' ')        return AVPROBE_SCORE_MAX;    else        return 0;}static AVInputFormat avi_iformat = {    "avi",    "avi format",    sizeof(AVIContext),    avi_probe,    avi_read_header,    avi_read_packet,    avi_read_close,    avi_read_seek,};int avidec_init(void){    av_register_input_format(&avi_iformat);    return 0;}

⌨️ 快捷键说明

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