[FFmpeg-devel] [PATCH] mjpegdec: parse JPS extension and save relevant stereo3d information
Stefano Sabatini
stefasab at gmail.com
Sun Feb 9 11:59:09 CET 2014
On date Friday 2014-01-31 13:13:57 +0400, Kirill Gavrilov encoded:
> On Thu, Jan 30, 2014 at 3:53 AM, Michael Niedermayer <michaelni at gmx.at>wrote:
>
> > btw it seems ffprobe doesnt support showing avframe side data
> > heres a quick proof of concept patch, that prints something
> > maybe you (or someone else) wants t improve it ?
> >
> I have prepared 2 alternative patches for ffprobe - one prints information
> as integers and another as text (probably requires libavutil minor version
> bump).
>
> But there are several issues with current stereo3d implementation.
> FFmpeg have two alternative implementations which are not yet synchronized:
> 1) First is based on metadata keys parsing (implemented for MKV container
> which has dedicated fields and per-frame metadata in h264_sei) and
> documented (stereo_mode in http://www.ffmpeg.org/ffmpeg-formats.html).
> 2) Second is based on new frame side_data extension, taken from LibAV
> (implemented for various other decoders).
>
> Another issue is that per-frame stereo3d information is unavailable within
> av_dump_format(), but in most cases stereo format should be consistent
> across single stream in file (excluding potential live-streaming use cases).
> -----------------------------------------------
> Kirill Gavrilov,
> <kirill at sview.ru>
> From d8b3fa42c51d9cebccc7d5c45a5189670ff63d5b Mon Sep 17 00:00:00 2001
> From: Kirill Gavrilov <kirill at sview.ru>
> Date: Fri, 31 Jan 2014 12:54:45 +0400
> Subject: [PATCH] ffprobe: print frame side_data info
>
> ---
> ffprobe.c | 17 +++++++++++++++++
> libavutil/stereo3d.c | 28 ++++++++++++++++++++++++++++
> libavutil/stereo3d.h | 15 +++++++++++++++
> 3 files changed, 60 insertions(+)
>
> diff --git a/ffprobe.c b/ffprobe.c
> index ef3bcc6..680d76b 100644
> --- a/ffprobe.c
> +++ b/ffprobe.c
> @@ -38,6 +38,7 @@
> #include "libavutil/dict.h"
> #include "libavutil/libm.h"
> #include "libavutil/parseutils.h"
> +#include "libavutil/stereo3d.h"
> #include "libavutil/timecode.h"
> #include "libavutil/timestamp.h"
> #include "libavdevice/avdevice.h"
> @@ -1712,6 +1713,7 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream,
> {
> AVBPrint pbuf;
> const char *s;
> + int i;
>
> av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED);
>
> @@ -1755,6 +1757,21 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream,
> print_int("interlaced_frame", frame->interlaced_frame);
> print_int("top_field_first", frame->top_field_first);
> print_int("repeat_pict", frame->repeat_pict);
> + for (i = 0; i < frame->nb_side_data; i++) {
> + AVStereo3D *st3d;
> + AVFrameSideData *sd = frame->side_data[i];
> + print_int("side_data_type", sd->type);
here type could be a string for better readibility
> + print_int("side_data_size", sd->size);
> + switch (sd->type) {
> + case AV_FRAME_DATA_STEREO3D:
> + st3d = (AVStereo3D *)sd->data;
> + s = av_get_stereo3d_type_name(st3d->type);
> + if (s) print_str ("side_data_st3d_type", s);
> + else print_str_opt("side_data_st3d_type", "unknown");
> + print_int("side_data_st3d_invert", !!(st3d->flags & AV_STEREO3D_FLAG_INVERT));
> + break;
> + }
I wonder if we should have a general function to convert side data to
a dictionary, this is probably overkill.
> + }
> break;
>
> case AVMEDIA_TYPE_AUDIO:
> diff --git a/libavutil/stereo3d.c b/libavutil/stereo3d.c
> index a44af21..809678d 100644
> --- a/libavutil/stereo3d.c
> +++ b/libavutil/stereo3d.c
> @@ -38,3 +38,31 @@ AVStereo3D *av_stereo3d_create_side_data(AVFrame *frame)
>
> return (AVStereo3D *)side_data->data;
> }
> +
> +/** this table contains types names */
> +static const char *stereo3d_types[AV_STEREO3D_NB] = {
Nit: stereo3d_type_names
> + [AV_STEREO3D_2D] = "mono",
why 2D => mono?
> + [AV_STEREO3D_SIDEBYSIDE] = "sidebyside",
> + [AV_STEREO3D_TOPBOTTOM] = "topbottom",
> + [AV_STEREO3D_FRAMESEQUENCE] = "framesequence",
> + [AV_STEREO3D_CHECKERBOARD] = "checkboard",
again, please let's keep macro and name string in sync for consistency
> + [AV_STEREO3D_SIDEBYSIDE_QUINCUNX] = "sidebyside_quincunx",
> + [AV_STEREO3D_LINES] = "lines",
> + [AV_STEREO3D_COLUMNS] = "columns",
> +};
> +
> +const char *av_get_stereo3d_type_name(enum AVStereo3DType type)
> +{
> + if (type < 0 || type >= AV_STEREO3D_NB)
> + return NULL;
> + return stereo3d_types[type];
> +}
> +
> +enum AVStereo3DType av_get_stereo3d_type(const char *name)
> +{
> + int i;
> + for (i = 0; i < AV_STEREO3D_NB; i++)
> + if (!strcmp(stereo3d_types[i], name))
> + return i;
> + return AV_STEREO3D_2D;
> +}
> diff --git a/libavutil/stereo3d.h b/libavutil/stereo3d.h
> index 8829da9..e1baa93 100644
> --- a/libavutil/stereo3d.h
> +++ b/libavutil/stereo3d.h
> @@ -102,6 +102,11 @@ enum AVStereo3DType {
> * ...
> */
> AV_STEREO3D_COLUMNS,
> +
> + /**
> + * Number of types. DO NOT USE if linking dynamically.
> + */
> + AV_STEREO3D_NB
> };
>
>
> @@ -145,3 +150,13 @@ AVStereo3D *av_stereo3d_alloc(void);
> * @return The AVStereo3D structure to be filled by caller.
> */
> AVStereo3D *av_stereo3d_create_side_data(AVFrame *frame);
> +
> +/**
> + * Return the name of type, or NULL if type is not recognized.
> + */
> +const char *av_get_stereo3d_type_name(enum AVStereo3DType type);
> +
> +/**
> + * Return a stereo3d type corresponding to name, or AV_STEREO3D_2D on error.
> + */
> +enum AVStereo3DType av_get_stereo3d_type(const char *name);
> --
> 1.8.3.2
>
> From 2b00014410d176e5ec461dda593da8220945e1f4 Mon Sep 17 00:00:00 2001
> From: Kirill Gavrilov <kirill at sview.ru>
> Date: Fri, 31 Jan 2014 11:44:36 +0400
> Subject: [PATCH] ffprobe: print frame side_data info
>
> ---
> ffprobe.c | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
> diff --git a/ffprobe.c b/ffprobe.c
> index ef3bcc6..e7d1959 100644
> --- a/ffprobe.c
> +++ b/ffprobe.c
> @@ -38,6 +38,7 @@
> #include "libavutil/dict.h"
> #include "libavutil/libm.h"
> #include "libavutil/parseutils.h"
> +#include "libavutil/stereo3d.h"
> #include "libavutil/timecode.h"
> #include "libavutil/timestamp.h"
> #include "libavdevice/avdevice.h"
> @@ -1712,6 +1713,7 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream,
> {
> AVBPrint pbuf;
> const char *s;
> + int i;
>
> av_bprint_init(&pbuf, 1, AV_BPRINT_SIZE_UNLIMITED);
>
> @@ -1755,6 +1757,19 @@ static void show_frame(WriterContext *w, AVFrame *frame, AVStream *stream,
> print_int("interlaced_frame", frame->interlaced_frame);
> print_int("top_field_first", frame->top_field_first);
> print_int("repeat_pict", frame->repeat_pict);
> + for (i = 0; i < frame->nb_side_data; i++) {
> + AVStereo3D *st3d;
> + AVFrameSideData *sd = frame->side_data[i];
> + print_int("side_data_type", sd->type);
> + print_int("side_data_size", sd->size);
> + switch (sd->type) {
> + case AV_FRAME_DATA_STEREO3D:
> + st3d = (AVStereo3D *)sd->data;
> + print_int("side_data_st3d_type", st3d->type);
> + print_int("side_data_st3d_flags", st3d->flags);
> + break;
> + }
> + }
I tend to prefer the latter approach since it generates more
informative output.
--
FFmpeg = Furious and Fundamentalist MultiPurpose Evil Gorilla
More information about the ffmpeg-devel
mailing list