From 4abe4cdab012a6725b54475def016a3cfe95735f Mon Sep 17 00:00:00 2001 From: Jonathan Thomas Date: Tue, 11 Mar 2025 18:29:22 -0500 Subject: [PATCH] Add new side data rotation detection, used by modern cell phone video. Save "rotate" metadata as the inverse of the rotation (to correct it). --- src/FFmpegReader.cpp | 21 +++++++++++++++++++++ src/FFmpegUtilities.h | 1 + 2 files changed, 22 insertions(+) diff --git a/src/FFmpegReader.cpp b/src/FFmpegReader.cpp index 6c9b824f..6d8f9ccd 100644 --- a/src/FFmpegReader.cpp +++ b/src/FFmpegReader.cpp @@ -554,6 +554,27 @@ void FFmpegReader::Open() { info.metadata[str_key.toStdString()] = str_value.trimmed().toStdString(); } + // If "rotate" isn't already set, extract it from the video stream's side data. + if (info.metadata.find("rotate") == info.metadata.end()) { + for (unsigned int i = 0; i < pFormatCtx->nb_streams; i++) { + if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { + for (int j = 0; j < pFormatCtx->streams[i]->nb_side_data; j++) { + // Use the address-of operator to get a pointer to the j-th element. + AVPacketSideData *sd = &pFormatCtx->streams[i]->side_data[j]; + if (sd->type == AV_PKT_DATA_DISPLAYMATRIX && sd->size >= 9 * sizeof(int32_t)) { + double rotation = -av_display_rotation_get(reinterpret_cast(sd->data)); + if (isnan(rotation)) + rotation = 0; + QString str_value = QString::number(rotation, 'g', 6); + info.metadata["rotate"] = str_value.trimmed().toStdString(); + break; + } + } + break; // Only process the first video stream. + } + } + } + // Init previous audio location to zero previous_packet_location.frame = -1; previous_packet_location.sample_start = 0; diff --git a/src/FFmpegUtilities.h b/src/FFmpegUtilities.h index 39018a39..143b3427 100644 --- a/src/FFmpegUtilities.h +++ b/src/FFmpegUtilities.h @@ -39,6 +39,7 @@ extern "C" { #include #include + #include #if (LIBAVFORMAT_VERSION_MAJOR >= 57) #include //PM