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