You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

164 lines
4.2KB

  1. /*
  2. * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  3. *
  4. * This file is part of Libav.
  5. *
  6. * Libav 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. * Libav 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 Libav; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. #include <string.h>
  21. #include "avcodec.h"
  22. #include "libavutil/internal.h"
  23. #include "libavutil/mem.h"
  24. #if FF_API_OLD_BSF
  25. FF_DISABLE_DEPRECATION_WARNINGS
  26. AVBitStreamFilter *av_bitstream_filter_next(const AVBitStreamFilter *f)
  27. {
  28. const AVBitStreamFilter *filter = NULL;
  29. void *opaque = NULL;
  30. while (filter != f)
  31. filter = av_bsf_next(&opaque);
  32. return av_bsf_next(&opaque);
  33. }
  34. void av_register_bitstream_filter(AVBitStreamFilter *bsf)
  35. {
  36. }
  37. typedef struct BSFCompatContext {
  38. AVBSFContext *ctx;
  39. } BSFCompatContext;
  40. AVBitStreamFilterContext *av_bitstream_filter_init(const char *name)
  41. {
  42. AVBitStreamFilterContext *ctx = NULL;
  43. BSFCompatContext *priv = NULL;
  44. const AVBitStreamFilter *bsf;
  45. bsf = av_bsf_get_by_name(name);
  46. if (!bsf)
  47. return NULL;
  48. ctx = av_mallocz(sizeof(*ctx));
  49. if (!ctx)
  50. return NULL;
  51. priv = av_mallocz(sizeof(*priv));
  52. if (!priv)
  53. goto fail;
  54. ctx->filter = bsf;
  55. ctx->priv_data = priv;
  56. return ctx;
  57. fail:
  58. if (priv)
  59. av_bsf_free(&priv->ctx);
  60. av_freep(&priv);
  61. av_freep(&ctx);
  62. return NULL;
  63. }
  64. void av_bitstream_filter_close(AVBitStreamFilterContext *bsfc)
  65. {
  66. BSFCompatContext *priv = bsfc->priv_data;
  67. av_bsf_free(&priv->ctx);
  68. av_freep(&bsfc->priv_data);
  69. av_free(bsfc);
  70. }
  71. int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc,
  72. AVCodecContext *avctx, const char *args,
  73. uint8_t **poutbuf, int *poutbuf_size,
  74. const uint8_t *buf, int buf_size, int keyframe)
  75. {
  76. BSFCompatContext *priv = bsfc->priv_data;
  77. AVPacket pkt = { 0 };
  78. int ret;
  79. if (!priv->ctx) {
  80. ret = av_bsf_alloc(bsfc->filter, &priv->ctx);
  81. if (ret < 0)
  82. return ret;
  83. ret = avcodec_parameters_from_context(priv->ctx->par_in, avctx);
  84. if (ret < 0)
  85. return ret;
  86. priv->ctx->time_base_in = avctx->time_base;
  87. ret = av_bsf_init(priv->ctx);
  88. if (ret < 0)
  89. return ret;
  90. if (priv->ctx->par_out->extradata_size) {
  91. av_freep(&avctx->extradata);
  92. avctx->extradata_size = 0;
  93. avctx->extradata = av_mallocz(priv->ctx->par_out->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
  94. if (!avctx->extradata)
  95. return AVERROR(ENOMEM);
  96. memcpy(avctx->extradata, priv->ctx->par_out->extradata,
  97. priv->ctx->par_out->extradata_size);
  98. avctx->extradata_size = priv->ctx->par_out->extradata_size;
  99. }
  100. }
  101. pkt.data = buf;
  102. pkt.size = buf_size;
  103. ret = av_bsf_send_packet(priv->ctx, &pkt);
  104. if (ret < 0)
  105. return ret;
  106. *poutbuf = NULL;
  107. *poutbuf_size = 0;
  108. ret = av_bsf_receive_packet(priv->ctx, &pkt);
  109. if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
  110. return 0;
  111. else if (ret < 0)
  112. return ret;
  113. *poutbuf = av_malloc(pkt.size + AV_INPUT_BUFFER_PADDING_SIZE);
  114. if (!*poutbuf) {
  115. av_packet_unref(&pkt);
  116. return AVERROR(ENOMEM);
  117. }
  118. *poutbuf_size = pkt.size;
  119. memcpy(*poutbuf, pkt.data, pkt.size);
  120. av_packet_unref(&pkt);
  121. /* drain all the remaining packets we cannot return */
  122. while (ret >= 0) {
  123. ret = av_bsf_receive_packet(priv->ctx, &pkt);
  124. av_packet_unref(&pkt);
  125. }
  126. return 1;
  127. }
  128. FF_ENABLE_DEPRECATION_WARNINGS
  129. #endif