filmstro_ffmpeg
 All Classes Files Functions Friends Macros
filmstro_ffmpeg_FFmpegVideoScaler.h
Go to the documentation of this file.
1 /*
2  ==============================================================================
3  Copyright (c) 2017, Filmstro Ltd. - Daniel Walz
4  All rights reserved.
5 
6  Redistribution and use in source and binary forms, with or without modification,
7  are permitted provided that the following conditions are met:
8  1. Redistributions of source code must retain the above copyright notice, this
9  list of conditions and the following disclaimer.
10  2. Redistributions in binary form must reproduce the above copyright notice,
11  this list of conditions and the following disclaimer in the documentation
12  and/or other materials provided with the distribution.
13  3. Neither the name of the copyright holder nor the names of its contributors
14  may be used to endorse or promote products derived from this software without
15  specific prior written permission.
16 
17  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
21  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
26  OF THE POSSIBILITY OF SUCH DAMAGE.
27  ==============================================================================
28  \class FFmpegVideoScaler
29  \file filmstro_ffmpeg_FFmpegVideoScaler.h
30  \brief Converts and scales FFmpeg frames into juce format
31 
32  \author Daniel Walz @ filmstro.com
33  \date January 25th 2017
34 
35  \description Converts and scales FFmpeg frames into juce format
36 
37  ==============================================================================
38  */
39 
40 
41 #ifndef FILMSTRO_FFMPEG_FFMPEGVIDEOSCALER_H_INCLUDED
42 #define FILMSTRO_FFMPEG_FFMPEGVIDEOSCALER_H_INCLUDED
43 
45 public:
47  FFmpegVideoScaler () : scalerContext (nullptr) {}
48 
50  {
51  if (scalerContext)
52  sws_freeContext (scalerContext);
53  }
54 
56  void setupScaler (const int in_width, const int in_height, const AVPixelFormat in_format,
57  const int out_width, const int out_height, const AVPixelFormat out_format)
58  {
59  if (scalerContext) {
60  sws_freeContext (scalerContext);
61  scalerContext = nullptr;
62  }
63 
64  const AVPixFmtDescriptor* in_descriptor = av_pix_fmt_desc_get (in_format);
65  if (!in_descriptor) {
66  DBG ("No description for input pixel format");
67  return;
68  }
69  const int in_bitsPerPixel = av_get_padded_bits_per_pixel (in_descriptor);
70  for (int i=0; i < 4; ++i)
71  inLinesizes [i] = i < in_descriptor->nb_components ? in_width * in_bitsPerPixel >> 3 : 0;
72 
73  const AVPixFmtDescriptor* out_descriptor = av_pix_fmt_desc_get (out_format);
74  if (!out_descriptor) {
75  DBG ("No description for output pixel format");
76  return;
77  }
78  const int out_bitsPerPixel = av_get_padded_bits_per_pixel (out_descriptor);
79  for (int i=0; i < 4; ++i)
80  outLinesizes [i] = i < out_descriptor->nb_components ? out_width * out_bitsPerPixel >> 3 : 0;
81 
82  /* create scaling context */
83  scalerContext = sws_getContext (in_width, in_height, in_format,
84  out_width, out_height, out_format,
85  SWS_BILINEAR, NULL, NULL, NULL);
86  if (!scalerContext) {
87  DBG ("Impossible to create scale context for the conversion");
88  }
89  }
90 
91 
94  void convertFrameToImage (juce::Image& image, const AVFrame* frame)
95  {
96  if (scalerContext) {
97  juce::Image::BitmapData data (image, 0, 0,
98  image.getWidth(),
99  image.getHeight(),
100  juce::Image::BitmapData::writeOnly);
101 
102  uint8_t* destination[4] = {data.data, nullptr, nullptr, nullptr};
103 
104  sws_scale (scalerContext,
105  frame->data,
106  frame->linesize,
107  0,
108  frame->height,
109  destination,
110  outLinesizes);
111  }
112  }
113 
114 
116  void convertImageToFrame (AVFrame* frame, const juce::Image& image)
117  {
118  if (scalerContext) {
119  juce::Image::BitmapData data (image, 0, 0,
120  image.getWidth(),
121  image.getHeight());
122 
123  uint8_t* source[4] = {data.data, nullptr, nullptr, nullptr};
124 
125  sws_scale (scalerContext,
126  source,
127  inLinesizes,
128  0,
129  image.getHeight(),
130  frame->data,
131  frame->linesize);
132  }
133  }
134 
135 
136 private:
137  SwsContext* scalerContext;
138 
139  int inLinesizes[4];
140  int outLinesizes[4];
141 
142  JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FFmpegVideoScaler)
143 };
144 
145 #endif /* FILMSTRO_FFMPEG_FFMPEGVIDEOSCALER_H_INCLUDED */
void setupScaler(const int in_width, const int in_height, const AVPixelFormat in_format, const int out_width, const int out_height, const AVPixelFormat out_format)
Setup a scaler to scale video frames and to convert pixel formats.
Definition: filmstro_ffmpeg_FFmpegVideoScaler.h:56
void convertImageToFrame(AVFrame *frame, const juce::Image &image)
Converts a JUCE Image into a ffmpeg AVFrame to be written into a video stream.
Definition: filmstro_ffmpeg_FFmpegVideoScaler.h:116
~FFmpegVideoScaler()
Definition: filmstro_ffmpeg_FFmpegVideoScaler.h:49
void convertFrameToImage(juce::Image &image, const AVFrame *frame)
takes an AVFrame from ffmpeg and converts it to a JUCE Image.
Definition: filmstro_ffmpeg_FFmpegVideoScaler.h:94
Definition: filmstro_ffmpeg_FFmpegVideoScaler.h:44
FFmpegVideoScaler()
Creates a scaler object.
Definition: filmstro_ffmpeg_FFmpegVideoScaler.h:47