Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright (c) 2012 Stefano Sabatini
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a copy
  5.  * of this software and associated documentation files (the "Software"), to deal
  6.  * in the Software without restriction, including without limitation the rights
  7.  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8.  * copies of the Software, and to permit persons to whom the Software is
  9.  * furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice shall be included in
  12.  * all copies or substantial portions of the Software.
  13.  *
  14.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19.  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20.  * THE SOFTWARE.
  21.  */
  22.  
  23. /**
  24.  * @file
  25.  * libswscale API use example.
  26.  * @example doc/examples/scaling_video.c
  27.  */
  28.  
  29. #include <libavutil/imgutils.h>
  30. #include <libavutil/parseutils.h>
  31. #include <libswscale/swscale.h>
  32.  
  33. static void fill_yuv_image(uint8_t *data[4], int linesize[4],
  34.                            int width, int height, int frame_index)
  35. {
  36.     int x, y;
  37.  
  38.     /* Y */
  39.     for (y = 0; y < height; y++)
  40.         for (x = 0; x < width; x++)
  41.             data[0][y * linesize[0] + x] = x + y + frame_index * 3;
  42.  
  43.     /* Cb and Cr */
  44.     for (y = 0; y < height / 2; y++) {
  45.         for (x = 0; x < width / 2; x++) {
  46.             data[1][y * linesize[1] + x] = 128 + y + frame_index * 2;
  47.             data[2][y * linesize[2] + x] = 64 + x + frame_index * 5;
  48.         }
  49.     }
  50. }
  51.  
  52. int main(int argc, char **argv)
  53. {
  54.     uint8_t *src_data[4], *dst_data[4];
  55.     int src_linesize[4], dst_linesize[4];
  56.     int src_w = 320, src_h = 240, dst_w, dst_h;
  57.     enum AVPixelFormat src_pix_fmt = AV_PIX_FMT_YUV420P, dst_pix_fmt = AV_PIX_FMT_RGB24;
  58.     const char *dst_size = NULL;
  59.     const char *dst_filename = NULL;
  60.     FILE *dst_file;
  61.     int dst_bufsize;
  62.     struct SwsContext *sws_ctx;
  63.     int i, ret;
  64.  
  65.     if (argc != 3) {
  66.         fprintf(stderr, "Usage: %s output_file output_size\n"
  67.                 "API example program to show how to scale an image with libswscale.\n"
  68.                 "This program generates a series of pictures, rescales them to the given "
  69.                 "output_size and saves them to an output file named output_file\n."
  70.                 "\n", argv[0]);
  71.         exit(1);
  72.     }
  73.     dst_filename = argv[1];
  74.     dst_size     = argv[2];
  75.  
  76.     if (av_parse_video_size(&dst_w, &dst_h, dst_size) < 0) {
  77.         fprintf(stderr,
  78.                 "Invalid size '%s', must be in the form WxH or a valid size abbreviation\n",
  79.                 dst_size);
  80.         exit(1);
  81.     }
  82.  
  83.     dst_file = fopen(dst_filename, "wb");
  84.     if (!dst_file) {
  85.         fprintf(stderr, "Could not open destination file %s\n", dst_filename);
  86.         exit(1);
  87.     }
  88.  
  89.     /* create scaling context */
  90.     sws_ctx = sws_getContext(src_w, src_h, src_pix_fmt,
  91.                              dst_w, dst_h, dst_pix_fmt,
  92.                              SWS_BILINEAR, NULL, NULL, NULL);
  93.     if (!sws_ctx) {
  94.         fprintf(stderr,
  95.                 "Impossible to create scale context for the conversion "
  96.                 "fmt:%s s:%dx%d -> fmt:%s s:%dx%d\n",
  97.                 av_get_pix_fmt_name(src_pix_fmt), src_w, src_h,
  98.                 av_get_pix_fmt_name(dst_pix_fmt), dst_w, dst_h);
  99.         ret = AVERROR(EINVAL);
  100.         goto end;
  101.     }
  102.  
  103.     /* allocate source and destination image buffers */
  104.     if ((ret = av_image_alloc(src_data, src_linesize,
  105.                               src_w, src_h, src_pix_fmt, 16)) < 0) {
  106.         fprintf(stderr, "Could not allocate source image\n");
  107.         goto end;
  108.     }
  109.  
  110.     /* buffer is going to be written to rawvideo file, no alignment */
  111.     if ((ret = av_image_alloc(dst_data, dst_linesize,
  112.                               dst_w, dst_h, dst_pix_fmt, 1)) < 0) {
  113.         fprintf(stderr, "Could not allocate destination image\n");
  114.         goto end;
  115.     }
  116.     dst_bufsize = ret;
  117.  
  118.     for (i = 0; i < 100; i++) {
  119.         /* generate synthetic video */
  120.         fill_yuv_image(src_data, src_linesize, src_w, src_h, i);
  121.  
  122.         /* convert to destination format */
  123.         sws_scale(sws_ctx, (const uint8_t * const*)src_data,
  124.                   src_linesize, 0, src_h, dst_data, dst_linesize);
  125.  
  126.         /* write scaled image to file */
  127.         fwrite(dst_data[0], 1, dst_bufsize, dst_file);
  128.     }
  129.  
  130.     fprintf(stderr, "Scaling succeeded. Play the output file with the command:\n"
  131.            "ffplay -f rawvideo -pix_fmt %s -video_size %dx%d %s\n",
  132.            av_get_pix_fmt_name(dst_pix_fmt), dst_w, dst_h, dst_filename);
  133.  
  134. end:
  135.     if (dst_file)
  136.         fclose(dst_file);
  137.     av_freep(&src_data[0]);
  138.     av_freep(&dst_data[0]);
  139.     sws_freeContext(sws_ctx);
  140.     return ret < 0;
  141. }
  142.