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.

185 lines
4.8KB

  1. /*
  2. * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
  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 <string.h>
  21. #include "avcodec.h"
  22. #include "libavutil/atomic.h"
  23. #include "libavutil/internal.h"
  24. #include "libavutil/mem.h"
  25. #include "libavutil/opt.h"
  26. #if FF_API_OLD_BSF
  27. FF_DISABLE_DEPRECATION_WARNINGS
  28. AVBitStreamFilter *av_bitstream_filter_next(const AVBitStreamFilter *f)
  29. {
  30. const AVBitStreamFilter *filter = NULL;
  31. void *opaque = NULL;
  32. while (filter != f)
  33. filter = av_bsf_next(&opaque);
  34. return av_bsf_next(&opaque);
  35. }
  36. void av_register_bitstream_filter(AVBitStreamFilter *bsf)
  37. {
  38. }
  39. typedef struct BSFCompatContext {
  40. AVBSFContext *ctx;
  41. int extradata_updated;
  42. } BSFCompatContext;
  43. AVBitStreamFilterContext *av_bitstream_filter_init(const char *name)
  44. {
  45. AVBitStreamFilterContext *ctx = NULL;
  46. BSFCompatContext *priv = NULL;
  47. const AVBitStreamFilter *bsf;
  48. bsf = av_bsf_get_by_name(name);
  49. if (!bsf)
  50. return NULL;
  51. ctx = av_mallocz(sizeof(*ctx));
  52. if (!ctx)
  53. return NULL;
  54. priv = av_mallocz(sizeof(*priv));
  55. if (!priv)
  56. goto fail;
  57. ctx->filter = bsf;
  58. ctx->priv_data = priv;
  59. return ctx;
  60. fail:
  61. if (priv)
  62. av_bsf_free(&priv->ctx);
  63. av_freep(&priv);
  64. av_freep(&ctx);
  65. return NULL;
  66. }
  67. void av_bitstream_filter_close(AVBitStreamFilterContext *bsfc)
  68. {
  69. BSFCompatContext *priv;
  70. if (!bsfc)
  71. return;
  72. priv = bsfc->priv_data;
  73. av_bsf_free(&priv->ctx);
  74. av_freep(&bsfc->priv_data);
  75. av_free(bsfc);
  76. }
  77. int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc,
  78. AVCodecContext *avctx, const char *args,
  79. uint8_t **poutbuf, int *poutbuf_size,
  80. const uint8_t *buf, int buf_size, int keyframe)
  81. {
  82. BSFCompatContext *priv = bsfc->priv_data;
  83. AVPacket pkt = { 0 };
  84. int ret;
  85. if (!priv->ctx) {
  86. ret = av_bsf_alloc(bsfc->filter, &priv->ctx);
  87. if (ret < 0)
  88. return ret;
  89. ret = avcodec_parameters_from_context(priv->ctx->par_in, avctx);
  90. if (ret < 0)
  91. return ret;
  92. priv->ctx->time_base_in = avctx->time_base;
  93. if (bsfc->args && bsfc->filter->priv_class) {
  94. const AVOption *opt = av_opt_next(priv->ctx->priv_data, NULL);
  95. const char * shorthand[2] = {NULL};
  96. if (opt)
  97. shorthand[0] = opt->name;
  98. ret = av_opt_set_from_string(priv->ctx->priv_data, bsfc->args, shorthand, "=", ":");
  99. }
  100. ret = av_bsf_init(priv->ctx);
  101. if (ret < 0)
  102. return ret;
  103. }
  104. pkt.data = buf;
  105. pkt.size = buf_size;
  106. ret = av_bsf_send_packet(priv->ctx, &pkt);
  107. if (ret < 0)
  108. return ret;
  109. *poutbuf = NULL;
  110. *poutbuf_size = 0;
  111. ret = av_bsf_receive_packet(priv->ctx, &pkt);
  112. if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
  113. return 0;
  114. else if (ret < 0)
  115. return ret;
  116. *poutbuf = av_malloc(pkt.size + AV_INPUT_BUFFER_PADDING_SIZE);
  117. if (!*poutbuf) {
  118. av_packet_unref(&pkt);
  119. return AVERROR(ENOMEM);
  120. }
  121. *poutbuf_size = pkt.size;
  122. memcpy(*poutbuf, pkt.data, pkt.size);
  123. av_packet_unref(&pkt);
  124. /* drain all the remaining packets we cannot return */
  125. while (ret >= 0) {
  126. ret = av_bsf_receive_packet(priv->ctx, &pkt);
  127. av_packet_unref(&pkt);
  128. }
  129. if (!priv->extradata_updated) {
  130. /* update extradata in avctx from the output codec parameters */
  131. if (priv->ctx->par_out->extradata_size && (!args || !strstr(args, "private_spspps_buf"))) {
  132. av_freep(&avctx->extradata);
  133. avctx->extradata_size = 0;
  134. avctx->extradata = av_mallocz(priv->ctx->par_out->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
  135. if (!avctx->extradata)
  136. return AVERROR(ENOMEM);
  137. memcpy(avctx->extradata, priv->ctx->par_out->extradata, priv->ctx->par_out->extradata_size);
  138. avctx->extradata_size = priv->ctx->par_out->extradata_size;
  139. }
  140. priv->extradata_updated = 1;
  141. }
  142. return 1;
  143. }
  144. FF_ENABLE_DEPRECATION_WARNINGS
  145. #endif