On 08-05-2019 11:54 AM, Jun Li wrote:
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.

Suggest commit msg should be

"

'Orientation' field from EXIF tags in first decoded frame is extracted
 as stream side data so that ffmpeg can apply auto-rotation.

"


---
  fftools/ffmpeg.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++-
  1 file changed, 56 insertions(+), 1 deletion(-)

diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index 01f04103cf..98ccaf0732 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -2341,6 +2341,58 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, 
int *got_output,
      return err < 0 ? err : ret;
  }
+static int set_metadata_from_1stframe(InputStream* ist, AVFrame* frame)
+{
+    // read exif Orientation data
+    AVDictionaryEntry *entry = av_dict_get(frame->metadata, "Orientation", 
NULL, 0);
+    int orientation = 0;
+    int32_t* sd = NULL;
+    if (entry) {
+        orientation = atoi(entry->value);
+        sd = (int32_t*)av_stream_new_side_data(ist->st, 
AV_PKT_DATA_DISPLAYMATRIX, 4 * 9);
+        if (!sd)
+            return AVERROR(ENOMEM);
+        memset(sd, 0, 4 * 9);
+        switch (orientation)
+        {
+            case 1: // horizontal (normal)
+                av_display_rotation_set(sd, 0.0);
+                break;
+            case 2: // mirror horizontal
+                av_display_rotation_set(sd, 0.0);
+                av_display_matrix_flip(sd, 1, 0);
+                break;
+            case 3: // rotate 180
+                av_display_rotation_set(sd, 180.0);
+                break;
+            case 4: // mirror vertical
+                av_display_rotation_set(sd, 0.0);
+                av_display_matrix_flip(sd, 0, 1);
+                break;
+            case 5: // mirror horizontal and rotate 270 CW
+                av_display_rotation_set(sd, 270.0);
+                av_display_matrix_flip(sd, 0, 1);
+                break;
+            case 6: // rotate 90 CW
+                av_display_rotation_set(sd, 90.0);
+                break;
+            case 7: // mirror horizontal and rotate 90 CW
+                av_display_rotation_set(sd, 90.0);
+                av_display_matrix_flip(sd, 0, 1);
+                break;
+            case 8: // rotate 270 CW
+                av_display_rotation_set(sd, 270.0);
+                break;
+            default:
+                av_display_rotation_set(sd, 0.0);
+                av_log(ist->dec_ctx, AV_LOG_WARNING,
+                    "Exif orientation data out of range: %i. Set to default value: 
horizontal(normal).\n", orientation);
+                break;
+        }
+    }
+    return 0;
+}
+
  static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output, 
int64_t *duration_pts, int eof,
                          int *decode_failed)
  {
@@ -2423,7 +2475,10 @@ 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 &&
+        ((err = set_metadata_from_1stframe(ist, decoded_frame)) < 0))
+        goto fail;
+
      if (ist->hwaccel_retrieve_data && decoded_frame->format == 
ist->hwaccel_pix_fmt) {
          err = ist->hwaccel_retrieve_data(ist->dec_ctx, decoded_frame);
          if (err < 0)

Also, is there a chance that there may be multiple sources for orientation data available for a given stream? If yes, what's the interaction? It looks like you append a new SD element.

Gyan
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to