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 + -
显示快捷键?