H264 outperforms HEVC SSIM at 3 Mbps, 1280x720

Originator:cellsworth
Number:rdar://47887172 Date Originated:2/7/19
Status:Open Resolved:
Product:AVFoundation Product Version:iOS 12.1
Classification:Bug Reproducible:Always
 
We are seeing that H264 consistently outperforms HEVC in terms of SSIM at 3 Mbps with a 1280x720 resolution. Please find attached the SSIM and PSNR of encoding the same asset on an iPhone 8 running iOS 12.1 at various bitrates using both HEVC and H264, as well as driver code. SSIM and PSNR were measured with FFmpeg using the following command: ffmpeg -i hevc.mp4 -i video.mp4 -lavfi "ssim;[0:v][1:v]psnr" -f null -

-----


+------+----------+----------+--+------+-----------+-----------+
| SSIM |          |          |  | PSNR |           |           |
+------+----------+----------+--+------+-----------+-----------+
| Mbps | H264     | HEVC     |  | Mbps | H264      | HEVC      |
| 1.6  | 0.868546 | 0.866705 |  | 1.6  | 28.742276 | 29.012076 |
| 1.8  | 0.878769 | 0.870306 |  | 1.8  | 29.127728 | 29.145616 |
| 2.0  | 0.887289 | 0.876988 |  | 2.0  | 29.493496 | 29.401263 |
| 2.2  | 0.894511 | 0.885587 |  | 2.2  | 29.826788 | 29.753897 |
| 2.4  | 0.901402 | 0.892895 |  | 2.4  | 30.168525 | 30.083894 |
| 2.6  | 0.907192 | 0.901793 |  | 2.6  | 30.482898 | 30.523067 |
| 2.8  | 0.912267 | 0.910082 |  | 2.8  | 30.776906 | 30.990894 |
| 3.0  | 0.916828 | 0.916097 |  | 3.0  | 31.044133 | 31.348581 |
| 3.2  | 0.921024 | 0.921129 |  | 3.2  | 31.316162 | 31.696412 |
| 3.4  | 0.924703 | 0.926292 |  | 3.4  | 31.564169 | 32.059309 |
| 3.6  | 0.928121 | 0.930604 |  | 3.6  | 31.793409 | 32.375958 |
| 3.8  | 0.931357 | 0.933995 |  | 3.8  | 32.039006 | 32.647455 |
| 4.2  | 0.936885 | 0.940416 |  | 4.2  | 32.458297 | 33.190408 |
| 4.7  | 0.942769 | 0.946592 |  | 4.7  | 32.956044 | 33.77437  |
| 5.6  | 0.951091 | 0.955087 |  | 5.6  | 33.749049 | 34.707639 |
| 7.2  | 0.961685 | 0.964716 |  | 7.2  | 34.977282 | 35.99391  |
| 10.8 | 0.974855 | 0.97714  |  | 10.8 | 37.143887 | 38.316594 |
| 14.4 | 0.98164  | 0.983663 |  | 14.4 | 38.844081 | 40.099846 |
| 21.6 | 0.988423 | 0.989922 |  | 21.6 | 41.34255  | 42.658182 |
| 28.8 | 0.991736 | 0.992605 |  | 28.8 | 43.166993 | 44.312512 |
| 43.2 | 0.995039 | 0.994992 |  | 43.2 | 45.774187 | 46.329256 |
| 57.6 | 0.996671 | 0.995594 |  | 57.6 | 47.556865 | 47.045504 |
+------+----------+----------+--+------+-----------+-----------+

-----

- (void)testCodec:(AVVideoCodecType)codec withBitrate:(CGFloat)bitRate {
    NSURL *const outputUrl = [[[NSURL fileURLWithPath:NSTemporaryDirectory()]
                               URLByAppendingPathComponent:[[NSUUID UUID] UUIDString]]
                              URLByAppendingPathExtension:@"mp4"];

    NSURL *const url = [[NSBundle bundleForClass:[self class]] URLForResource:@"video" withExtension:@"mp4"];
    AVAsset *const asset = [AVAsset assetWithURL:url];
    AVAssetTrack *const videoTrack = [[asset tracksWithMediaType:AVMediaTypeVideo] firstObject];
    NSError *error = nil;
    AVAssetReader *const assetReader = [AVAssetReader assetReaderWithAsset:asset error:&error];
    XCTAssertNil(error);
    AVAssetWriter *const assetWriter = [AVAssetWriter assetWriterWithURL:outputUrl fileType:AVFileTypeMPEG4 error:&error];
    XCTAssertNil(error);

    AVAssetWriterInput *const input = [[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeVideo
                                                                     outputSettings:@{
                                                                                      AVVideoCodecKey: codec,
                                                                                      AVVideoWidthKey: @(1280),
                                                                                      AVVideoHeightKey: @(720),
                                                                                      AVVideoCompressionPropertiesKey: @{
                                                                                              AVVideoAverageBitRateKey: @(bitRate),
                                                                                              }
                                                                                      }];

    AVAssetReaderOutput *const output = [[AVAssetReaderTrackOutput alloc] initWithTrack:videoTrack
                                                                         outputSettings:@{
                                                                                          (id)kCVPixelBufferPixelFormatTypeKey:
                                                                                              @(kCVPixelFormatType_32BGRA),
                                                                                          }];

    [assetReader addOutput:output];
    [assetWriter addInput:input];

    XCTAssertNil(assetReader.error);
    XCTAssertNil(assetWriter.error);

    [assetReader startReading];
    [assetWriter startWriting];

    [assetWriter startSessionAtSourceTime:kCMTimeZero];

    const dispatch_queue_t queue = dispatch_queue_create("transcode", DISPATCH_QUEUE_SERIAL);
    const dispatch_semaphore_t transcode = dispatch_semaphore_create(0);
    [input requestMediaDataWhenReadyOnQueue:queue usingBlock:^{
        while ([input isReadyForMoreMediaData]) {
            const CMSampleBufferRef sampleBuffer = [output copyNextSampleBuffer];

            XCTAssertNil(assetReader.error);
            XCTAssertNil(assetWriter.error);

            if (sampleBuffer) {
                [input appendSampleBuffer:sampleBuffer];
                CFRelease(sampleBuffer);
            } else {
                [input markAsFinished];
                dispatch_semaphore_signal(transcode);
            }
        }
    }];

    dispatch_semaphore_wait(transcode, DISPATCH_TIME_FOREVER);

    const dispatch_semaphore_t write = dispatch_semaphore_create(0);
    [assetWriter finishWritingWithCompletionHandler:^{
        dispatch_semaphore_signal(write);
    }];

    XCTAssertNil(assetWriter.error);

    dispatch_semaphore_wait(write, DISPATCH_TIME_FOREVER);

    NSLog(@"Wrote to %@", outputUrl);
}

-----

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!