Merge commit '827a05eaa9482e9ac2a17f7f2e42ead07c1d7574'
authorJames Almer <jamrial@gmail.com>
Sat, 21 Oct 2017 15:56:33 +0000 (12:56 -0300)
committerJames Almer <jamrial@gmail.com>
Sat, 21 Oct 2017 16:19:36 +0000 (13:19 -0300)
* commit '827a05eaa9482e9ac2a17f7f2e42ead07c1d7574':
  matroskaenc: add support for Spherical Video elements

See 58eb0f57f6702d57b6f97ec5010657bb2c076eff. Merged for cosmetics
purposes.
Also includes changes from d32d59bc977b43031007bb2ab21e232f96d2ebcb

Merged-by: James Almer <jamrial@gmail.com>
1  2 
libavformat/matroskaenc.c

@@@ -863,168 -648,81 +863,169 @@@ static int mkv_write_codecprivate(AVFor
      return ret;
  }
  
- static int mkv_write_video_projection(AVFormatContext *s, AVIOContext *pb, AVStream *st)
 +static int mkv_write_video_color(AVIOContext *pb, AVCodecParameters *par, AVStream *st) {
 +    AVIOContext *dyn_cp;
 +    uint8_t *colorinfo_ptr;
 +    int side_data_size = 0;
 +    int ret, colorinfo_size;
 +    const uint8_t *side_data;
 +
 +    ret = avio_open_dyn_buf(&dyn_cp);
 +    if (ret < 0)
 +        return ret;
 +
 +    if (par->color_trc != AVCOL_TRC_UNSPECIFIED &&
 +        par->color_trc < AVCOL_TRC_NB) {
 +        put_ebml_uint(dyn_cp, MATROSKA_ID_VIDEOCOLORTRANSFERCHARACTERISTICS,
 +                      par->color_trc);
 +    }
 +    if (par->color_space != AVCOL_SPC_UNSPECIFIED &&
 +        par->color_space < AVCOL_SPC_NB) {
 +        put_ebml_uint(dyn_cp, MATROSKA_ID_VIDEOCOLORMATRIXCOEFF, par->color_space);
 +    }
 +    if (par->color_primaries != AVCOL_PRI_UNSPECIFIED &&
 +        par->color_primaries < AVCOL_PRI_NB) {
 +        put_ebml_uint(dyn_cp, MATROSKA_ID_VIDEOCOLORPRIMARIES, par->color_primaries);
 +    }
 +    if (par->color_range != AVCOL_RANGE_UNSPECIFIED &&
 +        par->color_range < AVCOL_RANGE_NB) {
 +        put_ebml_uint(dyn_cp, MATROSKA_ID_VIDEOCOLORRANGE, par->color_range);
 +    }
 +    if (par->chroma_location != AVCHROMA_LOC_UNSPECIFIED &&
 +        par->chroma_location <= AVCHROMA_LOC_TOP) {
 +        int xpos, ypos;
 +
 +        avcodec_enum_to_chroma_pos(&xpos, &ypos, par->chroma_location);
 +        put_ebml_uint(dyn_cp, MATROSKA_ID_VIDEOCOLORCHROMASITINGHORZ, (xpos >> 7) + 1);
 +        put_ebml_uint(dyn_cp, MATROSKA_ID_VIDEOCOLORCHROMASITINGVERT, (ypos >> 7) + 1);
 +    }
 +
 +    side_data = av_stream_get_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
 +                                        &side_data_size);
 +    if (side_data_size) {
 +        const AVContentLightMetadata *metadata =
 +            (const AVContentLightMetadata*)side_data;
 +        put_ebml_uint(dyn_cp, MATROSKA_ID_VIDEOCOLORMAXCLL,  metadata->MaxCLL);
 +        put_ebml_uint(dyn_cp, MATROSKA_ID_VIDEOCOLORMAXFALL, metadata->MaxFALL);
 +    }
 +
 +    side_data = av_stream_get_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
 +                                        &side_data_size);
 +    if (side_data_size == sizeof(AVMasteringDisplayMetadata)) {
 +        ebml_master meta_element = start_ebml_master(
 +            dyn_cp, MATROSKA_ID_VIDEOCOLORMASTERINGMETA, 0);
 +        const AVMasteringDisplayMetadata *metadata =
 +            (const AVMasteringDisplayMetadata*)side_data;
 +        if (metadata->has_primaries) {
 +            put_ebml_float(dyn_cp, MATROSKA_ID_VIDEOCOLOR_RX,
 +                           av_q2d(metadata->display_primaries[0][0]));
 +            put_ebml_float(dyn_cp, MATROSKA_ID_VIDEOCOLOR_RY,
 +                           av_q2d(metadata->display_primaries[0][1]));
 +            put_ebml_float(dyn_cp, MATROSKA_ID_VIDEOCOLOR_GX,
 +                           av_q2d(metadata->display_primaries[1][0]));
 +            put_ebml_float(dyn_cp, MATROSKA_ID_VIDEOCOLOR_GY,
 +                           av_q2d(metadata->display_primaries[1][1]));
 +            put_ebml_float(dyn_cp, MATROSKA_ID_VIDEOCOLOR_BX,
 +                           av_q2d(metadata->display_primaries[2][0]));
 +            put_ebml_float(dyn_cp, MATROSKA_ID_VIDEOCOLOR_BY,
 +                           av_q2d(metadata->display_primaries[2][1]));
 +            put_ebml_float(dyn_cp, MATROSKA_ID_VIDEOCOLOR_WHITEX,
 +                           av_q2d(metadata->white_point[0]));
 +            put_ebml_float(dyn_cp, MATROSKA_ID_VIDEOCOLOR_WHITEY,
 +                           av_q2d(metadata->white_point[1]));
 +        }
 +        if (metadata->has_luminance) {
 +            put_ebml_float(dyn_cp, MATROSKA_ID_VIDEOCOLOR_LUMINANCEMAX,
 +                           av_q2d(metadata->max_luminance));
 +            put_ebml_float(dyn_cp, MATROSKA_ID_VIDEOCOLOR_LUMINANCEMIN,
 +                           av_q2d(metadata->min_luminance));
 +        }
 +        end_ebml_master(dyn_cp, meta_element);
 +    }
 +
 +    colorinfo_size = avio_close_dyn_buf(dyn_cp, &colorinfo_ptr);
 +    if (colorinfo_size) {
 +        ebml_master colorinfo = start_ebml_master(pb, MATROSKA_ID_VIDEOCOLOR, colorinfo_size);
 +        avio_write(pb, colorinfo_ptr, colorinfo_size);
 +        end_ebml_master(pb, colorinfo);
 +    }
 +    av_free(colorinfo_ptr);
 +    return 0;
 +}
 +
+ static int mkv_write_video_projection(AVFormatContext *s, AVIOContext *pb,
+                                       AVStream *st)
  {
+     AVIOContext b;
+     AVIOContext *dyn_cp;
      int side_data_size = 0;
+     int ret, projection_size;
+     uint8_t *projection_ptr;
+     uint8_t private[20];
      const AVSphericalMapping *spherical =
-         (const AVSphericalMapping*) av_stream_get_side_data(st, AV_PKT_DATA_SPHERICAL,
+         (const AVSphericalMapping *)av_stream_get_side_data(st, AV_PKT_DATA_SPHERICAL,
                                                              &side_data_size);
  
-     if (side_data_size) {
-         AVIOContext *dyn_cp;
-         uint8_t *projection_ptr;
-         int ret, projection_size;
-         ret = avio_open_dyn_buf(&dyn_cp);
-         if (ret < 0)
-             return ret;
-         switch (spherical->projection) {
-         case AV_SPHERICAL_EQUIRECTANGULAR:
-             put_ebml_uint(dyn_cp, MATROSKA_ID_VIDEOPROJECTIONTYPE,
-                           MATROSKA_VIDEO_PROJECTION_TYPE_EQUIRECTANGULAR);
-             break;
-         case AV_SPHERICAL_EQUIRECTANGULAR_TILE:
-         {
-             AVIOContext b;
-             uint8_t private[20];
-             ffio_init_context(&b, private, sizeof(private),
-                               1, NULL, NULL, NULL, NULL);
-             put_ebml_uint(dyn_cp, MATROSKA_ID_VIDEOPROJECTIONTYPE,
-                           MATROSKA_VIDEO_PROJECTION_TYPE_EQUIRECTANGULAR);
-             avio_wb32(&b, 0); // version + flags
-             avio_wb32(&b, spherical->bound_top);
-             avio_wb32(&b, spherical->bound_bottom);
-             avio_wb32(&b, spherical->bound_left);
-             avio_wb32(&b, spherical->bound_right);
-             put_ebml_binary(dyn_cp, MATROSKA_ID_VIDEOPROJECTIONPRIVATE, private, sizeof(private));
-             break;
-         }
-         case AV_SPHERICAL_CUBEMAP:
-         {
-             AVIOContext b;
-             uint8_t private[12];
-             ffio_init_context(&b, private, sizeof(private),
-                               1, NULL, NULL, NULL, NULL);
-             put_ebml_uint(dyn_cp, MATROSKA_ID_VIDEOPROJECTIONTYPE,
-                           MATROSKA_VIDEO_PROJECTION_TYPE_CUBEMAP);
-             avio_wb32(&b, 0); // version + flags
-             avio_wb32(&b, 0); // layout
-             avio_wb32(&b, spherical->padding);
-             put_ebml_binary(dyn_cp, MATROSKA_ID_VIDEOPROJECTIONPRIVATE, private, sizeof(private));
-             break;
-         }
-         default:
-             av_log(s, AV_LOG_WARNING, "Unknown projection type\n");
-             goto end;
-         }
 -    if (!side_data_size) {
 -        av_log(NULL, AV_LOG_WARNING, "Unknown spherical metadata\n");
++    if (!side_data_size)
+         return 0;
 -    }
+     ret = avio_open_dyn_buf(&dyn_cp);
+     if (ret < 0)
+         return ret;
  
-         if (spherical->yaw)
-             put_ebml_float(dyn_cp, MATROSKA_ID_VIDEOPROJECTIONPOSEYAW,   (double)spherical->yaw   / (1 << 16));
-         if (spherical->pitch)
-             put_ebml_float(dyn_cp, MATROSKA_ID_VIDEOPROJECTIONPOSEPITCH, (double)spherical->pitch / (1 << 16));
-         if (spherical->roll)
-             put_ebml_float(dyn_cp, MATROSKA_ID_VIDEOPROJECTIONPOSEROLL,  (double)spherical->roll  / (1 << 16));
+     switch (spherical->projection) {
+     case AV_SPHERICAL_EQUIRECTANGULAR:
+         put_ebml_uint(dyn_cp, MATROSKA_ID_VIDEOPROJECTIONTYPE,
+                       MATROSKA_VIDEO_PROJECTION_TYPE_EQUIRECTANGULAR);
+         break;
+     case AV_SPHERICAL_EQUIRECTANGULAR_TILE:
+         ffio_init_context(&b, private, 20, 1, NULL, NULL, NULL, NULL);
+         put_ebml_uint(dyn_cp, MATROSKA_ID_VIDEOPROJECTIONTYPE,
+                       MATROSKA_VIDEO_PROJECTION_TYPE_EQUIRECTANGULAR);
+         avio_wb32(&b, 0); // version + flags
+         avio_wb32(&b, spherical->bound_top);
+         avio_wb32(&b, spherical->bound_bottom);
+         avio_wb32(&b, spherical->bound_left);
+         avio_wb32(&b, spherical->bound_right);
+         put_ebml_binary(dyn_cp, MATROSKA_ID_VIDEOPROJECTIONPRIVATE,
 -                        private, sizeof(private));
++                        private, avio_tell(&b));
+         break;
+     case AV_SPHERICAL_CUBEMAP:
+         ffio_init_context(&b, private, 12, 1, NULL, NULL, NULL, NULL);
+         put_ebml_uint(dyn_cp, MATROSKA_ID_VIDEOPROJECTIONTYPE,
+                       MATROSKA_VIDEO_PROJECTION_TYPE_CUBEMAP);
+         avio_wb32(&b, 0); // version + flags
+         avio_wb32(&b, 0); // layout
+         avio_wb32(&b, spherical->padding);
+         put_ebml_binary(dyn_cp, MATROSKA_ID_VIDEOPROJECTIONPRIVATE,
 -                        private, sizeof(private));
++                        private, avio_tell(&b));
+         break;
+     default:
+         av_log(s, AV_LOG_WARNING, "Unknown projection type\n");
+         goto end;
+     }
+     if (spherical->yaw)
+         put_ebml_float(dyn_cp, MATROSKA_ID_VIDEOPROJECTIONPOSEYAW,
+                        (double) spherical->yaw   / (1 << 16));
+     if (spherical->pitch)
+         put_ebml_float(dyn_cp, MATROSKA_ID_VIDEOPROJECTIONPOSEPITCH,
+                        (double) spherical->pitch / (1 << 16));
+     if (spherical->roll)
+         put_ebml_float(dyn_cp, MATROSKA_ID_VIDEOPROJECTIONPOSEROLL,
+                        (double) spherical->roll  / (1 << 16));
  
  end:
-         projection_size = avio_close_dyn_buf(dyn_cp, &projection_ptr);
-         if (projection_size) {
-             ebml_master projection = start_ebml_master(pb, MATROSKA_ID_VIDEOPROJECTION, projection_size);
-             avio_write(pb, projection_ptr, projection_size);
-             end_ebml_master(pb, projection);
-         }
-         av_freep(&projection_ptr);
+     projection_size = avio_close_dyn_buf(dyn_cp, &projection_ptr);
+     if (projection_size) {
+         ebml_master projection = start_ebml_master(pb,
+                                                    MATROSKA_ID_VIDEOPROJECTION,
+                                                    projection_size);
+         avio_write(pb, projection_ptr, projection_size);
+         end_ebml_master(pb, projection);
      }
+     av_freep(&projection_ptr);
  
      return 0;
  }