1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-23 12:43:46 +02:00

spherical: Add tiled equirectangular type and projection-specific properties

Signed-off-by: Vittorio Giovara <vittorio.giovara@gmail.com>
This commit is contained in:
Vittorio Giovara 2017-02-10 15:26:55 -05:00
parent 776f289c0f
commit 1b7ffddb3a
8 changed files with 129 additions and 10 deletions

View File

@ -15,6 +15,11 @@ libavutil: 2015-08-28
API changes, most recent first:
2017-02-10 - xxxxxxx - lavu 55.48.100 / 55.33.0 - spherical.h
Add AV_SPHERICAL_EQUIRECTANGULAR_TILE, av_spherical_tile_bounds(),
and projection-specific properties (bound_left, bound_top, bound_right,
bound_bottom, padding) to AVSphericalMapping.
2017-03-02 - xxxxxxx - lavc 57.81.104 - videotoolbox.h
AVVideotoolboxContext.cv_pix_fmt_type can now be set to 0 to output the
native decoder format. (The default value is not changed.)

View File

@ -1762,6 +1762,7 @@ static inline int show_tags(WriterContext *w, AVDictionary *tags, int section_id
}
static void print_pkt_side_data(WriterContext *w,
AVCodecParameters *par,
const AVPacketSideData *side_data,
int nb_side_data,
SectionID id_data_list,
@ -1788,9 +1789,19 @@ static void print_pkt_side_data(WriterContext *w,
const AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data;
if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR)
print_str("projection", "equirectangular");
else if (spherical->projection == AV_SPHERICAL_CUBEMAP)
else if (spherical->projection == AV_SPHERICAL_CUBEMAP) {
print_str("projection", "cubemap");
else
print_int("padding", spherical->padding);
} else if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR_TILE) {
size_t l, t, r, b;
av_spherical_tile_bounds(spherical, par->width, par->height,
&l, &t, &r, &b);
print_str("projection", "tiled equirectangular");
print_int("bound_left", l);
print_int("bound_top", t);
print_int("bound_right", r);
print_int("bound_bottom", b);
} else
print_str("projection", "unknown");
print_int("yaw", (double) spherical->yaw / (1 << 16));
@ -1843,7 +1854,7 @@ static void show_packet(WriterContext *w, InputFile *ifile, AVPacket *pkt, int p
av_dict_free(&dict);
}
print_pkt_side_data(w, pkt->side_data, pkt->side_data_elems,
print_pkt_side_data(w, st->codecpar, pkt->side_data, pkt->side_data_elems,
SECTION_ID_PACKET_SIDE_DATA_LIST,
SECTION_ID_PACKET_SIDE_DATA);
}
@ -2404,7 +2415,7 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id
ret = show_tags(w, stream->metadata, in_program ? SECTION_ID_PROGRAM_STREAM_TAGS : SECTION_ID_STREAM_TAGS);
if (stream->nb_side_data) {
print_pkt_side_data(w, stream->side_data, stream->nb_side_data,
print_pkt_side_data(w, stream->codecpar, stream->side_data, stream->nb_side_data,
SECTION_ID_STREAM_SIDE_DATA_LIST,
SECTION_ID_STREAM_SIDE_DATA);
}

View File

@ -343,7 +343,7 @@ static void dump_mastering_display_metadata(void *ctx, AVPacketSideData* sd) {
av_q2d(metadata->min_luminance), av_q2d(metadata->max_luminance));
}
static void dump_spherical(void *ctx, AVPacketSideData *sd)
static void dump_spherical(void *ctx, AVCodecParameters *par, AVPacketSideData *sd)
{
AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data;
double yaw, pitch, roll;
@ -357,6 +357,8 @@ static void dump_spherical(void *ctx, AVPacketSideData *sd)
av_log(ctx, AV_LOG_INFO, "equirectangular ");
else if (spherical->projection == AV_SPHERICAL_CUBEMAP)
av_log(ctx, AV_LOG_INFO, "cubemap ");
else if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR_TILE)
av_log(ctx, AV_LOG_INFO, "tiled equirectangular ");
else {
av_log(ctx, AV_LOG_WARNING, "unknown");
return;
@ -366,6 +368,15 @@ static void dump_spherical(void *ctx, AVPacketSideData *sd)
pitch = ((double)spherical->pitch) / (1 << 16);
roll = ((double)spherical->roll) / (1 << 16);
av_log(ctx, AV_LOG_INFO, "(%f/%f/%f) ", yaw, pitch, roll);
if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR_TILE) {
size_t l, t, r, b;
av_spherical_tile_bounds(spherical, par->width, par->height,
&l, &t, &r, &b);
av_log(ctx, AV_LOG_INFO, "[%zu, %zu, %zu, %zu] ", l, t, r, b);
} else if (spherical->projection == AV_SPHERICAL_CUBEMAP) {
av_log(ctx, AV_LOG_INFO, "[pad %zu] ", spherical->padding);
}
}
static void dump_sidedata(void *ctx, AVStream *st, const char *indent)
@ -421,7 +432,7 @@ static void dump_sidedata(void *ctx, AVStream *st, const char *indent)
break;
case AV_PKT_DATA_SPHERICAL:
av_log(ctx, AV_LOG_INFO, "spherical: ");
dump_spherical(ctx, &sd);
dump_spherical(ctx, st->codecpar, &sd);
break;
default:
av_log(ctx, AV_LOG_INFO,

View File

@ -32,3 +32,21 @@ AVSphericalMapping *av_spherical_alloc(size_t *size)
return spherical;
}
void av_spherical_tile_bounds(AVSphericalMapping *map,
size_t width, size_t height,
size_t *left, size_t *top,
size_t *right, size_t *bottom)
{
/* conversion from 0.32 coordinates to pixels */
uint64_t orig_width = (uint64_t) width * UINT32_MAX /
(UINT32_MAX - map->bound_right - map->bound_left);
uint64_t orig_height = (uint64_t) height * UINT32_MAX /
(UINT32_MAX - map->bound_bottom - map->bound_top);
/* add a (UINT32_MAX - 1) to round up integer division */
*left = (orig_width * map->bound_left + UINT32_MAX - 1) / UINT32_MAX;
*top = (orig_height * map->bound_top + UINT32_MAX - 1) / UINT32_MAX;
*right = orig_width - width - *left;
*bottom = orig_height - height - *top;
}

View File

@ -63,6 +63,13 @@ enum AVSphericalProjection {
* to the back.
*/
AV_SPHERICAL_CUBEMAP,
/**
* Video represents a portion of a sphere mapped on a flat surface
* using equirectangular projection. The @ref bounding fields indicate
* the position of the current video in a larger surface.
*/
AV_SPHERICAL_EQUIRECTANGULAR_TILE,
};
/**
@ -122,6 +129,57 @@ typedef struct AVSphericalMapping {
/**
* @}
*/
/**
* @name Bounding rectangle
* @anchor bounding
* @{
* These fields indicate the location of the current tile, and where
* it should be mapped relative to the original surface. They are
* exported as 0.32 fixed point, and can be converted to classic
* pixel values with av_spherical_bounds().
*
* @code{.unparsed}
* +----------------+----------+
* | |bound_top |
* | +--------+ |
* | bound_left |tile | |
* +<---------->| |<--->+bound_right
* | +--------+ |
* | | |
* | bound_bottom| |
* +----------------+----------+
* @endcode
*
* If needed, the original video surface dimensions can be derived
* by adding the current stream or frame size to the related bounds,
* like in the following example:
*
* @code{c}
* original_width = tile->width + bound_left + bound_right;
* original_height = tile->height + bound_top + bound_bottom;
* @endcode
*
* @note These values are valid only for the tiled equirectangular
* projection type (@ref AV_SPHERICAL_EQUIRECTANGULAR_TILE),
* and should be ignored in all other cases.
*/
size_t bound_left; ///< Distance from the left edge
size_t bound_top; ///< Distance from the top edge
size_t bound_right; ///< Distance from the right edge
size_t bound_bottom; ///< Distance from the bottom edge
/**
* @}
*/
/**
* Number of pixels to pad from the edge of each cube face.
*
* @note This value is valid for only for the cubemap projection type
* (@ref AV_SPHERICAL_CUBEMAP), and should be ignored in all other
* cases.
*/
size_t padding;
} AVSphericalMapping;
/**
@ -132,6 +190,22 @@ typedef struct AVSphericalMapping {
*/
AVSphericalMapping *av_spherical_alloc(size_t *size);
/**
* Convert the @ref bounding fields from an AVSphericalVideo
* from 0.32 fixed point to pixels.
*
* @param map The AVSphericalVideo map to read bound values from.
* @param width Width of the current frame or stream.
* @param height Height of the current frame or stream.
* @param left Pixels from the left edge.
* @param top Pixels from the top edge.
* @param right Pixels from the right edge.
* @param bottom Pixels from the bottom edge.
*/
void av_spherical_tile_bounds(AVSphericalMapping *map,
size_t width, size_t height,
size_t *left, size_t *top,
size_t *right, size_t *bottom);
/**
* @}
* @}

View File

@ -79,8 +79,8 @@
*/
#define LIBAVUTIL_VERSION_MAJOR 55
#define LIBAVUTIL_VERSION_MINOR 47
#define LIBAVUTIL_VERSION_MICRO 101
#define LIBAVUTIL_VERSION_MINOR 48
#define LIBAVUTIL_VERSION_MICRO 100
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
LIBAVUTIL_VERSION_MINOR, \

View File

@ -7,7 +7,7 @@ inverted=0
[/SIDE_DATA]
[SIDE_DATA]
side_data_type=Spherical Mapping
side_data_size=16
side_data_size=56
projection=equirectangular
yaw=45
pitch=30

View File

@ -7,7 +7,7 @@ inverted=0
[/SIDE_DATA]
[SIDE_DATA]
side_data_type=Spherical Mapping
side_data_size=16
side_data_size=56
projection=equirectangular
yaw=45
pitch=30