@@ -497,10 +497,6 @@ int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst,
497
497
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
498
498
}
499
499
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
-
504
500
int retVal = Release ();
505
501
if (retVal < 0 ) {
506
502
return retVal;
@@ -654,8 +650,8 @@ int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst,
654
650
// Creating a wrapper to the image - setting image data to NULL.
655
651
// Actual pointer will be set in encode. Setting align to 1, as it
656
652
// 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 );
659
655
660
656
// Note the order we use is different from webm, we have lowest resolution
661
657
// at position 0 and they have highest resolution at position 0.
@@ -703,9 +699,10 @@ int LibvpxVp8Encoder::InitEncode(const VideoCodec* inst,
703
699
// Setting alignment to 32 - as that ensures at least 16 for all
704
700
// planes (32 for Y, 16 for U,V). Libvpx sets the requested stride for
705
701
// 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 );
709
706
SetStreamState (stream_bitrates[stream_idx] > 0 , stream_idx);
710
707
vpx_configs_[i].rc_target_bitrate = stream_bitrates[stream_idx];
711
708
if (stream_bitrates[stream_idx] > 0 ) {
@@ -1017,12 +1014,26 @@ int LibvpxVp8Encoder::Encode(const VideoFrame& frame,
1017
1014
flags[i] = send_key_frame ? VPX_EFLAG_FORCE_KF : EncodeFlags (tl_configs[i]);
1018
1015
}
1019
1016
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
+
1026
1037
struct CleanUpOnExit {
1027
1038
explicit CleanUpOnExit (vpx_image_t & raw_image) : raw_image_(raw_image) {}
1028
1039
~CleanUpOnExit () {
@@ -1033,6 +1044,22 @@ int LibvpxVp8Encoder::Encode(const VideoFrame& frame,
1033
1044
vpx_image_t & raw_image_;
1034
1045
} clean_up_on_exit (raw_images_[0 ]);
1035
1046
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
+
1036
1063
if (send_key_frame) {
1037
1064
// Adapt the size of the key frame when in screenshare with 1 temporal
1038
1065
// layer.
@@ -1284,105 +1311,6 @@ int LibvpxVp8Encoder::RegisterEncodeCompleteCallback(
1284
1311
return WEBRTC_VIDEO_CODEC_OK;
1285
1312
}
1286
1313
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
-
1386
1314
// static
1387
1315
LibvpxVp8Encoder::VariableFramerateExperiment
1388
1316
LibvpxVp8Encoder::ParseVariableFramerateConfig (std::string group_name) {
0 commit comments