From b1904d27f09df80ee3ab8dc8c51bf0777dd9f6f0 Mon Sep 17 00:00:00 2001 From: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com> Date: Fri, 3 Jan 2014 15:49:28 -0500 Subject: [PATCH] * 37884: add scale_and_pad() to VideoScaler class --- daemon/src/video/video_mixer.cpp | 15 +++---------- daemon/src/video/video_scaler.cpp | 35 +++++++++++++++++++++++++++++++ daemon/src/video/video_scaler.h | 3 +++ 3 files changed, 41 insertions(+), 12 deletions(-) diff --git a/daemon/src/video/video_mixer.cpp b/daemon/src/video/video_mixer.cpp index bbceb20bf4..16879b3290 100644 --- a/daemon/src/video/video_mixer.cpp +++ b/daemon/src/video/video_mixer.cpp @@ -97,7 +97,6 @@ void VideoMixer::update(Observable<std::shared_ptr<VideoFrame> >* ob, void VideoMixer::render_frame(VideoFrame& input, const int index) { VideoScaler scaler; - VideoFrame scaled_input; if (!width_ or !height_) return; @@ -118,18 +117,10 @@ void VideoMixer::render_frame(VideoFrame& input, const int index) const int zoom = ceil(sqrt(n)); const int cell_width = width_ / zoom; const int cell_height = height_ / zoom; + const int xoff = (index % zoom) * cell_width; + const int yoff = (index / zoom) * cell_height; - if (!scaled_input.allocBuffer(cell_width, cell_height, - VIDEO_PIXFMT_YUV420P)) { - ERROR("VideoFrame::allocBuffer() failed"); - return; - } - - int xoff = (index % zoom) * cell_width; - int yoff = (index / zoom) * cell_height; - - scaler.scale(input, scaled_input); - output.blit(scaled_input, xoff, yoff); + scaler.scale_and_pad(input, output, xoff, yoff, cell_width, cell_height); publishFrame(); } diff --git a/daemon/src/video/video_scaler.cpp b/daemon/src/video/video_scaler.cpp index 30ff53b620..bcbe18f5dc 100644 --- a/daemon/src/video/video_scaler.cpp +++ b/daemon/src/video/video_scaler.cpp @@ -62,6 +62,41 @@ void VideoScaler::scale(VideoFrame &input, VideoFrame &output) input_frame->height, output_frame->data, output_frame->linesize); } +void VideoScaler::scale_and_pad(VideoFrame &input, VideoFrame &output, + unsigned xoff, unsigned yoff, + unsigned dest_width, unsigned dest_height) +{ + AVFrame *input_frame = input.get(); + AVFrame *output_frame = output.get(); + uint8_t *data[AV_NUM_DATA_POINTERS]; + + for (int i = 0; i < AV_NUM_DATA_POINTERS; i++) { + if (output_frame->data[i]) { + const unsigned divisor = i == 0 ? 1 : 2; + unsigned offset = (yoff * output_frame->linesize[i] + xoff) / divisor; + data[i] = output_frame->data[i] + offset; + } else + data[i] = 0; + } + + ctx_ = sws_getCachedContext(ctx_, + input_frame->width, + input_frame->height, + (AVPixelFormat) input_frame->format, + dest_width, + dest_height, + (AVPixelFormat) output_frame->format, + mode_, + NULL, NULL, NULL); + if (!ctx_) { + ERROR("Unable to create a scaler context"); + return; + } + + sws_scale(ctx_, input_frame->data, input_frame->linesize, 0, + input_frame->height, data, output_frame->linesize); +} + void VideoScaler::reset() { if (ctx_) { diff --git a/daemon/src/video/video_scaler.h b/daemon/src/video/video_scaler.h index ad7bb70c1a..96e09290e7 100644 --- a/daemon/src/video/video_scaler.h +++ b/daemon/src/video/video_scaler.h @@ -46,6 +46,9 @@ public: ~VideoScaler(); void scale(VideoFrame &input, VideoFrame &output); void reset(); + void scale_and_pad(VideoFrame &input, VideoFrame &output, + unsigned xoff, unsigned yoff, + unsigned dest_width, unsigned dest_height); private: NON_COPYABLE(VideoScaler); -- GitLab