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.

188 lines
5.4KB

  1. /*
  2. * This file is part of Libav.
  3. *
  4. * Libav is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2.1 of the License, or (at your option) any later version.
  8. *
  9. * Libav is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public
  15. * License along with Libav; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. #include <string.h>
  19. #include "libavutil/common.h"
  20. #include "libavutil/mem.h"
  21. #include "bsf.h"
  22. #include "cbs.h"
  23. #include "cbs_h264.h"
  24. #include "h264.h"
  25. typedef struct H264RedundantPPSContext {
  26. CodedBitstreamContext *input;
  27. CodedBitstreamContext *output;
  28. CodedBitstreamFragment access_unit;
  29. int global_pic_init_qp;
  30. int current_pic_init_qp;
  31. int extradata_pic_init_qp;
  32. } H264RedundantPPSContext;
  33. static int h264_redundant_pps_fixup_pps(H264RedundantPPSContext *ctx,
  34. H264RawPPS *pps)
  35. {
  36. // Record the current value of pic_init_qp in order to fix up
  37. // following slices, then overwrite with the global value.
  38. ctx->current_pic_init_qp = pps->pic_init_qp_minus26 + 26;
  39. pps->pic_init_qp_minus26 = ctx->global_pic_init_qp - 26;
  40. // Some PPSs have this set, so it must be set in all of them.
  41. // (Slices which do not use such a PPS on input will still have
  42. // *_weight_l*flag as zero and therefore write equivalently.)
  43. pps->weighted_pred_flag = 1;
  44. return 0;
  45. }
  46. static int h264_redundant_pps_fixup_slice(H264RedundantPPSContext *ctx,
  47. H264RawSliceHeader *slice)
  48. {
  49. int qp;
  50. qp = ctx->current_pic_init_qp + slice->slice_qp_delta;
  51. slice->slice_qp_delta = qp - ctx->global_pic_init_qp;
  52. return 0;
  53. }
  54. static int h264_redundant_pps_filter(AVBSFContext *bsf, AVPacket *out)
  55. {
  56. H264RedundantPPSContext *ctx = bsf->priv_data;
  57. AVPacket *in;
  58. CodedBitstreamFragment *au = &ctx->access_unit;
  59. int au_has_sps;
  60. int err, i;
  61. err = ff_bsf_get_packet(bsf, &in);
  62. if (err < 0)
  63. return err;
  64. err = ff_cbs_read_packet(ctx->input, au, in);
  65. if (err < 0)
  66. return err;
  67. au_has_sps = 0;
  68. for (i = 0; i < au->nb_units; i++) {
  69. CodedBitstreamUnit *nal = &au->units[i];
  70. if (nal->type == H264_NAL_SPS)
  71. au_has_sps = 1;
  72. if (nal->type == H264_NAL_PPS) {
  73. h264_redundant_pps_fixup_pps(ctx, nal->content);
  74. if (!au_has_sps) {
  75. av_log(ctx, AV_LOG_VERBOSE, "Deleting redundant PPS "
  76. "at %"PRId64".\n", in->pts);
  77. ff_cbs_delete_unit(ctx->input, au, i);
  78. }
  79. }
  80. if (nal->type == H264_NAL_SLICE ||
  81. nal->type == H264_NAL_IDR_SLICE) {
  82. H264RawSlice *slice = nal->content;
  83. h264_redundant_pps_fixup_slice(ctx, &slice->header);
  84. }
  85. }
  86. err = ff_cbs_write_packet(ctx->output, out, au);
  87. if (err < 0)
  88. return err;
  89. ff_cbs_fragment_uninit(ctx->output, au);
  90. err = av_packet_copy_props(out, in);
  91. if (err < 0)
  92. return err;
  93. av_packet_free(&in);
  94. return 0;
  95. }
  96. static int h264_redundant_pps_init(AVBSFContext *bsf)
  97. {
  98. H264RedundantPPSContext *ctx = bsf->priv_data;
  99. CodedBitstreamFragment *au = &ctx->access_unit;
  100. int err, i;
  101. err = ff_cbs_init(&ctx->input, AV_CODEC_ID_H264, bsf);
  102. if (err < 0)
  103. return err;
  104. err = ff_cbs_init(&ctx->output, AV_CODEC_ID_H264, bsf);
  105. if (err < 0)
  106. return err;
  107. ctx->global_pic_init_qp = 26;
  108. if (bsf->par_in->extradata) {
  109. err = ff_cbs_read_extradata(ctx->input, au, bsf->par_in);
  110. if (err < 0) {
  111. av_log(bsf, AV_LOG_ERROR, "Failed to read extradata.\n");
  112. return err;
  113. }
  114. for (i = 0; i < au->nb_units; i++) {
  115. if (au->units[i].type == H264_NAL_PPS)
  116. h264_redundant_pps_fixup_pps(ctx, au->units[i].content);
  117. }
  118. ctx->extradata_pic_init_qp = ctx->current_pic_init_qp;
  119. err = ff_cbs_write_extradata(ctx->output, bsf->par_out, au);
  120. if (err < 0) {
  121. av_log(bsf, AV_LOG_ERROR, "Failed to write extradata.\n");
  122. return err;
  123. }
  124. ff_cbs_fragment_uninit(ctx->output, au);
  125. }
  126. return 0;
  127. }
  128. static void h264_redundant_pps_flush(AVBSFContext *bsf)
  129. {
  130. H264RedundantPPSContext *ctx = bsf->priv_data;
  131. ctx->current_pic_init_qp = ctx->extradata_pic_init_qp;
  132. }
  133. static void h264_redundant_pps_close(AVBSFContext *bsf)
  134. {
  135. H264RedundantPPSContext *ctx = bsf->priv_data;
  136. ff_cbs_close(&ctx->input);
  137. ff_cbs_close(&ctx->output);
  138. }
  139. static const enum AVCodecID h264_redundant_pps_codec_ids[] = {
  140. AV_CODEC_ID_H264, AV_CODEC_ID_NONE,
  141. };
  142. const AVBitStreamFilter ff_h264_redundant_pps_bsf = {
  143. .name = "h264_redundant_pps",
  144. .priv_data_size = sizeof(H264RedundantPPSContext),
  145. .init = &h264_redundant_pps_init,
  146. .flush = &h264_redundant_pps_flush,
  147. .close = &h264_redundant_pps_close,
  148. .filter = &h264_redundant_pps_filter,
  149. .codec_ids = h264_redundant_pps_codec_ids,
  150. };