Skip to content

Commit

Permalink
Squashed commit of the following:
Browse files Browse the repository at this point in the history
commit d0c32125df2269621f0b6a85dabe36120a6d3f3b
Merge: fea9399 a6b600d
Author: Collider LI <lhc199652@gmail.com>
Date:   Thu Apr 28 02:12:43 2022 -0400

    Merge branch 'issue-1720' of https://github.com/low-batt/iina into low-batt-issue-1720

commit a6b600d
Author: low-batt <86170219+low-batt@users.noreply.github.com>
Date:   Sun Jul 25 23:14:05 2021 -0400

    Fix memory leaks in FFmpegController, #1720

    The method `getPeeksForFile` in `FFmpegController` is leaking memory
    when generating thumbnails. This commit will:

    - Add a `@try-@finally` block in the while loop to free the packet

    - Replace `av_free` by `av_frame_free`, when freeing an `AVFrame`

    - Add a call to `sws_freeContext` to free the `SwsContext`

    - Replace deprecated method `avcodec_close` with `avcodec_free_context`

    - Add `nullable` annotation to declaration of `probeVideoInfoForFile`

    This is a stopgap fix and does not address all of the potential leaks
    in the method. This commit focuses on the leaks that occur during the
    normal flow when generating thumbnails. Error flows will still leak
    memory. At some point this method should be refactored to always
    properly free memory.
  • Loading branch information
lhc70000 committed Apr 28, 2022
1 parent fea9399 commit 8682a54
Showing 1 changed file with 46 additions and 45 deletions.
91 changes: 46 additions & 45 deletions iina/FFmpegController.m
Original file line number Diff line number Diff line change
Expand Up @@ -210,59 +210,60 @@ - (int)getPeeksForFile:(NSString *)file

// Read and decode frame
while(av_read_frame(pFormatCtx, &packet) >= 0) {
@try {
// Make sure it's video stream
if (packet.stream_index == videoStream) {

// Make sure it's video stream
if (packet.stream_index == videoStream) {

// Decode video frame
if (avcodec_send_packet(pCodecCtx, &packet) < 0)
break;

ret = avcodec_receive_frame(pCodecCtx, pFrame);
if (ret < 0) { // something happened
if (ret == AVERROR(EAGAIN)) // input not ready, retry
continue;
else
// Decode video frame
if (avcodec_send_packet(pCodecCtx, &packet) < 0)
break;
}

// Check if duplicated
NSNumber *currentTimeStamp = @(pFrame->best_effort_timestamp);
if ([_addedTimestamps containsObject:currentTimeStamp]) {
double currentTime = CACurrentMediaTime();
if (currentTime - _timestamp > 1) {
if (self.delegate) {
[self.delegate didUpdateThumbnails:NULL forFile: file withProgress: i];
_timestamp = currentTime;
ret = avcodec_receive_frame(pCodecCtx, pFrame);
if (ret < 0) { // something happened
if (ret == AVERROR(EAGAIN)) // input not ready, retry
continue;
else
break;
}

// Check if duplicated
NSNumber *currentTimeStamp = @(pFrame->best_effort_timestamp);
if ([_addedTimestamps containsObject:currentTimeStamp]) {
double currentTime = CACurrentMediaTime();
if (currentTime - _timestamp > 1) {
if (self.delegate) {
[self.delegate didUpdateThumbnails:NULL forFile: file withProgress: i];
_timestamp = currentTime;
}
}
break;
} else {
[_addedTimestamps addObject:currentTimeStamp];
}

// Convert the frame to RGBA
ret = sws_scale(sws_ctx,
(const uint8_t* const *)pFrame->data,
pFrame->linesize,
0,
pCodecCtx->height,
pFrameRGB->data,
pFrameRGB->linesize);
CHECK_SUCCESS(ret, @"Cannot convert frame")

// Save the frame to disk
[self saveThumbnail:pFrameRGB
width:pFrameRGB->width
height:pFrameRGB->height
index:i
realTime:(pFrame->best_effort_timestamp * timebaseDouble)
forFile:file];
break;
} else {
[_addedTimestamps addObject:currentTimeStamp];
}

// Convert the frame to RGBA
ret = sws_scale(sws_ctx,
(const uint8_t* const *)pFrame->data,
pFrame->linesize,
0,
pCodecCtx->height,
pFrameRGB->data,
pFrameRGB->linesize);
CHECK_SUCCESS(ret, @"Cannot convert frame")

// Save the frame to disk
[self saveThumbnail:pFrameRGB
width:pFrameRGB->width
height:pFrameRGB->height
index:i
realTime:(pFrame->best_effort_timestamp * timebaseDouble)
forFile:file];
break;
} @finally {
// Free the packet
av_packet_unref(&packet);
}

// Free the packet
av_packet_unref(&packet);
}
}
// Free the scaler
Expand Down

0 comments on commit 8682a54

Please sign in to comment.