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

📄 rmdec.c

📁 ffmpeg移植到symbian的全部源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
        *pos= url_ftell(pb) - 3;        if(rm->remaining_len > 0){            num= rm->current_stream;            len= rm->remaining_len;            *timestamp = AV_NOPTS_VALUE;            *flags= 0;        }else{            state= (state<<8) + get_byte(pb);            if(state == MKBETAG('I', 'N', 'D', 'X')){                len = get_be16(pb) - 6;                if(len<0)                    continue;                goto skip;            }            if(state > (unsigned)0xFFFF || state < 12)                continue;            len=state;            state= 0xFFFFFFFF;            num = get_be16(pb);            *timestamp = get_be32(pb);            res= get_byte(pb); /* reserved */            *flags = get_byte(pb); /* flags */            len -= 12;        }        for(i=0;i<s->nb_streams;i++) {            st = s->streams[i];            if (num == st->id)                break;        }        if (i == s->nb_streams) {skip:            /* skip packet if unknown number */            url_fskip(pb, len);            rm->remaining_len -= len;            continue;        }        *stream_index= i;        return len;    }    return -1;}static int rm_assemble_video_frame(AVFormatContext *s, RMContext *rm, AVPacket *pkt, int len){    ByteIOContext *pb = s->pb;    int hdr, seq, pic_num, len2, pos;    int type;    hdr = get_byte(pb); len--;    type = hdr >> 6;    switch(type){    case 0: // slice    case 2: // last slice        seq = get_byte(pb); len--;        len2 = get_num(pb, &len);        pos = get_num(pb, &len);        pic_num = get_byte(pb); len--;        rm->remaining_len = len;        break;    case 1: //whole frame        seq = get_byte(pb); len--;        if(av_new_packet(pkt, len + 9) < 0)            return AVERROR(EIO);        pkt->data[0] = 0;        AV_WL32(pkt->data + 1, 1);        AV_WL32(pkt->data + 5, 0);        get_buffer(pb, pkt->data + 9, len);        rm->remaining_len = 0;        return 0;    case 3: //frame as a part of packet        len2 = get_num(pb, &len);        pos = get_num(pb, &len);        pic_num = get_byte(pb); len--;        rm->remaining_len = len - len2;        if(av_new_packet(pkt, len2 + 9) < 0)            return AVERROR(EIO);        pkt->data[0] = 0;        AV_WL32(pkt->data + 1, 1);        AV_WL32(pkt->data + 5, 0);        get_buffer(pb, pkt->data + 9, len2);        return 0;    }    //now we have to deal with single slice    if((seq & 0x7F) == 1 || rm->curpic_num != pic_num){        rm->slices = ((hdr & 0x3F) << 1) + 1;        rm->videobufsize = len2 + 8*rm->slices + 1;        av_free(rm->videobuf);        if(!(rm->videobuf = av_malloc(rm->videobufsize)))            return AVERROR(ENOMEM);        rm->videobufpos = 8*rm->slices + 1;        rm->cur_slice = 0;        rm->curpic_num = pic_num;        rm->pktpos = url_ftell(pb);    }    if(type == 2)        len = FFMIN(len, pos);    if(++rm->cur_slice > rm->slices)        return 1;    AV_WL32(rm->videobuf - 7 + 8*rm->cur_slice, 1);    AV_WL32(rm->videobuf - 3 + 8*rm->cur_slice, rm->videobufpos - 8*rm->slices - 1);    if(rm->videobufpos + len > rm->videobufsize)        return 1;    if (get_buffer(pb, rm->videobuf + rm->videobufpos, len) != len)        return AVERROR(EIO);    rm->videobufpos += len;    rm->remaining_len-= len;    if(type == 2 || (rm->videobufpos) == rm->videobufsize){         rm->videobuf[0] = rm->cur_slice-1;         if(av_new_packet(pkt, rm->videobufpos - 8*(rm->slices - rm->cur_slice)) < 0)             return AVERROR(ENOMEM);         memcpy(pkt->data, rm->videobuf, 1 + 8*rm->cur_slice);         memcpy(pkt->data + 1 + 8*rm->cur_slice, rm->videobuf + 1 + 8*rm->slices,                rm->videobufpos - 1 - 8*rm->slices);         pkt->pts = AV_NOPTS_VALUE;         pkt->pos = rm->pktpos;         return 0;    }    return 1;}static inline voidrm_ac3_swap_bytes (AVStream *st, AVPacket *pkt){    uint8_t *ptr;    int j;    if (st->codec->codec_id == CODEC_ID_AC3) {        ptr = pkt->data;        for (j=0;j<pkt->size;j+=2) {            FFSWAP(int, ptr[0], ptr[1]);            ptr += 2;        }    }}intff_rm_parse_packet (AVFormatContext *s, AVStream *st, int len, AVPacket *pkt,                    int *seq, int *flags, int64_t *timestamp){    ByteIOContext *pb = s->pb;    RMContext *rm = s->priv_data;    if (st->codec->codec_type == CODEC_TYPE_VIDEO) {        rm->current_stream= st->id;        if(rm_assemble_video_frame(s, rm, pkt, len) == 1)            return -1; //got partial frame    } else if (st->codec->codec_type == CODEC_TYPE_AUDIO) {        if ((st->codec->codec_id == CODEC_ID_RA_288) ||            (st->codec->codec_id == CODEC_ID_COOK) ||            (st->codec->codec_id == CODEC_ID_ATRAC3)) {            int x;            int sps = rm->sub_packet_size;            int cfs = rm->coded_framesize;            int h = rm->sub_packet_h;            int y = rm->sub_packet_cnt;            int w = rm->audio_framesize;            if (*flags & 2)                y = rm->sub_packet_cnt = 0;            if (!y)                rm->audiotimestamp = *timestamp;            switch(st->codec->codec_id) {                case CODEC_ID_RA_288:                    for (x = 0; x < h/2; x++)                        get_buffer(pb, rm->audiobuf+x*2*w+y*cfs, cfs);                    break;                case CODEC_ID_ATRAC3:                case CODEC_ID_COOK:                    for (x = 0; x < w/sps; x++)                        get_buffer(pb, rm->audiobuf+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), sps);                    break;            }            if (++(rm->sub_packet_cnt) < h)                return -1;            else {                rm->sub_packet_cnt = 0;                rm->audio_stream_num = st->index;                rm->audio_pkt_cnt = h * w / st->codec->block_align - 1;                // Release first audio packet                av_new_packet(pkt, st->codec->block_align);                memcpy(pkt->data, rm->audiobuf, st->codec->block_align);                *timestamp = rm->audiotimestamp;                *flags = 2; // Mark first packet as keyframe            }        } else if (st->codec->codec_id == CODEC_ID_AAC) {            int x;            rm->audio_stream_num = st->index;            rm->sub_packet_cnt = (get_be16(pb) & 0xf0) >> 4;            if (rm->sub_packet_cnt) {                for (x = 0; x < rm->sub_packet_cnt; x++)                    rm->sub_packet_lengths[x] = get_be16(pb);                // Release first audio packet                rm->audio_pkt_cnt = rm->sub_packet_cnt - 1;                av_get_packet(pb, pkt, rm->sub_packet_lengths[0]);                *flags = 2; // Mark first packet as keyframe            }        } else {            av_get_packet(pb, pkt, len);            rm_ac3_swap_bytes(st, pkt);        }    } else        av_get_packet(pb, pkt, len);    if(  (st->discard >= AVDISCARD_NONKEY && !(*flags&2))       || st->discard >= AVDISCARD_ALL){        av_free_packet(pkt);        return -1;    }    pkt->stream_index = st->index;#if 0    if (st->codec->codec_type == CODEC_TYPE_VIDEO) {        if(st->codec->codec_id == CODEC_ID_RV20){            int seq= 128*(pkt->data[2]&0x7F) + (pkt->data[3]>>1);            av_log(NULL, AV_LOG_DEBUG, "%d %"PRId64" %d\n", *timestamp, *timestamp*512LL/25, seq);            seq |= (*timestamp&~0x3FFF);            if(seq - *timestamp >  0x2000) seq -= 0x4000;            if(seq - *timestamp < -0x2000) seq += 0x4000;        }    }#endif    pkt->pts= *timestamp;    if (*flags & 2)        pkt->flags |= PKT_FLAG_KEY;    return 0;}voidff_rm_retrieve_cache (AVFormatContext *s, AVStream *st, AVPacket *pkt){    ByteIOContext *pb = s->pb;    RMContext *rm = s->priv_data;    assert (rm->audio_pkt_cnt > 0);    if (st->codec->codec_id == CODEC_ID_AAC)        av_get_packet(pb, pkt, rm->sub_packet_lengths[rm->sub_packet_cnt - rm->audio_pkt_cnt]);    else {        av_new_packet(pkt, st->codec->block_align);        memcpy(pkt->data, rm->audiobuf + st->codec->block_align *               (rm->sub_packet_h * rm->audio_framesize / st->codec->block_align - rm->audio_pkt_cnt),               st->codec->block_align);    }    rm->audio_pkt_cnt--;    pkt->flags = 0;    pkt->stream_index = st->index;}static int rm_read_packet(AVFormatContext *s, AVPacket *pkt){    RMContext *rm = s->priv_data;    ByteIOContext *pb = s->pb;    AVStream *st;    int i, len;    int64_t timestamp, pos;    int flags;    if (rm->audio_pkt_cnt) {        // If there are queued audio packet return them first        st = s->streams[rm->audio_stream_num];        ff_rm_retrieve_cache(s, st, pkt);    } else if (rm->old_format) {        st = s->streams[0];        if (st->codec->codec_id == CODEC_ID_RA_288) {            int x, y;            for (y = 0; y < rm->sub_packet_h; y++)                for (x = 0; x < rm->sub_packet_h/2; x++)                    if (get_buffer(pb, rm->audiobuf+x*2*rm->audio_framesize+y*rm->coded_framesize, rm->coded_framesize) <= 0)                        return AVERROR(EIO);            rm->audio_stream_num = 0;            rm->audio_pkt_cnt = rm->sub_packet_h * rm->audio_framesize / st->codec->block_align - 1;            // Release first audio packet            av_new_packet(pkt, st->codec->block_align);            memcpy(pkt->data, rm->audiobuf, st->codec->block_align);            pkt->flags |= PKT_FLAG_KEY; // Mark first packet as keyframe            pkt->stream_index = 0;        } else {            /* just read raw bytes */            len = RAW_PACKET_SIZE;            len= av_get_packet(pb, pkt, len);            pkt->stream_index = 0;            if (len <= 0) {                return AVERROR(EIO);            }            pkt->size = len;        }        rm_ac3_swap_bytes(st, pkt);    } else {        int seq=1;resync:        len=sync(s, &timestamp, &flags, &i, &pos);        if(len<0)            return AVERROR(EIO);        st = s->streams[i];        if (ff_rm_parse_packet (s, st, len, pkt, &seq, &flags, &timestamp) < 0)            goto resync;        if((flags&2) && (seq&0x7F) == 1)            av_add_index_entry(st, pos, timestamp, 0, 0, AVINDEX_KEYFRAME);    }    return 0;}static int rm_read_close(AVFormatContext *s){    RMContext *rm = s->priv_data;    av_free(rm->audiobuf);    av_free(rm->videobuf);    return 0;}static int rm_probe(AVProbeData *p){    /* check file header */    if ((p->buf[0] == '.' && p->buf[1] == 'R' &&         p->buf[2] == 'M' && p->buf[3] == 'F' &&         p->buf[4] == 0 && p->buf[5] == 0) ||        (p->buf[0] == '.' && p->buf[1] == 'r' &&         p->buf[2] == 'a' && p->buf[3] == 0xfd))        return AVPROBE_SCORE_MAX;    else        return 0;}static int64_t rm_read_dts(AVFormatContext *s, int stream_index,                               int64_t *ppos, int64_t pos_limit){    RMContext *rm = s->priv_data;    int64_t pos, dts;    int stream_index2, flags, len, h;    pos = *ppos;    if(rm->old_format)        return AV_NOPTS_VALUE;    url_fseek(s->pb, pos, SEEK_SET);    rm->remaining_len=0;    for(;;){        int seq=1;        AVStream *st;        len=sync(s, &dts, &flags, &stream_index2, &pos);        if(len<0)            return AV_NOPTS_VALUE;        st = s->streams[stream_index2];        if (st->codec->codec_type == CODEC_TYPE_VIDEO) {            h= get_byte(s->pb); len--;            if(!(h & 0x40)){                seq = get_byte(s->pb); len--;            }        }        if((flags&2) && (seq&0x7F) == 1){//            av_log(s, AV_LOG_DEBUG, "%d %d-%d %"PRId64" %d\n", flags, stream_index2, stream_index, dts, seq);            av_add_index_entry(st, pos, dts, 0, 0, AVINDEX_KEYFRAME);            if(stream_index2 == stream_index)                break;        }        url_fskip(s->pb, len);    }    *ppos = pos;    return dts;}AVInputFormat rm_demuxer = {    "rm",    NULL_IF_CONFIG_SMALL("RM format"),    sizeof(RMContext),    rm_probe,    rm_read_header,    rm_read_packet,    rm_read_close,    NULL,    rm_read_dts,};

⌨️ 快捷键说明

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