Add new side data rotation detection, used by modern cell phone video. Save "rotate" metadata as the inverse of the rotation (to correct it).

This commit is contained in:
Jonathan Thomas
2025-03-11 18:29:22 -05:00
parent 37bdcacddf
commit 4abe4cdab0
2 changed files with 22 additions and 0 deletions

View File

@@ -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<int32_t *>(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;