@@ -497,10 +497,6 @@ int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst,
497497 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
498498 }
499499
500- // Use the previous pixel format to avoid extra image allocations.
501- vpx_img_fmt_t pixel_format =
502- raw_images_.empty () ? VPX_IMG_FMT_I420 : raw_images_[0 ].fmt ;
503-
504500 int retVal = Release ();
505501 if (retVal < 0 ) {
506502 return retVal;
@@ -654,8 +650,8 @@ int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst,
654650 // Creating a wrapper to the image - setting image data to NULL.
655651 // Actual pointer will be set in encode. Setting align to 1, as it
656652 // is meaningless (no memory allocation is done here).
657- libvpx_->img_wrap (&raw_images_[0 ], pixel_format , inst->width , inst-> height , 1 ,
658- NULL );
653+ libvpx_->img_wrap (&raw_images_[0 ], VPX_IMG_FMT_I420 , inst->width ,
654+ inst-> height , 1 , NULL );
659655
660656 // Note the order we use is different from webm, we have lowest resolution
661657 // at position 0 and they have highest resolution at position 0.
@@ -703,9 +699,10 @@ int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst,
703699 // Setting alignment to 32 - as that ensures at least 16 for all
704700 // planes (32 for Y, 16 for U,V). Libvpx sets the requested stride for
705701 // the y plane, but only half of it to the u and v planes.
706- libvpx_->img_alloc (
707- &raw_images_[i], pixel_format, inst->simulcastStream [stream_idx].width ,
708- inst->simulcastStream [stream_idx].height , kVp832ByteAlign );
702+ libvpx_->img_alloc (&raw_images_[i], VPX_IMG_FMT_I420,
703+ inst->simulcastStream [stream_idx].width ,
704+ inst->simulcastStream [stream_idx].height ,
705+ kVp832ByteAlign );
709706 SetStreamState (stream_bitrates[stream_idx] > 0 , stream_idx);
710707 vpx_configs_[i].rc_target_bitrate = stream_bitrates[stream_idx];
711708 if (stream_bitrates[stream_idx] > 0 ) {
@@ -1017,12 +1014,26 @@ int LibvpxVp8Encoder::Encode(const VideoFrame& frame,
10171014 flags[i] = send_key_frame ? VPX_EFLAG_FORCE_KF : EncodeFlags (tl_configs[i]);
10181015 }
10191016
1020- rtc::scoped_refptr<VideoFrameBuffer> input_image = frame.video_frame_buffer ();
1021- if (input_image->type () != VideoFrameBuffer::Type::kI420 &&
1022- input_image->type () != VideoFrameBuffer::Type::kNV12 ) {
1023- input_image = input_image->ToI420 ();
1024- }
1025- PrepareRawImagesForEncoding (input_image);
1017+ rtc::scoped_refptr<I420BufferInterface> input_image =
1018+ frame.video_frame_buffer ()->ToI420 ();
1019+ // Since we are extracting raw pointers from |input_image| to
1020+ // |raw_images_[0]|, the resolution of these frames must match.
1021+ RTC_DCHECK_EQ (input_image->width (), raw_images_[0 ].d_w );
1022+ RTC_DCHECK_EQ (input_image->height (), raw_images_[0 ].d_h );
1023+
1024+ // Image in vpx_image_t format.
1025+ // Input image is const. VP8's raw image is not defined as const.
1026+ raw_images_[0 ].planes [VPX_PLANE_Y] =
1027+ const_cast <uint8_t *>(input_image->DataY ());
1028+ raw_images_[0 ].planes [VPX_PLANE_U] =
1029+ const_cast <uint8_t *>(input_image->DataU ());
1030+ raw_images_[0 ].planes [VPX_PLANE_V] =
1031+ const_cast <uint8_t *>(input_image->DataV ());
1032+
1033+ raw_images_[0 ].stride [VPX_PLANE_Y] = input_image->StrideY ();
1034+ raw_images_[0 ].stride [VPX_PLANE_U] = input_image->StrideU ();
1035+ raw_images_[0 ].stride [VPX_PLANE_V] = input_image->StrideV ();
1036+
10261037 struct CleanUpOnExit {
10271038 explicit CleanUpOnExit (vpx_image_t & raw_image) : raw_image_(raw_image) {}
10281039 ~CleanUpOnExit () {
@@ -1033,6 +1044,22 @@ int LibvpxVp8Encoder::Encode(const VideoFrame& frame,
10331044 vpx_image_t & raw_image_;
10341045 } clean_up_on_exit (raw_images_[0 ]);
10351046
1047+ for (size_t i = 1 ; i < encoders_.size (); ++i) {
1048+ // Scale the image down a number of times by downsampling factor
1049+ libyuv::I420Scale (
1050+ raw_images_[i - 1 ].planes [VPX_PLANE_Y],
1051+ raw_images_[i - 1 ].stride [VPX_PLANE_Y],
1052+ raw_images_[i - 1 ].planes [VPX_PLANE_U],
1053+ raw_images_[i - 1 ].stride [VPX_PLANE_U],
1054+ raw_images_[i - 1 ].planes [VPX_PLANE_V],
1055+ raw_images_[i - 1 ].stride [VPX_PLANE_V], raw_images_[i - 1 ].d_w ,
1056+ raw_images_[i - 1 ].d_h , raw_images_[i].planes [VPX_PLANE_Y],
1057+ raw_images_[i].stride [VPX_PLANE_Y], raw_images_[i].planes [VPX_PLANE_U],
1058+ raw_images_[i].stride [VPX_PLANE_U], raw_images_[i].planes [VPX_PLANE_V],
1059+ raw_images_[i].stride [VPX_PLANE_V], raw_images_[i].d_w ,
1060+ raw_images_[i].d_h , libyuv::kFilterBilinear );
1061+ }
1062+
10361063 if (send_key_frame) {
10371064 // Adapt the size of the key frame when in screenshare with 1 temporal
10381065 // layer.
@@ -1284,105 +1311,6 @@ int LibvpxVp8Encoder::RegisterEncodeCompleteCallback(
12841311 return WEBRTC_VIDEO_CODEC_OK;
12851312}
12861313
1287- void LibvpxVp8Encoder::PrepareRawImagesForEncoding (
1288- const rtc::scoped_refptr<VideoFrameBuffer>& frame) {
1289- // Since we are extracting raw pointers from |input_image| to
1290- // |raw_images_[0]|, the resolution of these frames must match.
1291- RTC_DCHECK_EQ (frame->width (), raw_images_[0 ].d_w );
1292- RTC_DCHECK_EQ (frame->height (), raw_images_[0 ].d_h );
1293- switch (frame->type ()) {
1294- case VideoFrameBuffer::Type::kI420 :
1295- return PrepareI420Image (frame->GetI420 ());
1296- case VideoFrameBuffer::Type::kNV12 :
1297- return PrepareNV12Image (frame->GetNV12 ());
1298- default :
1299- RTC_NOTREACHED ();
1300- }
1301- }
1302-
1303- void LibvpxVp8Encoder::MaybeUpdatePixelFormat (vpx_img_fmt fmt) {
1304- RTC_DCHECK (!raw_images_.empty ());
1305- if (raw_images_[0 ].fmt == fmt) {
1306- RTC_DCHECK (std::all_of (
1307- std::next (raw_images_.begin ()), raw_images_.end (),
1308- [fmt](const vpx_image_t & raw_img) { return raw_img.fmt == fmt; }))
1309- << " Not all raw images had the right format!" ;
1310- return ;
1311- }
1312- RTC_LOG (INFO) << " Updating vp8 encoder pixel format to "
1313- << (fmt == VPX_IMG_FMT_NV12 ? " NV12" : " I420" );
1314- for (size_t i = 0 ; i < raw_images_.size (); ++i) {
1315- vpx_image_t & img = raw_images_[i];
1316- auto d_w = img.d_w ;
1317- auto d_h = img.d_h ;
1318- libvpx_->img_free (&img);
1319- // First image is wrapping the input frame, the rest are allocated.
1320- if (i == 0 ) {
1321- libvpx_->img_wrap (&img, fmt, d_w, d_h, 1 , NULL );
1322- } else {
1323- libvpx_->img_alloc (&img, fmt, d_w, d_h, kVp832ByteAlign );
1324- }
1325- }
1326- }
1327-
1328- void LibvpxVp8Encoder::PrepareI420Image (const I420BufferInterface* frame) {
1329- RTC_DCHECK (!raw_images_.empty ());
1330- MaybeUpdatePixelFormat (VPX_IMG_FMT_I420);
1331- // Image in vpx_image_t format.
1332- // Input image is const. VP8's raw image is not defined as const.
1333- raw_images_[0 ].planes [VPX_PLANE_Y] = const_cast <uint8_t *>(frame->DataY ());
1334- raw_images_[0 ].planes [VPX_PLANE_U] = const_cast <uint8_t *>(frame->DataU ());
1335- raw_images_[0 ].planes [VPX_PLANE_V] = const_cast <uint8_t *>(frame->DataV ());
1336-
1337- raw_images_[0 ].stride [VPX_PLANE_Y] = frame->StrideY ();
1338- raw_images_[0 ].stride [VPX_PLANE_U] = frame->StrideU ();
1339- raw_images_[0 ].stride [VPX_PLANE_V] = frame->StrideV ();
1340-
1341- for (size_t i = 1 ; i < encoders_.size (); ++i) {
1342- // Scale the image down a number of times by downsampling factor
1343- libyuv::I420Scale (
1344- raw_images_[i - 1 ].planes [VPX_PLANE_Y],
1345- raw_images_[i - 1 ].stride [VPX_PLANE_Y],
1346- raw_images_[i - 1 ].planes [VPX_PLANE_U],
1347- raw_images_[i - 1 ].stride [VPX_PLANE_U],
1348- raw_images_[i - 1 ].planes [VPX_PLANE_V],
1349- raw_images_[i - 1 ].stride [VPX_PLANE_V], raw_images_[i - 1 ].d_w ,
1350- raw_images_[i - 1 ].d_h , raw_images_[i].planes [VPX_PLANE_Y],
1351- raw_images_[i].stride [VPX_PLANE_Y], raw_images_[i].planes [VPX_PLANE_U],
1352- raw_images_[i].stride [VPX_PLANE_U], raw_images_[i].planes [VPX_PLANE_V],
1353- raw_images_[i].stride [VPX_PLANE_V], raw_images_[i].d_w ,
1354- raw_images_[i].d_h , libyuv::kFilterBilinear );
1355- }
1356- }
1357-
1358- void LibvpxVp8Encoder::PrepareNV12Image (const NV12BufferInterface* frame) {
1359- RTC_DCHECK (!raw_images_.empty ());
1360- MaybeUpdatePixelFormat (VPX_IMG_FMT_NV12);
1361- // Image in vpx_image_t format.
1362- // Input image is const. VP8's raw image is not defined as const.
1363- raw_images_[0 ].planes [VPX_PLANE_Y] = const_cast <uint8_t *>(frame->DataY ());
1364- raw_images_[0 ].planes [VPX_PLANE_U] = const_cast <uint8_t *>(frame->DataUV ());
1365- raw_images_[0 ].planes [VPX_PLANE_V] = raw_images_[0 ].planes [VPX_PLANE_U] + 1 ;
1366- raw_images_[0 ].stride [VPX_PLANE_Y] = frame->StrideY ();
1367- raw_images_[0 ].stride [VPX_PLANE_U] = frame->StrideUV ();
1368- raw_images_[0 ].stride [VPX_PLANE_V] = frame->StrideUV ();
1369-
1370- for (size_t i = 1 ; i < encoders_.size (); ++i) {
1371- // Scale the image down a number of times by downsampling factor
1372- libyuv::NV12Scale (
1373- raw_images_[i - 1 ].planes [VPX_PLANE_Y],
1374- raw_images_[i - 1 ].stride [VPX_PLANE_Y],
1375- raw_images_[i - 1 ].planes [VPX_PLANE_U],
1376- raw_images_[i - 1 ].stride [VPX_PLANE_U], raw_images_[i - 1 ].d_w ,
1377- raw_images_[i - 1 ].d_h , raw_images_[i].planes [VPX_PLANE_Y],
1378- raw_images_[i].stride [VPX_PLANE_Y], raw_images_[i].planes [VPX_PLANE_U],
1379- raw_images_[i].stride [VPX_PLANE_U], raw_images_[i].d_w ,
1380- raw_images_[i].d_h , libyuv::kFilterBilinear );
1381- raw_images_[i].planes [VPX_PLANE_V] = raw_images_[i].planes [VPX_PLANE_U] + 1 ;
1382- raw_images_[i].stride [VPX_PLANE_V] = raw_images_[i].stride [VPX_PLANE_U] + 1 ;
1383- }
1384- }
1385-
13861314// static
13871315LibvpxVp8Encoder::VariableFramerateExperiment
13881316LibvpxVp8Encoder::ParseVariableFramerateConfig (std::string group_name) {
0 commit comments