[FFmpeg-devel] [PATCH 02/20] avformat/matroskaenc: Improve writing Projection

Andreas Rheinhardt andreas.rheinhardt at gmail.com
Tue Jan 14 20:15:27 EET 2020


On Wed, Jan 1, 2020 at 1:59 AM Andreas Rheinhardt <
andreas.rheinhardt at gmail.com> wrote:

> The Matroska Projection master element has such a small maximum length
> that it can always be written with a length field of length one.
> So it is unnecessary to first write the element into a dynamic buffer to
> get the accurate length in order not to waste bytes on the length field.
>
> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at gmail.com>
> ---
>  libavformat/matroskaenc.c | 48 +++++++++++++++++----------------------
>  1 file changed, 21 insertions(+), 27 deletions(-)
>
> diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
> index 9cf840c9be..bbf9b55e78 100644
> --- a/libavformat/matroskaenc.c
> +++ b/libavformat/matroskaenc.c
> @@ -947,10 +947,8 @@ static int mkv_write_video_projection(AVFormatContext
> *s, AVIOContext *pb,
>                                        AVStream *st)
>  {
>      AVIOContext b;
> -    AVIOContext *dyn_cp;
> +    ebml_master projection;
>      int side_data_size = 0;
> -    int ret, projection_size;
> -    uint8_t *projection_ptr;
>      uint8_t private[20];
>
>      const AVSphericalMapping *spherical =
> @@ -960,62 +958,58 @@ static int
> mkv_write_video_projection(AVFormatContext *s, AVIOContext *pb,
>      if (!side_data_size)
>          return 0;
>
> -    ret = avio_open_dyn_buf(&dyn_cp);
> -    if (ret < 0)
> -        return ret;
> +    if (spherical->projection != AV_SPHERICAL_EQUIRECTANGULAR      &&
> +        spherical->projection != AV_SPHERICAL_EQUIRECTANGULAR_TILE &&
> +        spherical->projection != AV_SPHERICAL_CUBEMAP) {
> +        av_log(s, AV_LOG_WARNING, "Unknown projection type\n");
> +        return 0;
> +    }
> +
> +    // Maximally 4 8-byte elements with id-length 2 + 1 byte length field
> +    // and the private data of the AV_SPHERICAL_EQUIRECTANGULAR_TILE case
> +    projection = start_ebml_master(pb, MATROSKA_ID_VIDEOPROJECTION,
> +                                   4 * (2 + 1 + 8) + (2 + 1 + 20));
>
>      switch (spherical->projection) {
>      case AV_SPHERICAL_EQUIRECTANGULAR:
> -        put_ebml_uint(dyn_cp, MATROSKA_ID_VIDEOPROJECTIONTYPE,
> +        put_ebml_uint(pb, 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,
> +        put_ebml_uint(pb, 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,
> +        put_ebml_binary(pb, MATROSKA_ID_VIDEOPROJECTIONPRIVATE,
>                          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,
> +        put_ebml_uint(pb, 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,
> +        put_ebml_binary(pb, MATROSKA_ID_VIDEOPROJECTIONPRIVATE,
>                          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,
> +        put_ebml_float(pb, MATROSKA_ID_VIDEOPROJECTIONPOSEYAW,
>                         (double) spherical->yaw   / (1 << 16));
>      if (spherical->pitch)
> -        put_ebml_float(dyn_cp, MATROSKA_ID_VIDEOPROJECTIONPOSEPITCH,
> +        put_ebml_float(pb, MATROSKA_ID_VIDEOPROJECTIONPOSEPITCH,
>                         (double) spherical->pitch / (1 << 16));
>      if (spherical->roll)
> -        put_ebml_float(dyn_cp, MATROSKA_ID_VIDEOPROJECTIONPOSEROLL,
> +        put_ebml_float(pb, 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);
> +    end_ebml_master(pb, projection);
>
>      return 0;
>  }
> --
> 2.20.1
>
>
Ping.

- Andreas


More information about the ffmpeg-devel mailing list