22 #include <com/avpkit/ferry/Logger.h>
24 #include <com/avpkit/core/VideoResampler.h>
25 #include <com/avpkit/core/VideoPicture.h>
26 #include <com/avpkit/core/Rational.h>
27 #include <com/avpkit/core/Property.h>
33 #include <libswscale/swscale.h>
35 #include "PixelFormat.h"
38 VS_LOG_SETUP(VS_CPP_PACKAGE);
42 namespace com {
namespace avpkit {
namespace core
45 VideoResampler :: VideoResampler()
51 mIPixelFmt = IPixelFormat::NONE;
52 mOPixelFmt = IPixelFormat::NONE;
56 VideoResampler :: ~VideoResampler()
59 sws_freeContext(mContext);
64 VideoResampler :: getInputHeight()
70 VideoResampler :: getInputWidth()
76 VideoResampler :: getOutputHeight()
82 VideoResampler :: getOutputWidth()
88 VideoResampler :: getInputPixelFormat()
94 VideoResampler :: getOutputPixelFormat()
108 throw std::invalid_argument(
"invalid output frame");
110 throw std::runtime_error(
"output frame height does not match expected value");
111 if (outFrame->
getWidth() != mOWidth)
112 throw std::runtime_error(
"output frame width does not match expected value");
114 throw std::runtime_error(
"output frame pixel format does not match expected value");
118 throw std::invalid_argument(
"invalid input frame");
121 throw std::runtime_error(
"input frame height does not match expected value");
123 throw std::runtime_error(
"input frame width does not match expected value");
125 throw std::runtime_error(
"input frame pixel format does not match expected value");
127 throw std::runtime_error(
"incoming frame doesn't have complete data");
130 outFrame->
setComplete(
false, mOPixelFmt, mOWidth, mOHeight,
146 const uint8_t* srcFrame[4] = {
152 retval = sws_scale(mContext, srcFrame, inAVFrame->linesize, 0,
153 mIHeight, outAVFrame->data, outAVFrame->linesize);
158 outFrame->
setComplete(retval >= 0,mOPixelFmt, mOWidth, mOHeight,
162 catch (std::bad_alloc& e)
166 catch (std::exception& e)
168 VS_LOG_DEBUG(
"error: %s", e.what());
181 case AV_PIX_FMT_YUVJ420P: *format = (
PixelFormat::Type)AV_PIX_FMT_YUVJ420P;
return 1;
182 case AV_PIX_FMT_YUVJ422P: *format = (
PixelFormat::Type)AV_PIX_FMT_YUVJ422P;
return 1;
183 case AV_PIX_FMT_YUVJ444P: *format = (
PixelFormat::Type)AV_PIX_FMT_YUVJ444P;
return 1;
184 case AV_PIX_FMT_YUVJ440P: *format = (
PixelFormat::Type)AV_PIX_FMT_YUVJ440P;
return 1;
189 static SwsContext *avpkitSws_getContext(
int srcW,
int srcH, PixelFormat::Type srcFormat,
190 int dstW,
int dstH, PixelFormat::Type dstFormat,
int flags,
191 SwsFilter *srcFilter, SwsFilter *dstFilter,
const double *param)
195 int srcRange=handle_jpeg(&srcFormat);
196 int dstRange=handle_jpeg(&dstFormat);
198 if(!(c=sws_alloc_context()))
201 av_opt_set_int(c,
"sws_flags", flags, 0);
202 av_opt_set_int(c,
"srcw", srcW, 0);
203 av_opt_set_int(c,
"srch", srcH, 0);
204 av_opt_set_int(c,
"dstw", dstW, 0);
205 av_opt_set_int(c,
"dsth", dstH, 0);
206 av_opt_set_int(c,
"src_range", srcRange, 0);
207 av_opt_set_int(c,
"dst_range", dstRange, 0);
208 av_opt_set_int(c,
"src_format", srcFormat, 0);
209 av_opt_set_int(c,
"dst_format", dstFormat, 0);
212 av_opt_set_double(c,
"param0", param[0], 0);
213 av_opt_set_double(c,
"param1", param[1], 0);
216 coeff = sws_getCoefficients(SWS_CS_DEFAULT);
217 sws_setColorspaceDetails(c, coeff, srcRange, coeff , dstRange, 0, 1<<16, 1<<16);
219 if(sws_init_context(c, srcFilter, dstFilter) < 0){
227 VideoResampler :: make(
228 int32_t outputWidth, int32_t outputHeight,
229 IPixelFormat::Type outputFmt,
230 int32_t inputWidth, int32_t inputHeight,
231 IPixelFormat::Type inputFmt)
233 VideoResampler* retval = 0;
236 if (outputWidth <= 0)
237 throw std::invalid_argument(
"invalid output width");
238 if (outputHeight <= 0)
239 throw std::invalid_argument(
"invalid output height");
240 if (outputFmt == IPixelFormat::NONE)
241 throw std::invalid_argument(
"cannot set output pixel format to none");
243 throw std::invalid_argument(
"invalid input width");
244 if (inputHeight <= 0)
245 throw std::invalid_argument(
"invalid input height");
246 if (inputFmt == IPixelFormat::NONE)
247 throw std::invalid_argument(
"cannot set input pixel format to none");
249 retval = VideoResampler::make();
252 retval->mOHeight = outputHeight;
253 retval->mOWidth = outputWidth;
254 retval->mOPixelFmt = outputFmt;
256 retval->mIHeight = inputHeight;
257 retval->mIWidth = inputWidth;
258 retval->mIPixelFmt = inputFmt;
261 if (inputWidth < outputWidth)
268 retval->mContext = avpkitSws_getContext(
280 if (!retval->mContext)
281 throw std::runtime_error(
"could not allocate a image rescaler");
284 catch (std::bad_alloc& e)
286 VS_REF_RELEASE(retval);
288 catch (std::exception& e)
290 VS_LOG_DEBUG(
"error: %s", e.what());
291 VS_REF_RELEASE(retval);
298 VideoResampler :: getNumProperties()
300 return Property::getNumProperties(mContext);
304 VideoResampler :: getPropertyMetaData(int32_t propertyNo)
306 return Property::getPropertyMetaData(mContext, propertyNo);
310 VideoResampler :: getPropertyMetaData(
const char *name)
312 return Property::getPropertyMetaData(mContext, name);
318 return Property::setProperty(mContext, valuesToSet, valuesNotFound);
323 VideoResampler :: setProperty(
const char* aName,
const char *aValue)
325 return Property::setProperty(mContext, aName, aValue);
329 VideoResampler :: setProperty(
const char* aName,
double aValue)
331 return Property::setProperty(mContext, aName, aValue);
335 VideoResampler :: setProperty(
const char* aName, int64_t aValue)
337 return Property::setProperty(mContext, aName, aValue);
341 VideoResampler :: setProperty(
const char* aName,
bool aValue)
343 return Property::setProperty(mContext, aName, aValue);
348 VideoResampler :: setProperty(
const char* aName,
IRational *aValue)
350 return Property::setProperty(mContext, aName, aValue);
355 VideoResampler :: getPropertyAsString(
const char *aName)
357 return Property::getPropertyAsString(mContext, aName);
361 VideoResampler :: getPropertyAsDouble(
const char *aName)
363 return Property::getPropertyAsDouble(mContext, aName);
367 VideoResampler :: getPropertyAsLong(
const char *aName)
369 return Property::getPropertyAsLong(mContext, aName);
373 VideoResampler :: getPropertyAsRational(
const char *aName)
375 return Property::getPropertyAsRational(mContext, aName);
379 VideoResampler :: getPropertyAsBoolean(
const char *aName)
381 return Property::getPropertyAsBoolean(mContext, aName);
Represents settable properties that effect how AVPKit objects operate.
This class wraps represents a Rational number for the AVPKit.
Represents one raw (undecoded) picture in a video stream, plus a timestamp for when to display that v...
virtual void setComplete(bool aIsComplete, IPixelFormat::Type format, int width, int height, int64_t pts)
After modifying the raw data in this buffer, call this function to let the object know it is now comp...
virtual int64_t getPts()
What is the Presentation Time Stamp (in Microseconds) of this picture.
virtual IPixelFormat::Type getPixelType()
Returns the pixel format of the picture.
virtual bool isComplete()
Is this picture completely decoded?
virtual void setQuality(int newQuality)
Set the Quality to a new value.
virtual int getQuality()
This value is the quality setting this VideoPicture had when it was decoded, or is the value to use w...
virtual int getWidth()
What is the width of the picture.
virtual int getHeight()
What is the height of the picture.
VS_API_AVPKIT AVFrame * getAVFrame()
Call to get the raw underlying AVFrame we manage; don't pass this to ffmpeg directly as ffmpeg often ...
This library contains routines used by AVPKit libraries for "ferry"ing Java objects to and from nativ...
WARNING: Do not use logging in this class, and do not set any static file variables to values other t...