Commit 9261d4923f for ffmpeg
commit 9261d4923fcf8cee6d88670570f12b65d6b32a3a
Author: Niklas Haas <git@haasn.dev>
Date: Tue Sep 29 20:20:24 2026 +0200
avformat/libcurl: return CURLcode alongside AVERROR
Useful for the next commit. A slight complication arises from the
libcurl-internal distinction between CURLcode and CURLMcode, even though
the overlap between the two is quite big. Make an effort to map between
the two for a few relevant cases; excluding stuff we probably won't see
outside a debugging session.
Introduce a new helper to ensure these are always updated in lockstep.
Sponsored-by: nxtedition AB
Signed-off-by: Niklas Haas <git@haasn.dev>
diff --git a/libavformat/libcurl.c b/libavformat/libcurl.c
index 57e413df05..ffe9205c51 100644
--- a/libavformat/libcurl.c
+++ b/libavformat/libcurl.c
@@ -173,8 +173,9 @@ struct CurlContext {
pthread_cond_t cond;
AVFifo *fifo;
int paused; /* write callback paused, FIFO was full */
- int status; /* current stream status (AVERROR code) */
int aborted; /* transfer should stop (open was interrupted) */
+ int status; /* current stream status (AVERROR code) */
+ CURLcode curl_status; /* corresponding libcurl status code */
int64_t icy_metaint; /* in-band metadata interval, 0 if none */
};
@@ -200,6 +201,18 @@ static int curlcode_to_averror(CURLcode code)
}
}
+static int curlmcode_to_curlcode(CURLMcode code)
+{
+ switch (code) {
+ case CURLM_OK: return CURLE_OK;
+ case CURLM_UNKNOWN_OPTION: return CURLE_UNKNOWN_OPTION;
+ case CURLM_OUT_OF_MEMORY: return CURLE_OUT_OF_MEMORY;
+ case CURLM_ABORTED_BY_CALLBACK: return CURLE_ABORTED_BY_CALLBACK;
+ case CURLM_UNRECOVERABLE_POLL: return CURLE_UNRECOVERABLE_POLL;
+ default: return CURLE_FAILED_INIT;
+ }
+}
+
static int is_recoverable(CURLcode code)
{
switch (code) {
@@ -222,6 +235,15 @@ static int is_recoverable(CURLcode code)
/* curl callbacks (run on the loop thread) */
/* ------------------------------------------------------------------------- */
+static void update_status_locked(CurlContext *c, int status, CURLcode code)
+{
+ if (c->status)
+ return;
+
+ c->status = status;
+ c->curl_status = code;
+}
+
static size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
{
CurlContext *c = userdata;
@@ -505,8 +527,7 @@ static size_t header_callback(char *ptr, size_t size, size_t nitems, void *userd
if (!verify_content_range(c, content_start, content_end, content_total)) {
c->loop->num_errors++;
c->stream_ok = 0;
- if (!c->status)
- c->status = AVERROR(EIO);
+ update_status_locked(c, AVERROR(EIO), CURLE_OK);
pthread_cond_broadcast(&c->cond);
pthread_mutex_unlock(&c->mutex);
return len;
@@ -570,8 +591,7 @@ static size_t header_callback(char *ptr, size_t size, size_t nitems, void *userd
} else {
c->loop->num_errors++;
c->stream_ok = 0;
- if (!c->status)
- c->status = ff_http_averror(status, AVERROR(EIO));
+ update_status_locked(c, ff_http_averror(status, AVERROR(EIO)), CURLE_OK);
}
c->probed = 1;
pthread_cond_broadcast(&c->cond);
@@ -627,8 +647,7 @@ static void start_request(CurlContext *c)
curl_multi_strerror(res));
c->active = 0;
pthread_mutex_lock(&c->mutex);
- if (!c->status)
- c->status = AVERROR(EIO);
+ update_status_locked(c, AVERROR(EIO), curlmcode_to_curlcode(res));
pthread_cond_broadcast(&c->cond);
pthread_mutex_unlock(&c->mutex);
}
@@ -669,10 +688,9 @@ static void on_done(CurlContext *c, CURLcode code)
received = c->request_received;
/* Advance past delivered bytes so a retry or seek resumes at the right offset. */
if (received > INT64_MAX - c->request_start) {
- if (!c->status)
- c->status = AVERROR(EIO);
received = 0;
aborted = 1;
+ update_status_locked(c, AVERROR(EIO), code);
pthread_cond_broadcast(&c->cond);
}
c->request_start += received;
@@ -685,9 +703,8 @@ static void on_done(CurlContext *c, CURLcode code)
pthread_mutex_lock(&c->mutex);
c->probed = 1;
c->stream_ok = 0;
- if (!c->status)
- c->status = curlcode_to_averror(code);
c->loop->num_errors++;
+ update_status_locked(c, curlcode_to_averror(code), code);
pthread_cond_broadcast(&c->cond);
pthread_mutex_unlock(&c->mutex);
return;
@@ -715,6 +732,7 @@ static void on_done(CurlContext *c, CURLcode code)
}
pthread_mutex_lock(&c->mutex);
c->status = AVERROR_EOF;
+ c->curl_status = CURLE_OK;
pthread_cond_broadcast(&c->cond);
pthread_mutex_unlock(&c->mutex);
return;
@@ -737,8 +755,7 @@ static void on_done(CurlContext *c, CURLcode code)
/* Unhandled generic curl error */
pthread_mutex_lock(&c->mutex);
- if (!c->status)
- c->status = curlcode_to_averror(code);
+ update_status_locked(c, curlcode_to_averror(code), code);
pthread_cond_broadcast(&c->cond);
pthread_mutex_unlock(&c->mutex);
}
@@ -793,6 +810,7 @@ static void execute_command(CurlLoop *loop, CurlCmd *cmd)
const int was_paused = c->paused;
c->paused = 0;
c->status = 0;
+ c->curl_status = 0;
pthread_mutex_unlock(&c->mutex);
c->request_start = cmd->pos;
c->request_received = 0;