00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "libavcodec/bytestream.h"
00022 #include "avformat.h"
00023 #include "oggdec.h"
00024
00025 static int skeleton_header(AVFormatContext *s, int idx)
00026 {
00027 struct ogg *ogg = s->priv_data;
00028 struct ogg_stream *os = ogg->streams + idx;
00029 AVStream *st = s->streams[idx];
00030 uint8_t *buf = os->buf + os->pstart;
00031 int version_major, version_minor;
00032 int64_t start_num, start_den, start_granule;
00033 int target_idx, start_time;
00034
00035 strcpy(st->codec->codec_name, "skeleton");
00036 st->codec->codec_type = AVMEDIA_TYPE_DATA;
00037
00038 if (os->psize < 8)
00039 return -1;
00040
00041 if (!strncmp(buf, "fishead", 8)) {
00042 if (os->psize < 64)
00043 return -1;
00044
00045 version_major = AV_RL16(buf+8);
00046 version_minor = AV_RL16(buf+10);
00047
00048 if (version_major != 3) {
00049 av_log(s, AV_LOG_WARNING, "Unknown skeleton version %d.%d\n",
00050 version_major, version_minor);
00051 return -1;
00052 }
00053
00054
00055
00056
00057
00058
00059 start_num = AV_RL64(buf+12);
00060 start_den = AV_RL64(buf+20);
00061
00062 if (start_den) {
00063 av_reduce(&start_time, &st->time_base.den, start_num, start_den, INT_MAX);
00064 st->time_base.num = 1;
00065 os->lastpts =
00066 st->start_time = start_time;
00067 }
00068 } else if (!strncmp(buf, "fisbone", 8)) {
00069 if (os->psize < 52)
00070 return -1;
00071
00072 target_idx = ogg_find_stream(ogg, AV_RL32(buf+12));
00073 start_granule = AV_RL64(buf+36);
00074 if (target_idx >= 0 && start_granule != -1) {
00075 ogg->streams[target_idx].lastpts =
00076 s->streams[target_idx]->start_time = ogg_gptopts(s, target_idx, start_granule, NULL);
00077 }
00078 }
00079
00080 return 1;
00081 }
00082
00083 const struct ogg_codec ff_skeleton_codec = {
00084 .magic = "fishead",
00085 .magicsize = 8,
00086 .header = skeleton_header,
00087 };