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.

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