ogg2.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 701 行 · 第 1/2 页

C
701
字号
        }        os = ogg->streams + idx;#if 0        av_log (s, AV_LOG_DEBUG,                "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",                idx, os->pstart, os->psize, os->segp, os->nsegs);#endif        if (!os->codec){            if (os->header < 0){                os->codec = ogg_find_codec (os->buf, os->bufpos);                if (!os->codec){                    os->header = 0;                    return 0;                }            }else{                return 0;            }        }        segp = os->segp;        psize = os->psize;        while (os->segp < os->nsegs){            int ss = os->segments[os->segp++];            os->psize += ss;            if (ss < 255){                complete = 1;                break;            }        }        if (!complete && os->segp == os->nsegs){            ogg->curidx = -1;        }    }while (!complete);#if 0    av_log (s, AV_LOG_DEBUG,            "ogg_packet: idx %i, frame size %i, start %i\n",            idx, os->psize, os->pstart);#endif    ogg->curidx = idx;    if (os->header < 0){        int hdr = os->codec->header (s, idx);        if (!hdr){          os->header = os->seq;          os->segp = segp;          os->psize = psize;          ogg->headers = 1;        }else{          os->pstart += os->psize;          os->psize = 0;        }    }    if (os->header > -1 && os->seq > os->header){        if (os->codec && os->codec->packet)            os->codec->packet (s, idx);        if (str)            *str = idx;        if (dstart)            *dstart = os->pstart;        if (dsize)            *dsize = os->psize;        os->pstart += os->psize;        os->psize = 0;    }    os->seq++;    if (os->segp == os->nsegs)        ogg->curidx = -1;    return 0;}static intogg_get_headers (AVFormatContext * s){    ogg_t *ogg = s->priv_data;    do{        if (ogg_packet (s, NULL, NULL, NULL) < 0)            return -1;    }while (!ogg->headers);#if 0    av_log (s, AV_LOG_DEBUG, "found headers\n");#endif    return 0;}static uint64_togg_gptopts (AVFormatContext * s, int i, uint64_t gp){    ogg_t *ogg = s->priv_data;    ogg_stream_t *os = ogg->streams + i;    uint64_t pts = AV_NOPTS_VALUE;    if(os->codec->gptopts){        pts = os->codec->gptopts(s, i, gp);    } else {        pts = gp;    }    return pts;}static intogg_get_length (AVFormatContext * s){    ogg_t *ogg = s->priv_data;    int idx = -1, i;    offset_t size, end;    if(s->pb.is_streamed)        return 0;// already set    if (s->duration != AV_NOPTS_VALUE)        return 0;    size = url_fsize(&s->pb);    if(size < 0)        return 0;    end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: size;    ogg_save (s);    url_fseek (&s->pb, end, SEEK_SET);    while (!ogg_read_page (s, &i)){        if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&            ogg->streams[i].codec)            idx = i;    }    if (idx != -1){        s->streams[idx]->duration =            ogg_gptopts (s, idx, ogg->streams[idx].granule);    }    ogg->size = size;    ogg_restore (s, 0);    ogg_save (s);    while (!ogg_read_page (s, &i)) {        if (i == idx && ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0)            break;    }    if (i == idx) {        s->streams[idx]->start_time = ogg_gptopts (s, idx, ogg->streams[idx].granule);        s->streams[idx]->duration -= s->streams[idx]->start_time;    }    ogg_restore (s, 0);    return 0;}static intogg_read_header (AVFormatContext * s, AVFormatParameters * ap){    ogg_t *ogg = s->priv_data;    ogg->curidx = -1;    //linear headers seek from start    if (ogg_get_headers (s) < 0){      return -1;    }    //linear granulepos seek from end    ogg_get_length (s);    //fill the extradata in the per codec callbacks    return 0;}static intogg_read_packet (AVFormatContext * s, AVPacket * pkt){    ogg_t *ogg;    ogg_stream_t *os;    int idx = -1;    int pstart, psize;    //Get an ogg packet    do{        if (ogg_packet (s, &idx, &pstart, &psize) < 0)            return AVERROR(EIO);    }while (idx < 0 || !s->streams[idx]);    ogg = s->priv_data;    os = ogg->streams + idx;    //Alloc a pkt    if (av_new_packet (pkt, psize) < 0)        return AVERROR(EIO);    pkt->stream_index = idx;    memcpy (pkt->data, os->buf + pstart, psize);    if (os->lastgp != -1LL){        pkt->pts = ogg_gptopts (s, idx, os->lastgp);        os->lastgp = -1;    }    return psize;}static intogg_read_close (AVFormatContext * s){    ogg_t *ogg = s->priv_data;    int i;    for (i = 0; i < ogg->nstreams; i++){        av_free (ogg->streams[i].buf);        av_free (ogg->streams[i].private);    }    av_free (ogg->streams);    return 0;}static intogg_read_seek (AVFormatContext * s, int stream_index, int64_t target_ts,               int flags){    AVStream *st = s->streams[stream_index];    ogg_t *ogg = s->priv_data;    ByteIOContext *bc = &s->pb;    uint64_t min = 0, max = ogg->size;    uint64_t tmin = st->start_time, tmax = st->start_time + st->duration;    int64_t pts = AV_NOPTS_VALUE;    ogg_save (s);    if ((uint64_t)target_ts < tmin || target_ts < 0)        target_ts = tmin;    while (min <= max && tmin < tmax){        uint64_t p = min + (max - min) * (target_ts - tmin) / (tmax - tmin);        int i = -1;        url_fseek (bc, p, SEEK_SET);        while (!ogg_read_page (s, &i)){            if (i == stream_index && ogg->streams[i].granule != 0 &&                ogg->streams[i].granule != -1)                break;        }        if (i == -1)            break;        pts = ogg_gptopts (s, i, ogg->streams[i].granule);        p = url_ftell (bc);        if (FFABS (pts - target_ts) * st->time_base.num < st->time_base.den)            break;        if (pts > target_ts){            if (max == p && tmax == pts) {                // probably our tmin is wrong, causing us to always end up too late in the file                tmin = (target_ts + tmin + 1) / 2;                if (tmin == target_ts) {                    url_fseek(bc, min, SEEK_SET);                    break;                }            }            max = p;            tmax = pts;        }else{            if (min == p && tmin == pts) {                // probably our tmax is wrong, causing us to always end up too early in the file                tmax = (target_ts + tmax) / 2;                if (tmax == target_ts) {                    url_fseek(bc, max, SEEK_SET);                    break;                }            }            min = p;            tmin = pts;        }    }    if (FFABS (pts - target_ts) * st->time_base.num < st->time_base.den){        ogg_restore (s, 1);        ogg_reset (ogg);    }else{        ogg_restore (s, 0);        pts = AV_NOPTS_VALUE;    }    av_update_cur_dts(s, st, pts);    return 0;#if 0    //later...    int64_t pos;    if (av_seek_frame_binary (s, stream_index, target_ts, flags) < 0)        return -1;    pos = url_ftell (&s->pb);    ogg_read_timestamp (s, stream_index, &pos, pos - 1);#endif}#if 0static int64_togg_read_timestamp (AVFormatContext * s, int stream_index, int64_t * pos_arg,                    int64_t pos_limit){    ogg_t *ogg = s->priv_data;    ByteIOContext *bc = &s->pb;    int64_t pos, pts;    if (*pos_arg < 0)        return AV_NOPTS_VALUE;    pos = *pos_arg;}#endifstatic int ogg_probe(AVProbeData *p){    if (p->buf[0] == 'O' && p->buf[1] == 'g' &&        p->buf[2] == 'g' && p->buf[3] == 'S' &&        p->buf[4] == 0x0 && p->buf[5] <= 0x7 )        return AVPROBE_SCORE_MAX;    else        return 0;}AVInputFormat ogg_demuxer = {    "ogg",    "Ogg",    sizeof (ogg_t),    ogg_probe,    ogg_read_header,    ogg_read_packet,    ogg_read_close,    ogg_read_seek,// ogg_read_timestamp,    .extensions = "ogg",};

⌨️ 快捷键说明

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