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 int base_den;
00064 av_reduce(&start_time, &base_den, start_num, start_den, INT_MAX);
00065 av_set_pts_info(st, 64, 1, base_den);
00066 os->lastpts =
00067 st->start_time = start_time;
00068 }
00069 } else if (!strncmp(buf, "fisbone", 8)) {
00070 if (os->psize < 52)
00071 return -1;
00072
00073 target_idx = ogg_find_stream(ogg, AV_RL32(buf+12));
00074 start_granule = AV_RL64(buf+36);
00075 if (target_idx >= 0 && start_granule != -1) {
00076 ogg->streams[target_idx].lastpts =
00077 s->streams[target_idx]->start_time = ogg_gptopts(s, target_idx, start_granule, NULL);
00078 }
00079 }
00080
00081 return 1;
00082 }
00083
00084 const struct ogg_codec ff_skeleton_codec = {
00085 .magic = "fishead",
00086 .magicsize = 8,
00087 .header = skeleton_header,
00088 };