00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "libavcodec/get_bits.h"
00022 #include "libavcodec/dirac.h"
00023 #include "avformat.h"
00024 #include "internal.h"
00025 #include "oggdec.h"
00026
00027 static int dirac_header(AVFormatContext *s, int idx)
00028 {
00029 struct ogg *ogg = s->priv_data;
00030 struct ogg_stream *os = ogg->streams + idx;
00031 AVStream *st = s->streams[idx];
00032 dirac_source_params source;
00033 GetBitContext gb;
00034
00035
00036 if (st->codec->codec_id == CODEC_ID_DIRAC)
00037 return 0;
00038
00039 init_get_bits(&gb, os->buf + os->pstart + 13, (os->psize - 13) * 8);
00040 if (avpriv_dirac_parse_sequence_header(st->codec, &gb, &source) < 0)
00041 return -1;
00042
00043 st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
00044 st->codec->codec_id = CODEC_ID_DIRAC;
00045
00046 avpriv_set_pts_info(st, 64, st->codec->time_base.num, 2*st->codec->time_base.den);
00047 return 1;
00048 }
00049
00050
00051 static uint64_t dirac_gptopts(AVFormatContext *s, int idx, uint64_t granule,
00052 int64_t *dts_out)
00053 {
00054 int64_t gp = granule;
00055 struct ogg *ogg = s->priv_data;
00056 struct ogg_stream *os = ogg->streams + idx;
00057
00058 unsigned dist = ((gp >> 14) & 0xff00) | (gp & 0xff);
00059 int64_t dts = (gp >> 31);
00060 int64_t pts = dts + ((gp >> 9) & 0x1fff);
00061
00062 if (!dist)
00063 os->pflags |= AV_PKT_FLAG_KEY;
00064
00065 if (dts_out)
00066 *dts_out = dts;
00067
00068 return pts;
00069 }
00070
00071 static int old_dirac_header(AVFormatContext *s, int idx)
00072 {
00073 struct ogg *ogg = s->priv_data;
00074 struct ogg_stream *os = ogg->streams + idx;
00075 AVStream *st = s->streams[idx];
00076 uint8_t *buf = os->buf + os->pstart;
00077
00078 if (buf[0] != 'K')
00079 return 0;
00080
00081 st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
00082 st->codec->codec_id = CODEC_ID_DIRAC;
00083 avpriv_set_pts_info(st, 64, AV_RB32(buf+12), AV_RB32(buf+8));
00084 return 1;
00085 }
00086
00087 static uint64_t old_dirac_gptopts(AVFormatContext *s, int idx, uint64_t gp,
00088 int64_t *dts)
00089 {
00090 struct ogg *ogg = s->priv_data;
00091 struct ogg_stream *os = ogg->streams + idx;
00092 uint64_t iframe = gp >> 30;
00093 uint64_t pframe = gp & 0x3fffffff;
00094
00095 if (!pframe)
00096 os->pflags |= AV_PKT_FLAG_KEY;
00097
00098 return iframe + pframe;
00099 }
00100
00101 const struct ogg_codec ff_dirac_codec = {
00102 .magic = "BBCD\0",
00103 .magicsize = 5,
00104 .header = dirac_header,
00105 .gptopts = dirac_gptopts,
00106 .granule_is_start = 1,
00107 };
00108
00109 const struct ogg_codec ff_old_dirac_codec = {
00110 .magic = "KW-DIRAC",
00111 .magicsize = 8,
00112 .header = old_dirac_header,
00113 .gptopts = old_dirac_gptopts,
00114 .granule_is_start = 1,
00115 };