[FFmpeg-devel] [PATCH 1/2] lavf: add control message API

Nicolas George george at nsup.org
Sat Jan 25 17:28:49 CET 2014


Le sextidi 6 pluviôse, an CCXXII, Lukasz Marek a écrit :
> >From 66b3c40236d7d3e1735869d50c18d4efa3b44ba7 Mon Sep 17 00:00:00 2001
> From: Lukasz Marek <lukasz.m.luki at gmail.com>
> Date: Sun, 19 Jan 2014 16:11:09 +0100
> Subject: [PATCH 1/3] lavd: add avdevice_app_to_dev_control_message API
> 
> New API allows to send messages from application to devices.
> 
> Signed-off-by: Lukasz Marek <lukasz.m.luki at gmail.com>
> ---
>  libavdevice/avdevice.c |  8 ++++++++
>  libavdevice/avdevice.h | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  libavdevice/version.h  |  4 ++--
>  libavformat/avformat.h |  5 +++++
>  libavformat/version.h  |  2 +-
>  5 files changed, 72 insertions(+), 3 deletions(-)
> 
> diff --git a/libavdevice/avdevice.c b/libavdevice/avdevice.c
> index b9b18f2..c232bbd 100644
> --- a/libavdevice/avdevice.c
> +++ b/libavdevice/avdevice.c
> @@ -36,3 +36,11 @@ const char * avdevice_license(void)
>  #define LICENSE_PREFIX "libavdevice license: "
>      return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
>  }
> +

> +int avdevice_app_to_dev_control_message(struct AVFormatContext *s, enum AVAppToDevMessageType type,
> +                                        void *data, size_t data_size)

I liked it betted in the avformat namespace (especially with the fork
threatening to merge lavd into lavf, sigh), but Stefano liked the opposite,
and I will not make you undo and redo changes endlessly: please decide what
you like better.

But, on this line and a few others: please split long lines.

> +{
> +    if (!s->oformat || !s->oformat->control_message)
> +        return AVERROR(ENOSYS);
> +    return s->oformat->control_message(s, type, data, data_size);
> +}
> diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h
> index 93a044f..56a2a1d 100644
> --- a/libavdevice/avdevice.h
> +++ b/libavdevice/avdevice.h
> @@ -66,4 +66,60 @@ const char *avdevice_license(void);
>   */
>  void avdevice_register_all(void);
>  

> +typedef struct AVDeviceSize {
> +    int width;  /**< width */
> +    int height; /**< height */
> +} AVDeviceSize;
> +
> +typedef struct AVDeviceRect {
> +    int x;      /**< x coordinate of top left corner */
> +    int y;      /**< y coordinate of top left corner */
> +    int width;  /**< width */
> +    int height; /**< height */
> +} AVDeviceRect;

The AVDeviceSize seems redundant. After some time programming applications
with Gtk+, I found it is easier on the developer's memory to have a single
structure with fields that are frequently unused.

> +
> +/**
> + * Message types used by avdevice_app_to_dev_control_message().
> + */
> +enum AVAppToDevMessageType {
> +    /**
> +     * Dummy message.
> +     */
> +    AV_APP_TO_DEV_NONE = MKBETAG('N','O','N','E'),
> +
> +    /**
> +     * Window size change message.
> +     *
> +     * Message is sent to device every time application change the size
> +     * of the window device renders to. Message should also be send
> +     * right after window is created.

Spelling nits: "the device", unless you consider it is a kind of agent; "the
application change_s_", "be sen_t_".

> +     *
> +     * data: AVDeviceSize: new window size.
> +     */
> +    AV_APP_TO_DEV_WINDOW_SIZE = MKBETAG('G','E','O','M'),
> +
> +    /**
> +     * Repaint request message.
> +     *
> +     * Message is sent to device when window have to be rapainted.
> +     *
> +     * data: AVDeviceRect: area required to be repainted
> +     *       NULL: whole area is required to be repainted.
> +     */
> +    AV_APP_TO_DEV_WINDOW_REPAINT = MKBETAG('R','E','P','A')
> +};
> +
> +/**
> + * Send control message from application to device.
> + *

> + * @param s device context
> + * @param type message type.
> + * @param data message data. Exact type depends on message type.
> + * @param data_size size of message data.

Nit: alignment would be nice.

> + * @return 0 on success, negative on error.

">= 0 on success", to leave room for evolution.

> + *         AVERROR(EINVAL) when device doesn't implement handler of the message.

EINVAL -> ENOSYS

> + */
> +int avdevice_app_to_dev_control_message(struct AVFormatContext *s, enum AVAppToDevMessageType type,
> +                                        void *data, size_t data_size);
> +
>  #endif /* AVDEVICE_AVDEVICE_H */
> diff --git a/libavdevice/version.h b/libavdevice/version.h
> index d569fae..bfd4a70 100644
> --- a/libavdevice/version.h
> +++ b/libavdevice/version.h
> @@ -28,8 +28,8 @@
>  #include "libavutil/version.h"
>  
>  #define LIBAVDEVICE_VERSION_MAJOR  55
> -#define LIBAVDEVICE_VERSION_MINOR   5
> -#define LIBAVDEVICE_VERSION_MICRO 102
> +#define LIBAVDEVICE_VERSION_MINOR   6
> +#define LIBAVDEVICE_VERSION_MICRO 100
>  
>  #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
>                                                 LIBAVDEVICE_VERSION_MINOR, \
> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
> index a495ee0..09eea74 100644
> --- a/libavformat/avformat.h
> +++ b/libavformat/avformat.h
> @@ -453,6 +453,11 @@ typedef struct AVOutputFormat {
>  
>      void (*get_output_timestamp)(struct AVFormatContext *s, int stream,
>                                   int64_t *dts, int64_t *wall);
> +    /**
> +     * Allows sending messages from application to device.
> +     */
> +    int (*control_message)(struct AVFormatContext *s, int type,
> +                           void *data, size_t data_size);
>  } AVOutputFormat;
>  /**
>   * @}
> diff --git a/libavformat/version.h b/libavformat/version.h
> index a0e5a7c..51f6d59 100644
> --- a/libavformat/version.h
> +++ b/libavformat/version.h
> @@ -30,7 +30,7 @@
>  #include "libavutil/version.h"
>  
>  #define LIBAVFORMAT_VERSION_MAJOR 55
> -#define LIBAVFORMAT_VERSION_MINOR 26
> +#define LIBAVFORMAT_VERSION_MINOR 27
>  #define LIBAVFORMAT_VERSION_MICRO 100
>  
>  #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
> -- 
> 1.8.3.2
> 

> >From 64b7ab2917bf3941235768022d2750b9da0860b9 Mon Sep 17 00:00:00 2001
> From: Lukasz Marek <lukasz.m.luki at gmail.com>
> Date: Sun, 19 Jan 2014 16:12:07 +0100
> Subject: [PATCH 2/3] lavd: add avdevice_dev_to_app_control_message API
> 
> New API allows to send messages from devices to application.
> 
> Signed-off-by: Lukasz Marek <lukasz.m.luki at gmail.com>
> ---
>  libavdevice/avdevice.c |  8 ++++++
>  libavdevice/avdevice.h | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  libavdevice/version.h  |  2 +-
>  libavformat/avformat.h | 24 ++++++++++++++++++
>  libavformat/utils.c    |  2 ++
>  libavformat/version.h  |  2 +-
>  6 files changed, 102 insertions(+), 2 deletions(-)
> 
> diff --git a/libavdevice/avdevice.c b/libavdevice/avdevice.c
> index c232bbd..51617fb 100644
> --- a/libavdevice/avdevice.c
> +++ b/libavdevice/avdevice.c
> @@ -44,3 +44,11 @@ int avdevice_app_to_dev_control_message(struct AVFormatContext *s, enum AVAppToD
>          return AVERROR(ENOSYS);
>      return s->oformat->control_message(s, type, data, data_size);
>  }
> +
> +int avdevice_dev_to_app_control_message(struct AVFormatContext *s, enum AVDevToAppMessageType type,
> +                                        void *data, size_t data_size)
> +{
> +    if (!s->control_message_cb)
> +        return AVERROR(ENOSYS);
> +    return s->control_message_cb(s, type, data, data_size);
> +}
> diff --git a/libavdevice/avdevice.h b/libavdevice/avdevice.h
> index 56a2a1d..17893eb 100644
> --- a/libavdevice/avdevice.h
> +++ b/libavdevice/avdevice.h
> @@ -110,6 +110,59 @@ enum AVAppToDevMessageType {
>  };
>  
>  /**
> + * Message types used by avdevice_dev_to_app_control_message().
> + */
> +enum AVDevToAppMessageType {
> +    /**
> +     * Dummy message.
> +     */
> +    AV_DEV_TO_APP_NONE = MKBETAG('N','O','N','E'),
> +
> +    /**
> +     * Create window buffer message.
> +     *

> +     * Device requests to create a window buffer. Exact meaning is device
> +     * and application dependent. Message is sent before rendering first
> +     * frame and all one-shot initializations should be done here.

Spelling nit: "device- and application-dependent".

> +     *
> +     * data: NULL.
> +     */
> +    AV_DEV_TO_APP_CREATE_WINDOW_BUFFER = MKBETAG('B','C','R','E'),
> +
> +    /**
> +     * Prepare window buffer message.
> +     *
> +     * Device requests to prepare a window buffer for rendering. Exact meaning is
> +     * device and application dependent. Message is sent before rendering of each frame.
> +     *
> +     * data: NULL.
> +     */
> +    AV_DEV_TO_APP_PREPARE_WINDOW_BUFFER = MKBETAG('B','P','R','E'),
> +
> +    /**
> +     * Display window buffer message.
> +     *
> +     * Device requests to display a window buffer.
> +     * Message is sent when new frame is ready to be displyed.
> +     * Usually buffers need to be swapped in handler of this message.
> +     *
> +     * data: NULL.
> +     */
> +    AV_DEV_TO_APP_DISPLAY_WINDOW_BUFFER = MKBETAG('B','D','I','S'),
> +
> +    /**
> +     * Destroy window buffer message.
> +     *
> +     * Device requests to destroy a window buffer.
> +     * Message is sent when device is about to be destroyed and window
> +     * buffer is not required anymore.
> +     *
> +     * data: NULL.
> +     */
> +    AV_DEV_TO_APP_DESTROY_WINDOW_BUFFER = MKBETAG('B','D','E','S')
> +};
> +
> +/**
>   * Send control message from application to device.
>   *
>   * @param s device context
> @@ -122,4 +175,17 @@ enum AVAppToDevMessageType {
>  int avdevice_app_to_dev_control_message(struct AVFormatContext *s, enum AVAppToDevMessageType type,
>                                          void *data, size_t data_size);
>  
> +/**
> + * Send control message from device to application.
> + *

> + * @param s device context
> + * @param type message type.
> + * @param data message data. Can be NULL.
> + * @param data_size size of message data.
> + * @return 0 on success, negative on error.

Same as above: alignment and ">= 0".

> + *         AVERROR(EINVAL) when application doesn't implement handler of the message.

Same as above: ENOSYS.

> + */
> +int avdevice_dev_to_app_control_message(struct AVFormatContext *s, enum AVDevToAppMessageType type,
> +                                        void *data, size_t data_size);
> +
>  #endif /* AVDEVICE_AVDEVICE_H */
> diff --git a/libavdevice/version.h b/libavdevice/version.h
> index bfd4a70..a621775 100644
> --- a/libavdevice/version.h
> +++ b/libavdevice/version.h
> @@ -28,7 +28,7 @@
>  #include "libavutil/version.h"
>  
>  #define LIBAVDEVICE_VERSION_MAJOR  55
> -#define LIBAVDEVICE_VERSION_MINOR   6
> +#define LIBAVDEVICE_VERSION_MINOR   7
>  #define LIBAVDEVICE_VERSION_MICRO 100
>  
>  #define LIBAVDEVICE_VERSION_INT AV_VERSION_INT(LIBAVDEVICE_VERSION_MAJOR, \
> diff --git a/libavformat/avformat.h b/libavformat/avformat.h
> index 09eea74..002b015 100644
> --- a/libavformat/avformat.h
> +++ b/libavformat/avformat.h
> @@ -953,6 +953,13 @@ typedef struct AVChapter {
>  
>  
>  /**
> + * Callback used by devices to communicate with application.
> + */
> +typedef int (*av_format_control_message)(struct AVFormatContext *s, int type,
> +                                         void *data, size_t data_size);
> +
> +
> +/**
>   * The duration of a video can be estimated through various ways, and this enum can be used
>   * to know how the duration was estimated.
>   */
> @@ -1360,6 +1367,19 @@ typedef struct AVFormatContext {
>       * Muxing: Set by user via av_format_set_metadata_header_padding.
>       */
>      int metadata_header_padding;
> +
> +    /**
> +     * User data.
> +     * This is a place for some private data of the user.
> +     * Mostly usable with control_message_cb or any future callbacks in device's context.
> +     */
> +    void *opaque;
> +
> +    /**
> +     * Callback used by devices to communicate with application.
> +     */
> +    av_format_control_message control_message_cb;
> +
>  } AVFormatContext;
>  
>  int av_format_get_probe_score(const AVFormatContext *s);
> @@ -1371,6 +1391,10 @@ AVCodec * av_format_get_subtitle_codec(const AVFormatContext *s);
>  void      av_format_set_subtitle_codec(AVFormatContext *s, AVCodec *c);
>  int       av_format_get_metadata_header_padding(const AVFormatContext *s);
>  void      av_format_set_metadata_header_padding(AVFormatContext *s, int c);
> +void *    av_format_get_opaque(const AVFormatContext *s);
> +void      av_format_set_opaque(AVFormatContext *s, void *opaque);
> +av_format_control_message av_format_get_control_message_cb(const AVFormatContext *s);
> +void      av_format_set_control_message_cb(AVFormatContext *s, av_format_control_message callback);
>  
>  /**
>   * Returns the method used to set ctx->duration.
> diff --git a/libavformat/utils.c b/libavformat/utils.c
> index 421dfef..ea4bd14 100644
> --- a/libavformat/utils.c
> +++ b/libavformat/utils.c
> @@ -104,6 +104,8 @@ MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, video_codec)
>  MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, audio_codec)
>  MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, subtitle_codec)
>  MAKE_ACCESSORS(AVFormatContext, format, int, metadata_header_padding)
> +MAKE_ACCESSORS(AVFormatContext, format, void *, opaque)
> +MAKE_ACCESSORS(AVFormatContext, format, av_format_control_message, control_message_cb)
>  
>  static AVCodec *find_decoder(AVFormatContext *s, AVStream *st, enum AVCodecID codec_id)
>  {
> diff --git a/libavformat/version.h b/libavformat/version.h
> index 51f6d59..92f81a9 100644
> --- a/libavformat/version.h
> +++ b/libavformat/version.h
> @@ -30,7 +30,7 @@
>  #include "libavutil/version.h"
>  
>  #define LIBAVFORMAT_VERSION_MAJOR 55
> -#define LIBAVFORMAT_VERSION_MINOR 27
> +#define LIBAVFORMAT_VERSION_MINOR 28
>  #define LIBAVFORMAT_VERSION_MICRO 100
>  
>  #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
> -- 
> 1.8.3.2
> 

Regards,

-- 
  Nicolas George
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20140125/ca961fa6/attachment.asc>


More information about the ffmpeg-devel mailing list