[FFmpeg-devel] [PATCH v1 2/2] fftools/ffmpeg Add stream metadata from first frame's metadata

Jun Li junli1026 at gmail.com
Sun May 5 05:13:34 EEST 2019


Fix #6945
Exif extension has 'Orientaion' field for image flip and rotation.
This change is to add the first frame's exif into stream so that
autorotation would use the info to adjust the frames.
---
 fftools/ffmpeg.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 01f04103cf..1b59542e6c 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -2341,6 +2341,49 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output,
     return err < 0 ? err : ret;
 }
 
+static void set_metadata_from_1stframe(AVStream* stream, AVFrame* frame) 
+{
+    // read exif Orientation data
+    AVDictionaryEntry *entry = av_dict_get(frame->metadata, "Orientation", NULL, 0);
+    int orientation = 0;
+    uint8_t* sd = NULL;
+    if (entry) {
+        orientation = atoi(entry->value);
+        sd = av_stream_new_side_data(stream, AV_PKT_DATA_DISPLAYMATRIX, 
+                                                sizeof(int32_t) * 9);
+        switch (orientation)
+        {
+            case 2: // mirror horizontal
+                av_display_rotation_set((int32_t*)sd, 0.0);
+                av_display_matrix_flip(sd, 1, 0);
+                break;
+            case 3: // rotate 180
+                av_display_rotation_set((int32_t*)sd, 180.0);
+                break;
+            case 4: // mirror vertical
+                av_display_rotation_set((int32_t*)sd, 0.0);
+                av_display_matrix_flip(sd, 0, 1);
+                break;
+            case 5: // mirror horizontal and rotate 270 CW
+                av_display_rotation_set((int32_t*)sd, 270.0);
+                av_display_matrix_flip(sd, 0, 1);
+                break;
+            case 6: // rotate 90 CW
+                av_display_rotation_set((int32_t*)sd, 90.0);
+                break;
+            case 7: // mirror horizontal and rotate 90 CW
+                av_display_rotation_set((int32_t*)sd, 90.0);
+                av_display_matrix_flip(sd, 0, 1);
+                break;
+            case 8: // rotate 270 CW
+                av_display_rotation_set((int32_t*)sd, 270.0);
+                break;
+            default:
+                break;
+        }
+    }
+}
+
 static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int64_t *duration_pts, int eof,
                         int *decode_failed)
 {
@@ -2423,6 +2466,8 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, int64_
         decoded_frame->top_field_first = ist->top_field_first;
 
     ist->frames_decoded++;
+    if (ist->frames_decoded == 1)
+        set_metadata_from_1stframe(ist->st, decoded_frame);
 
     if (ist->hwaccel_retrieve_data && decoded_frame->format == ist->hwaccel_pix_fmt) {
         err = ist->hwaccel_retrieve_data(ist->dec_ctx, decoded_frame);
-- 
2.17.1



More information about the ffmpeg-devel mailing list