[FFmpeg-devel] [PATCH 4/4] examples: opengl_device_settings
Lukasz Marek
lukasz.m.luki at gmail.com
Mon Feb 3 01:02:51 CET 2014
Just a testing tool. Do not merge.
---
doc/examples/Makefile | 1 +
doc/examples/opengl_device_settings.c | 176 ++++++++++++++++++++++++++++++++++
2 files changed, 177 insertions(+)
create mode 100644 doc/examples/opengl_device_settings.c
diff --git a/doc/examples/Makefile b/doc/examples/Makefile
index f4f6c70..73b07da 100644
--- a/doc/examples/Makefile
+++ b/doc/examples/Makefile
@@ -22,6 +22,7 @@ EXAMPLES= avio_reading \
resampling_audio \
scaling_video \
transcode_aac \
+ opengl_device_settings \
OBJS=$(addsuffix .o,$(EXAMPLES))
diff --git a/doc/examples/opengl_device_settings.c b/doc/examples/opengl_device_settings.c
new file mode 100644
index 0000000..3debcc5
--- /dev/null
+++ b/doc/examples/opengl_device_settings.c
@@ -0,0 +1,176 @@
+
+#include <SDL/SDL.h>
+#include <libavutil/log.h>
+#include <libavutil/pixdesc.h>
+#include <libavutil/opt.h>
+#include <libavformat/avformat.h>
+#include <libavdevice/avdevice.h>
+
+SDL_Surface *g_surface = NULL;
+
+static int av_cold create_sdl_window(int width, int height)
+{
+ if (SDL_Init(SDL_INIT_VIDEO)) {
+ av_log(NULL, AV_LOG_ERROR, "Unable to initialize SDL: %s\n", SDL_GetError());
+ return AVERROR_EXTERNAL;
+ }
+ g_surface = SDL_SetVideoMode(width, height, 32, SDL_OPENGL);
+ if (!g_surface) {
+ av_log(NULL, AV_LOG_ERROR, "Unable to set video mode: %s\n", SDL_GetError());
+ return AVERROR_EXTERNAL;
+ }
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ return 0;
+}
+
+static int message_from_device_handler(struct AVFormatContext *s, int type,
+ void *data, size_t data_size)
+{
+ switch ((enum AVDevToAppMessageType) type) {
+ case AV_DEV_TO_APP_CREATE_WINDOW_BUFFER:
+ if (!g_surface)
+ return create_sdl_window(1, 1);
+ return 0;
+ case AV_DEV_TO_APP_DESTROY_WINDOW_BUFFER:
+ SDL_Quit();
+ g_surface = NULL;
+ return 0;
+ case AV_DEV_TO_APP_PREPARE_WINDOW_BUFFER:
+ //SDL 1.2 doesn't required it (no such API),
+ //but you need to make OpenGL context current here.
+ return 0;
+ case AV_DEV_TO_APP_DISPLAY_WINDOW_BUFFER:
+ SDL_GL_SwapBuffers();
+ return 0;
+ default:
+ break;
+ }
+ return AVERROR(ENOSYS);
+}
+
+static int print_ranges(AVFormatContext *oc, enum AVDeviceCapability cap,
+ const char *cap_name)
+{
+ int i;
+ AVOptionRanges *ranges;
+ AVOptionRange *range;
+
+ if ((i = avdevice_get_device_capability(oc, cap, &ranges)) < 0) {
+ av_log(oc, AV_LOG_ERROR, "Cannot query range of %s\n", cap_name);
+ return i;
+ }
+ av_log(oc, AV_LOG_INFO, "%-14s: allowed values: ", cap_name);
+ for(i = 0; i < ranges->nb_ranges; i++) {
+ range = ranges->range[i];
+ if (i)
+ av_log(oc, AV_LOG_INFO, ", ");
+ if (range->is_range)
+ if (cap == AV_DEV_CAP_FPS)
+ av_log(oc, AV_LOG_INFO, "%.5f - %.5f", range->value_min, range->value_max);
+ else
+ av_log(oc, AV_LOG_INFO, "%d - %d", (int)range->value_min, (int)range->value_max);
+ else {
+ if (cap == AV_DEV_CAP_FPS)
+ av_log(oc, AV_LOG_INFO, "%.5f", range->value_min);
+ if (cap == AV_DEV_CAP_FORMAT)
+ av_log(oc, AV_LOG_INFO, "%s", av_get_pix_fmt_name((int)range->value_min));
+ else if (cap == AV_DEV_CAP_CODEC_ID)
+ av_log(oc, AV_LOG_INFO, "%s", avcodec_get_name((int)range->value_min));
+ else
+ av_log(oc, AV_LOG_INFO, "%d", (int)range->value_min);
+ }
+ }
+ av_log(oc, AV_LOG_INFO, "\n");
+ av_opt_freep_ranges(&ranges);
+ return 0;
+}
+
+void print_all(AVFormatContext *oc)
+{
+ print_ranges(oc, AV_DEV_CAP_WINDOW_WIDTH, "window width");
+ print_ranges(oc, AV_DEV_CAP_WINDOW_HEIGHT, "window height");
+ print_ranges(oc, AV_DEV_CAP_FRAME_WIDTH, "frame width");
+ print_ranges(oc, AV_DEV_CAP_FRAME_HEIGHT, "frame height");
+ print_ranges(oc, AV_DEV_CAP_FPS, "fps");
+ print_ranges(oc, AV_DEV_CAP_CODEC_ID, "codec");
+ print_ranges(oc, AV_DEV_CAP_FORMAT, "format");
+}
+
+int set_video_configuration(AVFormatContext *oc)
+{
+ int ret;
+ AVDictionary *opts = NULL;
+ AVDeviceCapabilities *spec;
+
+ av_dict_set(&opts, "no_window", "1", 0);
+ ret = avdevice_init_device_capabilities(oc, &opts);
+ av_dict_free(&opts);
+ if (ret < 0) {
+ if (ret == AVERROR(ENOSYS))
+ av_log(oc, AV_LOG_ERROR, "Device doesn't provide this API.\n");
+ else
+ av_log(oc, AV_LOG_ERROR, "Error occurred.\n");
+ return ret;
+ }
+
+ av_log(oc, AV_LOG_INFO, "Parameter ranges accepted by OpenGL device are:\n");
+ print_all(oc);
+
+ avdevice_set_device_capability_int(oc, AV_DEV_CAP_WINDOW_WIDTH, 256);
+ avdevice_set_device_capability_int(oc, AV_DEV_CAP_WINDOW_HEIGHT, 256);
+ avdevice_set_device_capability_int(oc, AV_DEV_CAP_FRAME_WIDTH, 256);
+ avdevice_set_device_capability_int(oc, AV_DEV_CAP_FRAME_HEIGHT, 256);
+ //Set codec to raw video
+ avdevice_set_device_capability_int(oc, AV_DEV_CAP_CODEC_ID, AV_CODEC_ID_RAWVIDEO);
+ //60 frames per second, fps is ignored by OpenGL device, but it can be set
+ avdevice_set_device_capability_q(oc, AV_DEV_CAP_FPS, (AVRational){60, 1});
+ //set RGB24 format: each component is 1 byte long and no alpha
+ avdevice_set_device_capability_int(oc, AV_DEV_CAP_FORMAT, AV_PIX_FMT_RGB24);
+
+ av_log(oc, AV_LOG_INFO, "\n");
+ av_log(oc, AV_LOG_INFO, "Current OpenGL device configuration:\n");
+ print_all(oc);
+
+ avdevice_finish_device_capabilities(oc, &spec, AVDeviceApplyStrategyAbandonNotValid);
+ if (!spec) {
+ av_log(oc, AV_LOG_ERROR, "Provided configuration is wrong!\n");
+ return -1;
+ } else
+ av_log(oc, AV_LOG_INFO, "Configuration accepted!\n");
+
+ avdevice_free_device_capabilities(&spec);
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+ AVFormatContext *oc;
+
+ //av_log_set_level(AV_LOG_DEBUG);
+
+ av_register_all();
+ avdevice_register_all();
+
+ /* allocate the output media context */
+ ret = avformat_alloc_output_context2(&oc, NULL, "opengl", NULL);
+ if (ret < 0 || !oc) {
+ av_log(NULL, AV_LOG_ERROR, "Could not allocate output format context.\n");
+ return 1;
+ }
+
+ av_format_set_control_message_cb(oc, message_from_device_handler);
+
+ set_video_configuration(oc);
+
+ av_log(oc, AV_LOG_INFO, "To be continued...\n");
+
+ avformat_free_context(oc);
+
+ return 0;
+}
--
1.8.3.2
More information about the ffmpeg-devel
mailing list