oggparsedirac.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /*
  2. * Copyright (C) 2008 David Conrad
  3. *
  4. * This file is part of FFmpeg.
  5. *
  6. * FFmpeg is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * FFmpeg is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with FFmpeg; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. #include "libavcodec/get_bits.h"
  21. #include "libavcodec/dirac.h"
  22. #include "avformat.h"
  23. #include "internal.h"
  24. #include "oggdec.h"
  25. static int dirac_header(AVFormatContext *s, int idx)
  26. {
  27. struct ogg *ogg = s->priv_data;
  28. struct ogg_stream *os = ogg->streams + idx;
  29. AVStream *st = s->streams[idx];
  30. dirac_source_params source;
  31. GetBitContext gb;
  32. // already parsed the header
  33. if (st->codec->codec_id == CODEC_ID_DIRAC)
  34. return 0;
  35. init_get_bits(&gb, os->buf + os->pstart + 13, (os->psize - 13) * 8);
  36. if (avpriv_dirac_parse_sequence_header(st->codec, &gb, &source) < 0)
  37. return -1;
  38. st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
  39. st->codec->codec_id = CODEC_ID_DIRAC;
  40. // dirac in ogg always stores timestamps as though the video were interlaced
  41. avpriv_set_pts_info(st, 64, st->codec->time_base.num, 2*st->codec->time_base.den);
  42. return 1;
  43. }
  44. // various undocument things: granule is signed (only for dirac!)
  45. static uint64_t dirac_gptopts(AVFormatContext *s, int idx, uint64_t granule,
  46. int64_t *dts_out)
  47. {
  48. int64_t gp = granule;
  49. struct ogg *ogg = s->priv_data;
  50. struct ogg_stream *os = ogg->streams + idx;
  51. unsigned dist = ((gp >> 14) & 0xff00) | (gp & 0xff);
  52. int64_t dts = (gp >> 31);
  53. int64_t pts = dts + ((gp >> 9) & 0x1fff);
  54. if (!dist)
  55. os->pflags |= AV_PKT_FLAG_KEY;
  56. if (dts_out)
  57. *dts_out = dts;
  58. return pts;
  59. }
  60. static int old_dirac_header(AVFormatContext *s, int idx)
  61. {
  62. struct ogg *ogg = s->priv_data;
  63. struct ogg_stream *os = ogg->streams + idx;
  64. AVStream *st = s->streams[idx];
  65. uint8_t *buf = os->buf + os->pstart;
  66. if (buf[0] != 'K')
  67. return 0;
  68. st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
  69. st->codec->codec_id = CODEC_ID_DIRAC;
  70. avpriv_set_pts_info(st, 64, AV_RB32(buf+12), AV_RB32(buf+8));
  71. return 1;
  72. }
  73. static uint64_t old_dirac_gptopts(AVFormatContext *s, int idx, uint64_t gp,
  74. int64_t *dts)
  75. {
  76. struct ogg *ogg = s->priv_data;
  77. struct ogg_stream *os = ogg->streams + idx;
  78. uint64_t iframe = gp >> 30;
  79. uint64_t pframe = gp & 0x3fffffff;
  80. if (!pframe)
  81. os->pflags |= AV_PKT_FLAG_KEY;
  82. return iframe + pframe;
  83. }
  84. const struct ogg_codec ff_dirac_codec = {
  85. .magic = "BBCD\0",
  86. .magicsize = 5,
  87. .header = dirac_header,
  88. .gptopts = dirac_gptopts,
  89. .granule_is_start = 1,
  90. };
  91. const struct ogg_codec ff_old_dirac_codec = {
  92. .magic = "KW-DIRAC",
  93. .magicsize = 8,
  94. .header = old_dirac_header,
  95. .gptopts = old_dirac_gptopts,
  96. .granule_is_start = 1,
  97. };