Commit 1b7ffddb authored by Vittorio Giovara's avatar Vittorio Giovara

spherical: Add tiled equirectangular type and projection-specific properties

Signed-off-by: 's avatarVittorio Giovara <vittorio.giovara@gmail.com>
parent 776f289c
...@@ -15,6 +15,11 @@ libavutil: 2015-08-28 ...@@ -15,6 +15,11 @@ libavutil: 2015-08-28
API changes, most recent first: 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 2017-03-02 - xxxxxxx - lavc 57.81.104 - videotoolbox.h
AVVideotoolboxContext.cv_pix_fmt_type can now be set to 0 to output the AVVideotoolboxContext.cv_pix_fmt_type can now be set to 0 to output the
native decoder format. (The default value is not changed.) native decoder format. (The default value is not changed.)
......
...@@ -1762,6 +1762,7 @@ static inline int show_tags(WriterContext *w, AVDictionary *tags, int section_id ...@@ -1762,6 +1762,7 @@ static inline int show_tags(WriterContext *w, AVDictionary *tags, int section_id
} }
static void print_pkt_side_data(WriterContext *w, static void print_pkt_side_data(WriterContext *w,
AVCodecParameters *par,
const AVPacketSideData *side_data, const AVPacketSideData *side_data,
int nb_side_data, int nb_side_data,
SectionID id_data_list, SectionID id_data_list,
...@@ -1788,9 +1789,19 @@ static void print_pkt_side_data(WriterContext *w, ...@@ -1788,9 +1789,19 @@ static void print_pkt_side_data(WriterContext *w,
const AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data; const AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data;
if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR) if (spherical->projection == AV_SPHERICAL_EQUIRECTANGULAR)
print_str("projection", "equirectangular"); print_str("projection", "equirectangular");
else if (spherical->projection == AV_SPHERICAL_CUBEMAP) else if (spherical->projection == AV_SPHERICAL_CUBEMAP) {
print_str("projection", "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_str("projection", "unknown");
print_int("yaw", (double) spherical->yaw / (1 << 16)); print_int("yaw", (double) spherical->yaw / (1 << 16));
...@@ -1843,7 +1854,7 @@ static void show_packet(WriterContext *w, InputFile *ifile, AVPacket *pkt, int p ...@@ -1843,7 +1854,7 @@ static void show_packet(WriterContext *w, InputFile *ifile, AVPacket *pkt, int p
av_dict_free(&dict); 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_LIST,
SECTION_ID_PACKET_SIDE_DATA); SECTION_ID_PACKET_SIDE_DATA);
} }
...@@ -2404,7 +2415,7 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id ...@@ -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); ret = show_tags(w, stream->metadata, in_program ? SECTION_ID_PROGRAM_STREAM_TAGS : SECTION_ID_STREAM_TAGS);
if (stream->nb_side_data) { 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_LIST,
SECTION_ID_STREAM_SIDE_DATA); SECTION_ID_STREAM_SIDE_DATA);
} }
......
...@@ -343,7 +343,7 @@ static void dump_mastering_display_metadata(void *ctx, AVPacketSideData* sd) { ...@@ -343,7 +343,7 @@ static void dump_mastering_display_metadata(void *ctx, AVPacketSideData* sd) {
av_q2d(metadata->min_luminance), av_q2d(metadata->max_luminance)); 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; AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data;
double yaw, pitch, roll; double yaw, pitch, roll;
...@@ -357,6 +357,8 @@ static void dump_spherical(void *ctx, AVPacketSideData *sd) ...@@ -357,6 +357,8 @@ static void dump_spherical(void *ctx, AVPacketSideData *sd)
av_log(ctx, AV_LOG_INFO, "equirectangular "); av_log(ctx, AV_LOG_INFO, "equirectangular ");
else if (spherical->projection == AV_SPHERICAL_CUBEMAP) else if (spherical->projection == AV_SPHERICAL_CUBEMAP)
av_log(ctx, AV_LOG_INFO, "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 { else {
av_log(ctx, AV_LOG_WARNING, "unknown"); av_log(ctx, AV_LOG_WARNING, "unknown");
return; return;
...@@ -366,6 +368,15 @@ static void dump_spherical(void *ctx, AVPacketSideData *sd) ...@@ -366,6 +368,15 @@ static void dump_spherical(void *ctx, AVPacketSideData *sd)
pitch = ((double)spherical->pitch) / (1 << 16); pitch = ((double)spherical->pitch) / (1 << 16);
roll = ((double)spherical->roll) / (1 << 16); roll = ((double)spherical->roll) / (1 << 16);
av_log(ctx, AV_LOG_INFO, "(%f/%f/%f) ", yaw, pitch, roll); 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) 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) ...@@ -421,7 +432,7 @@ static void dump_sidedata(void *ctx, AVStream *st, const char *indent)
break; break;
case AV_PKT_DATA_SPHERICAL: case AV_PKT_DATA_SPHERICAL:
av_log(ctx, AV_LOG_INFO, "spherical: "); av_log(ctx, AV_LOG_INFO, "spherical: ");
dump_spherical(ctx, &sd); dump_spherical(ctx, st->codecpar, &sd);
break; break;
default: default:
av_log(ctx, AV_LOG_INFO, av_log(ctx, AV_LOG_INFO,
......
...@@ -32,3 +32,21 @@ AVSphericalMapping *av_spherical_alloc(size_t *size) ...@@ -32,3 +32,21 @@ AVSphericalMapping *av_spherical_alloc(size_t *size)
return spherical; 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;
}
...@@ -63,6 +63,13 @@ enum AVSphericalProjection { ...@@ -63,6 +63,13 @@ enum AVSphericalProjection {
* to the back. * to the back.
*/ */
AV_SPHERICAL_CUBEMAP, 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 { ...@@ -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; } AVSphericalMapping;
/** /**
...@@ -132,6 +190,22 @@ typedef struct AVSphericalMapping { ...@@ -132,6 +190,22 @@ typedef struct AVSphericalMapping {
*/ */
AVSphericalMapping *av_spherical_alloc(size_t *size); 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);
/** /**
* @} * @}
* @} * @}
......
...@@ -79,8 +79,8 @@ ...@@ -79,8 +79,8 @@
*/ */
#define LIBAVUTIL_VERSION_MAJOR 55 #define LIBAVUTIL_VERSION_MAJOR 55
#define LIBAVUTIL_VERSION_MINOR 47 #define LIBAVUTIL_VERSION_MINOR 48
#define LIBAVUTIL_VERSION_MICRO 101 #define LIBAVUTIL_VERSION_MICRO 100
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
LIBAVUTIL_VERSION_MINOR, \ LIBAVUTIL_VERSION_MINOR, \
......
...@@ -7,7 +7,7 @@ inverted=0 ...@@ -7,7 +7,7 @@ inverted=0
[/SIDE_DATA] [/SIDE_DATA]
[SIDE_DATA] [SIDE_DATA]
side_data_type=Spherical Mapping side_data_type=Spherical Mapping
side_data_size=16 side_data_size=56
projection=equirectangular projection=equirectangular
yaw=45 yaw=45
pitch=30 pitch=30
......
...@@ -7,7 +7,7 @@ inverted=0 ...@@ -7,7 +7,7 @@ inverted=0
[/SIDE_DATA] [/SIDE_DATA]
[SIDE_DATA] [SIDE_DATA]
side_data_type=Spherical Mapping side_data_type=Spherical Mapping
side_data_size=16 side_data_size=56
projection=equirectangular projection=equirectangular
yaw=45 yaw=45
pitch=30 pitch=30
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment