vf_aspect.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. * Aspect ratio modification video filter
  3. * Copyright (c) 2010 Bobby Bingham
  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. /**
  21. * @file
  22. * aspect ratio modification video filter
  23. */
  24. #include "avfilter.h"
  25. typedef struct {
  26. AVRational aspect;
  27. } AspectContext;
  28. static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
  29. {
  30. AspectContext *aspect = ctx->priv;
  31. double ratio;
  32. int64_t gcd;
  33. if(args) {
  34. if(sscanf(args, "%d:%d", &aspect->aspect.num, &aspect->aspect.den) < 2) {
  35. if(sscanf(args, "%lf", &ratio) < 1)
  36. return -1;
  37. aspect->aspect = av_d2q(ratio, 100);
  38. } else {
  39. gcd = av_gcd(FFABS(aspect->aspect.num), FFABS(aspect->aspect.den));
  40. if(gcd) {
  41. aspect->aspect.num /= gcd;
  42. aspect->aspect.den /= gcd;
  43. }
  44. }
  45. }
  46. if(aspect->aspect.den == 0)
  47. aspect->aspect = (AVRational) {0, 1};
  48. return 0;
  49. }
  50. static void start_frame(AVFilterLink *link, AVFilterPicRef *picref)
  51. {
  52. AspectContext *aspect = link->dst->priv;
  53. picref->pixel_aspect = aspect->aspect;
  54. avfilter_start_frame(link->dst->outputs[0], picref);
  55. }
  56. #if CONFIG_ASPECT_FILTER
  57. /* for aspect filter, convert from frame aspect ratio to pixel aspect ratio */
  58. static int frameaspect_config_props(AVFilterLink *inlink)
  59. {
  60. AspectContext *aspect = inlink->dst->priv;
  61. av_reduce(&aspect->aspect.num, &aspect->aspect.den,
  62. aspect->aspect.num * inlink->h,
  63. aspect->aspect.den * inlink->w, 100);
  64. return 0;
  65. }
  66. AVFilter avfilter_vf_aspect = {
  67. .name = "aspect",
  68. .description = NULL_IF_CONFIG_SMALL("Set the frame aspect ratio."),
  69. .init = init,
  70. .priv_size = sizeof(AspectContext),
  71. .inputs = (AVFilterPad[]) {{ .name = "default",
  72. .type = AVMEDIA_TYPE_VIDEO,
  73. .config_props = frameaspect_config_props,
  74. .get_video_buffer = avfilter_null_get_video_buffer,
  75. .start_frame = start_frame,
  76. .end_frame = avfilter_null_end_frame },
  77. { .name = NULL}},
  78. .outputs = (AVFilterPad[]) {{ .name = "default",
  79. .type = AVMEDIA_TYPE_VIDEO, },
  80. { .name = NULL}},
  81. };
  82. #endif /* CONFIG_ASPECT_FILTER */
  83. #if CONFIG_PIXELASPECT_FILTER
  84. AVFilter avfilter_vf_pixelaspect = {
  85. .name = "pixelaspect",
  86. .description = NULL_IF_CONFIG_SMALL("Set the pixel aspect ratio."),
  87. .init = init,
  88. .priv_size = sizeof(AspectContext),
  89. .inputs = (AVFilterPad[]) {{ .name = "default",
  90. .type = AVMEDIA_TYPE_VIDEO,
  91. .get_video_buffer = avfilter_null_get_video_buffer,
  92. .start_frame = start_frame,
  93. .end_frame = avfilter_null_end_frame },
  94. { .name = NULL}},
  95. .outputs = (AVFilterPad[]) {{ .name = "default",
  96. .type = AVMEDIA_TYPE_VIDEO, },
  97. { .name = NULL}},
  98. };
  99. #endif /* CONFIG_PIXELASPECT_FILTER */