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 "oggdec.h"
00025
00026 static int dirac_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 dirac_source_params source;
00032 GetBitContext gb;
00033
00034
00035 if (st->codec->codec_id == CODEC_ID_DIRAC)
00036 return 0;
00037
00038 init_get_bits(&gb, os->buf + os->pstart + 13, (os->psize - 13) * 8);
00039 if (ff_dirac_parse_sequence_header(st->codec, &gb, &source) < 0)
00040 return -1;
00041
00042 st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
00043 st->codec->codec_id = CODEC_ID_DIRAC;
00044
00045 st->time_base = (AVRational){st->codec->time_base.num, 2*st->codec->time_base.den};
00046 return 1;
00047 }
00048
00049
00050 static uint64_t dirac_gptopts(AVFormatContext *s, int idx, uint64_t granule,
00051 int64_t *dts_out)
00052 {
00053 int64_t gp = granule;
00054 struct ogg *ogg = s->priv_data;
00055 struct ogg_stream *os = ogg->streams + idx;
00056
00057 unsigned dist = ((gp >> 14) & 0xff00) | (gp & 0xff);
00058 int64_t dts = (gp >> 31);
00059 int64_t pts = dts + ((gp >> 9) & 0x1fff);
00060
00061 if (!dist)
00062 os->pflags |= AV_PKT_FLAG_KEY;
00063
00064 if (dts_out)
00065 *dts_out = dts;
00066
00067 return pts;
00068 }
00069
00070 static int old_dirac_header(AVFormatContext *s, int idx)
00071 {
00072 struct ogg *ogg = s->priv_data;
00073 struct ogg_stream *os = ogg->streams + idx;
00074 AVStream *st = s->streams[idx];
00075 uint8_t *buf = os->buf + os->pstart;
00076
00077 if (buf[0] != 'K')
00078 return 0;
00079
00080 st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
00081 st->codec->codec_id = CODEC_ID_DIRAC;
00082 st->time_base.den = AV_RB32(buf+8);
00083 st->time_base.num = AV_RB32(buf+12);
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 };