dvdsub_parser.c 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /*
  2. * DVD subtitle decoding for ffmpeg
  3. * Copyright (c) 2005 Fabrice Bellard
  4. *
  5. * This file is part of FFmpeg.
  6. *
  7. * FFmpeg is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * FFmpeg is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with FFmpeg; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. #include "libavutil/intreadwrite.h"
  22. #include "avcodec.h"
  23. /* parser definition */
  24. typedef struct DVDSubParseContext {
  25. uint8_t *packet;
  26. int packet_len;
  27. int packet_index;
  28. } DVDSubParseContext;
  29. static av_cold int dvdsub_parse_init(AVCodecParserContext *s)
  30. {
  31. return 0;
  32. }
  33. static int dvdsub_parse(AVCodecParserContext *s,
  34. AVCodecContext *avctx,
  35. const uint8_t **poutbuf, int *poutbuf_size,
  36. const uint8_t *buf, int buf_size)
  37. {
  38. DVDSubParseContext *pc = s->priv_data;
  39. if (pc->packet_index == 0) {
  40. if (buf_size < 2)
  41. return 0;
  42. pc->packet_len = AV_RB16(buf);
  43. if (pc->packet_len == 0) /* HD-DVD subpicture packet */
  44. pc->packet_len = AV_RB32(buf+2);
  45. av_freep(&pc->packet);
  46. pc->packet = av_malloc(pc->packet_len);
  47. }
  48. if (pc->packet) {
  49. if (pc->packet_index + buf_size <= pc->packet_len) {
  50. memcpy(pc->packet + pc->packet_index, buf, buf_size);
  51. pc->packet_index += buf_size;
  52. if (pc->packet_index >= pc->packet_len) {
  53. *poutbuf = pc->packet;
  54. *poutbuf_size = pc->packet_len;
  55. pc->packet_index = 0;
  56. return buf_size;
  57. }
  58. } else {
  59. /* erroneous size */
  60. pc->packet_index = 0;
  61. }
  62. }
  63. *poutbuf = NULL;
  64. *poutbuf_size = 0;
  65. return buf_size;
  66. }
  67. static av_cold void dvdsub_parse_close(AVCodecParserContext *s)
  68. {
  69. DVDSubParseContext *pc = s->priv_data;
  70. av_freep(&pc->packet);
  71. }
  72. AVCodecParser dvdsub_parser = {
  73. { CODEC_ID_DVD_SUBTITLE },
  74. sizeof(DVDSubParseContext),
  75. dvdsub_parse_init,
  76. dvdsub_parse,
  77. dvdsub_parse_close,
  78. };