| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. | 2  *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. | 
| 3  * | 3  * | 
| 4  *  Use of this source code is governed by a BSD-style license | 4  *  Use of this source code is governed by a BSD-style license | 
| 5  *  that can be found in the LICENSE file in the root of the source | 5  *  that can be found in the LICENSE file in the root of the source | 
| 6  *  tree. An additional intellectual property rights grant can be found | 6  *  tree. An additional intellectual property rights grant can be found | 
| 7  *  in the file PATENTS.  All contributing project authors may | 7  *  in the file PATENTS.  All contributing project authors may | 
| 8  *  be found in the AUTHORS file in the root of the source tree. | 8  *  be found in the AUTHORS file in the root of the source tree. | 
| 9  */ | 9  */ | 
| 10 | 10 | 
| (...skipping 13 matching lines...) Expand all  Loading... | 
| 24 | 24 | 
| 25 // Round to 2 pixels because Chroma channels are half size. | 25 // Round to 2 pixels because Chroma channels are half size. | 
| 26 #define ROUNDTO2(v) (v & ~1) | 26 #define ROUNDTO2(v) (v & ~1) | 
| 27 | 27 | 
| 28 bool VideoFrame::CopyToPlanes(uint8_t* dst_y, | 28 bool VideoFrame::CopyToPlanes(uint8_t* dst_y, | 
| 29                               uint8_t* dst_u, | 29                               uint8_t* dst_u, | 
| 30                               uint8_t* dst_v, | 30                               uint8_t* dst_v, | 
| 31                               int32_t dst_pitch_y, | 31                               int32_t dst_pitch_y, | 
| 32                               int32_t dst_pitch_u, | 32                               int32_t dst_pitch_u, | 
| 33                               int32_t dst_pitch_v) const { | 33                               int32_t dst_pitch_v) const { | 
| 34   const rtc::scoped_refptr<webrtc::VideoFrameBuffer>& buffer = | 34   if (!GetYPlane() || !GetUPlane() || !GetVPlane()) { | 
| 35       video_frame_buffer(); | 35     LOG(LS_ERROR) << "NULL plane pointer."; | 
| 36   if (!buffer) { |  | 
| 37     LOG(LS_ERROR) << "NULL video buffer."; |  | 
| 38     return false; | 36     return false; | 
| 39   } | 37   } | 
| 40   int32_t src_width = width(); | 38   int32_t src_width = width(); | 
| 41   int32_t src_height = height(); | 39   int32_t src_height = height(); | 
| 42   return libyuv::I420Copy(buffer->DataY(), buffer->StrideY(), | 40   return libyuv::I420Copy(GetYPlane(), GetYPitch(), | 
| 43                           buffer->DataU(), buffer->StrideU(), | 41                           GetUPlane(), GetUPitch(), | 
| 44                           buffer->DataV(), buffer->StrideV(), | 42                           GetVPlane(), GetVPitch(), | 
| 45                           dst_y, dst_pitch_y, | 43                           dst_y, dst_pitch_y, | 
| 46                           dst_u, dst_pitch_u, | 44                           dst_u, dst_pitch_u, | 
| 47                           dst_v, dst_pitch_v, | 45                           dst_v, dst_pitch_v, | 
| 48                           src_width, src_height) == 0; | 46                           src_width, src_height) == 0; | 
| 49 } | 47 } | 
| 50 | 48 | 
| 51 size_t VideoFrame::ConvertToRgbBuffer(uint32_t to_fourcc, | 49 size_t VideoFrame::ConvertToRgbBuffer(uint32_t to_fourcc, | 
| 52                                       uint8_t* buffer, | 50                                       uint8_t* buffer, | 
| 53                                       size_t size, | 51                                       size_t size, | 
| 54                                       int stride_rgb) const { | 52                                       int stride_rgb) const { | 
| 55   const size_t needed = std::abs(stride_rgb) * static_cast<size_t>(height()); | 53   const size_t needed = std::abs(stride_rgb) * static_cast<size_t>(height()); | 
| 56   if (size < needed) { | 54   if (size < needed) { | 
| 57     LOG(LS_WARNING) << "RGB buffer is not large enough"; | 55     LOG(LS_WARNING) << "RGB buffer is not large enough"; | 
| 58     return needed; | 56     return needed; | 
| 59   } | 57   } | 
| 60 | 58 | 
| 61   if (libyuv::ConvertFromI420( | 59   if (libyuv::ConvertFromI420(GetYPlane(), GetYPitch(), GetUPlane(), | 
| 62           video_frame_buffer()->DataY(), video_frame_buffer()->StrideY(), | 60                               GetUPitch(), GetVPlane(), GetVPitch(), buffer, | 
| 63           video_frame_buffer()->DataU(), video_frame_buffer()->StrideU(), | 61                               stride_rgb, width(), height(), to_fourcc)) { | 
| 64           video_frame_buffer()->DataV(), video_frame_buffer()->StrideV(), |  | 
| 65           buffer, stride_rgb, width(), height(), to_fourcc)) { |  | 
| 66     LOG(LS_ERROR) << "RGB type not supported: " << to_fourcc; | 62     LOG(LS_ERROR) << "RGB type not supported: " << to_fourcc; | 
| 67     return 0;  // 0 indicates error | 63     return 0;  // 0 indicates error | 
| 68   } | 64   } | 
| 69   return needed; | 65   return needed; | 
| 70 } | 66 } | 
| 71 | 67 | 
| 72 // TODO(fbarchard): Handle odd width/height with rounding. | 68 // TODO(fbarchard): Handle odd width/height with rounding. | 
| 73 // TODO(nisse): If method is kept, switch to using int instead of | 69 // TODO(nisse): If method is kept, switch to using int instead of | 
| 74 // size_t and int32_t. | 70 // size_t and int32_t. | 
| 75 void VideoFrame::StretchToPlanes(uint8_t* dst_y, | 71 void VideoFrame::StretchToPlanes(uint8_t* dst_y, | 
| 76                                  uint8_t* dst_u, | 72                                  uint8_t* dst_u, | 
| 77                                  uint8_t* dst_v, | 73                                  uint8_t* dst_v, | 
| 78                                  int32_t dst_pitch_y, | 74                                  int32_t dst_pitch_y, | 
| 79                                  int32_t dst_pitch_u, | 75                                  int32_t dst_pitch_u, | 
| 80                                  int32_t dst_pitch_v, | 76                                  int32_t dst_pitch_v, | 
| 81                                  size_t dst_width, | 77                                  size_t dst_width, | 
| 82                                  size_t dst_height, | 78                                  size_t dst_height, | 
| 83                                  bool interpolate, | 79                                  bool interpolate, | 
| 84                                  bool vert_crop) const { | 80                                  bool vert_crop) const { | 
| 85   if (!video_frame_buffer()) { | 81   if (!GetYPlane() || !GetUPlane() || !GetVPlane()) { | 
| 86     LOG(LS_ERROR) << "NULL frame buffer."; | 82     LOG(LS_ERROR) << "NULL plane pointer."; | 
| 87     return; | 83     return; | 
| 88   } | 84   } | 
| 89 | 85 | 
| 90   size_t src_width = width(); | 86   size_t src_width = width(); | 
| 91   size_t src_height = height(); | 87   size_t src_height = height(); | 
| 92   if (dst_width == src_width && dst_height == src_height) { | 88   if (dst_width == src_width && dst_height == src_height) { | 
| 93     CopyToPlanes(dst_y, dst_u, dst_v, dst_pitch_y, dst_pitch_u, dst_pitch_v); | 89     CopyToPlanes(dst_y, dst_u, dst_v, dst_pitch_y, dst_pitch_u, dst_pitch_v); | 
| 94     return; | 90     return; | 
| 95   } | 91   } | 
| 96   const uint8_t* src_y = video_frame_buffer()->DataY(); | 92   const uint8_t* src_y = GetYPlane(); | 
| 97   const uint8_t* src_u = video_frame_buffer()->DataU(); | 93   const uint8_t* src_u = GetUPlane(); | 
| 98   const uint8_t* src_v = video_frame_buffer()->DataV(); | 94   const uint8_t* src_v = GetVPlane(); | 
| 99 | 95 | 
| 100   if (vert_crop) { | 96   if (vert_crop) { | 
| 101     // Adjust the input width:height ratio to be the same as the output ratio. | 97     // Adjust the input width:height ratio to be the same as the output ratio. | 
| 102     if (src_width * dst_height > src_height * dst_width) { | 98     if (src_width * dst_height > src_height * dst_width) { | 
| 103       // Reduce the input width, but keep size/position aligned for YuvScaler | 99       // Reduce the input width, but keep size/position aligned for YuvScaler | 
| 104       src_width = ROUNDTO2(src_height * dst_width / dst_height); | 100       src_width = ROUNDTO2(src_height * dst_width / dst_height); | 
| 105       int32_t iwidth_offset = ROUNDTO2((width() - src_width) / 2); | 101       int32_t iwidth_offset = ROUNDTO2((width() - src_width) / 2); | 
| 106       src_y += iwidth_offset; | 102       src_y += iwidth_offset; | 
| 107       src_u += iwidth_offset / 2; | 103       src_u += iwidth_offset / 2; | 
| 108       src_v += iwidth_offset / 2; | 104       src_v += iwidth_offset / 2; | 
| 109     } else if (src_width * dst_height < src_height * dst_width) { | 105     } else if (src_width * dst_height < src_height * dst_width) { | 
| 110       // Reduce the input height. | 106       // Reduce the input height. | 
| 111       src_height = src_width * dst_height / dst_width; | 107       src_height = src_width * dst_height / dst_width; | 
| 112       int32_t iheight_offset = | 108       int32_t iheight_offset = | 
| 113           static_cast<int32_t>((height() - src_height) >> 2); | 109           static_cast<int32_t>((height() - src_height) >> 2); | 
| 114       iheight_offset <<= 1;  // Ensure that iheight_offset is even. | 110       iheight_offset <<= 1;  // Ensure that iheight_offset is even. | 
| 115       src_y += iheight_offset * video_frame_buffer()->StrideY(); | 111       src_y += iheight_offset * GetYPitch(); | 
| 116       src_u += iheight_offset / 2 * video_frame_buffer()->StrideU(); | 112       src_u += iheight_offset / 2 * GetUPitch(); | 
| 117       src_v += iheight_offset / 2 * video_frame_buffer()->StrideV(); | 113       src_v += iheight_offset / 2 * GetVPitch(); | 
| 118     } | 114     } | 
| 119   } | 115   } | 
| 120 | 116 | 
| 121   // Scale to the output I420 frame. | 117   // Scale to the output I420 frame. | 
| 122   libyuv::Scale(src_y, src_u, src_v, video_frame_buffer()->StrideY(), | 118   libyuv::Scale(src_y, src_u, src_v, | 
| 123                 video_frame_buffer()->StrideU(), | 119                 GetYPitch(), GetUPitch(), GetVPitch(), | 
| 124                 video_frame_buffer()->StrideV(), |  | 
| 125                 static_cast<int>(src_width), static_cast<int>(src_height), | 120                 static_cast<int>(src_width), static_cast<int>(src_height), | 
| 126                 dst_y, dst_u, dst_v, dst_pitch_y, dst_pitch_u, dst_pitch_v, | 121                 dst_y, dst_u, dst_v, dst_pitch_y, dst_pitch_u, dst_pitch_v, | 
| 127                 static_cast<int>(dst_width), static_cast<int>(dst_height), | 122                 static_cast<int>(dst_width), static_cast<int>(dst_height), | 
| 128                 interpolate); | 123                 interpolate); | 
| 129 } | 124 } | 
| 130 | 125 | 
| 131 void VideoFrame::StretchToFrame(VideoFrame* dst, | 126 void VideoFrame::StretchToFrame(VideoFrame* dst, | 
| 132                                 bool interpolate, bool vert_crop) const { | 127                                 bool interpolate, bool vert_crop) const { | 
| 133   if (!dst) { | 128   if (!dst) { | 
| 134     LOG(LS_ERROR) << "NULL dst pointer."; | 129     LOG(LS_ERROR) << "NULL dst pointer."; | 
| 135     return; | 130     return; | 
| 136   } | 131   } | 
| 137 | 132 | 
| 138   StretchToPlanes(dst->video_frame_buffer()->MutableDataY(), | 133   StretchToPlanes(dst->GetYPlane(), dst->GetUPlane(), dst->GetVPlane(), | 
| 139                   dst->video_frame_buffer()->MutableDataU(), | 134                   dst->GetYPitch(), dst->GetUPitch(), dst->GetVPitch(), | 
| 140                   dst->video_frame_buffer()->MutableDataV(), |  | 
| 141                   dst->video_frame_buffer()->StrideY(), |  | 
| 142                   dst->video_frame_buffer()->StrideU(), |  | 
| 143                   dst->video_frame_buffer()->StrideV(), |  | 
| 144                   dst->width(), dst->height(), | 135                   dst->width(), dst->height(), | 
| 145                   interpolate, vert_crop); | 136                   interpolate, vert_crop); | 
| 146   dst->SetTimeStamp(GetTimeStamp()); | 137   dst->SetTimeStamp(GetTimeStamp()); | 
| 147   // Stretched frame should have the same rotation as the source. | 138   // Stretched frame should have the same rotation as the source. | 
| 148   dst->set_rotation(rotation()); | 139   dst->set_rotation(rotation()); | 
| 149 } | 140 } | 
| 150 | 141 | 
| 151 VideoFrame* VideoFrame::Stretch(size_t dst_width, size_t dst_height, | 142 VideoFrame* VideoFrame::Stretch(size_t dst_width, size_t dst_height, | 
| 152                                 bool interpolate, bool vert_crop) const { | 143                                 bool interpolate, bool vert_crop) const { | 
| 153   VideoFrame* dest = CreateEmptyFrame(static_cast<int>(dst_width), | 144   VideoFrame* dest = CreateEmptyFrame(static_cast<int>(dst_width), | 
| 154                                       static_cast<int>(dst_height), | 145                                       static_cast<int>(dst_height), | 
| 155                                       GetTimeStamp()); | 146                                       GetTimeStamp()); | 
| 156   if (dest) { | 147   if (dest) { | 
| 157     StretchToFrame(dest, interpolate, vert_crop); | 148     StretchToFrame(dest, interpolate, vert_crop); | 
| 158   } | 149   } | 
| 159   return dest; | 150   return dest; | 
| 160 } | 151 } | 
| 161 | 152 | 
| 162 bool VideoFrame::SetToBlack() { | 153 bool VideoFrame::SetToBlack() { | 
| 163   return libyuv::I420Rect(video_frame_buffer()->MutableDataY(), | 154   return libyuv::I420Rect(GetYPlane(), GetYPitch(), | 
| 164                           video_frame_buffer()->StrideY(), | 155                           GetUPlane(), GetUPitch(), | 
| 165                           video_frame_buffer()->MutableDataU(), | 156                           GetVPlane(), GetVPitch(), | 
| 166                           video_frame_buffer()->StrideU(), |  | 
| 167                           video_frame_buffer()->MutableDataV(), |  | 
| 168                           video_frame_buffer()->StrideV(), |  | 
| 169                           0, 0, | 157                           0, 0, | 
| 170                           width(), height(), | 158                           width(), height(), | 
| 171                           16, 128, 128) == 0; | 159                           16, 128, 128) == 0; | 
| 172 } | 160 } | 
| 173 | 161 | 
| 174 static const size_t kMaxSampleSize = 1000000000u; | 162 static const size_t kMaxSampleSize = 1000000000u; | 
| 175 // Returns whether a sample is valid. | 163 // Returns whether a sample is valid. | 
| 176 bool VideoFrame::Validate(uint32_t fourcc, | 164 bool VideoFrame::Validate(uint32_t fourcc, | 
| 177                           int w, | 165                           int w, | 
| 178                           int h, | 166                           int h, | 
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 314                  << " expected: " << expected_size | 302                  << " expected: " << expected_size | 
| 315                  << " sample[0..3]: " << static_cast<int>(four_samples[0]) | 303                  << " sample[0..3]: " << static_cast<int>(four_samples[0]) | 
| 316                  << ", " << static_cast<int>(four_samples[1]) | 304                  << ", " << static_cast<int>(four_samples[1]) | 
| 317                  << ", " << static_cast<int>(four_samples[2]) | 305                  << ", " << static_cast<int>(four_samples[2]) | 
| 318                  << ", " << static_cast<int>(four_samples[3]); | 306                  << ", " << static_cast<int>(four_samples[3]); | 
| 319   } | 307   } | 
| 320   return true; | 308   return true; | 
| 321 } | 309 } | 
| 322 | 310 | 
| 323 }  // namespace cricket | 311 }  // namespace cricket | 
| OLD | NEW | 
|---|