X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavdevice%2Fopengl_enc.c;h=9302979f46ccfe829fb9197c8392f07309347c26;hb=f183d6555e714e00b41aec728feb8a731826cbdc;hp=54c7e610bd52b9a32c8f6d9efc829c7c216b09e0;hpb=5ca7eb36b7353f9e6af05a5a952eead5f6d326dd;p=ffmpeg diff --git a/libavdevice/opengl_enc.c b/libavdevice/opengl_enc.c index 54c7e610bd5..9302979f46c 100644 --- a/libavdevice/opengl_enc.c +++ b/libavdevice/opengl_enc.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include "config.h" @@ -569,8 +568,9 @@ static void opengl_make_ortho(float matrix[16], float left, float right, matrix[15] = 1.0f; } -static av_cold int opengl_read_limits(OpenGLContext *opengl) +static av_cold int opengl_read_limits(AVFormatContext *h) { + OpenGLContext *opengl = h->priv_data; static const struct{ const char *extension; int major; @@ -588,17 +588,21 @@ static av_cold int opengl_read_limits(OpenGLContext *opengl) version = glGetString(GL_VERSION); extensions = glGetString(GL_EXTENSIONS); + if (!version || !extensions) { + av_log(h, AV_LOG_ERROR, "No OpenGL context initialized for the current thread\n"); + return AVERROR(ENOSYS); + } - av_log(opengl, AV_LOG_DEBUG, "OpenGL version: %s\n", version); + av_log(h, AV_LOG_DEBUG, "OpenGL version: %s\n", version); sscanf(version, "%d.%d", &major, &minor); for (i = 0; required_extensions[i].extension; i++) { if (major < required_extensions[i].major && (major == required_extensions[i].major && minor < required_extensions[i].minor) && !strstr(extensions, required_extensions[i].extension)) { - av_log(opengl, AV_LOG_ERROR, "Required extension %s is not supported.\n", + av_log(h, AV_LOG_ERROR, "Required extension %s is not supported.\n", required_extensions[i].extension); - av_log(opengl, AV_LOG_DEBUG, "Supported extensions are: %s\n", extensions); + av_log(h, AV_LOG_DEBUG, "Supported extensions are: %s\n", extensions); return AVERROR(ENOSYS); } } @@ -611,10 +615,10 @@ static av_cold int opengl_read_limits(OpenGLContext *opengl) opengl->unpack_subimage = 1; #endif - av_log(opengl, AV_LOG_DEBUG, "Non Power of 2 textures support: %s\n", opengl->non_pow_2_textures ? "Yes" : "No"); - av_log(opengl, AV_LOG_DEBUG, "Unpack Subimage extension support: %s\n", opengl->unpack_subimage ? "Yes" : "No"); - av_log(opengl, AV_LOG_DEBUG, "Max texture size: %dx%d\n", opengl->max_texture_size, opengl->max_texture_size); - av_log(opengl, AV_LOG_DEBUG, "Max viewport size: %dx%d\n", + av_log(h, AV_LOG_DEBUG, "Non Power of 2 textures support: %s\n", opengl->non_pow_2_textures ? "Yes" : "No"); + av_log(h, AV_LOG_DEBUG, "Unpack Subimage extension support: %s\n", opengl->unpack_subimage ? "Yes" : "No"); + av_log(h, AV_LOG_DEBUG, "Max texture size: %dx%d\n", opengl->max_texture_size, opengl->max_texture_size); + av_log(h, AV_LOG_DEBUG, "Max viewport size: %dx%d\n", opengl->max_viewport_width, opengl->max_viewport_height); OPENGL_ERROR_CHECK(opengl); @@ -1051,13 +1055,14 @@ static av_cold int opengl_init_context(OpenGLContext *opengl) static av_cold int opengl_write_header(AVFormatContext *h) { OpenGLContext *opengl = h->priv_data; + AVCodecParameters *par = h->streams[0]->codecpar; AVStream *st; int ret; if (h->nb_streams != 1 || - h->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO || - h->streams[0]->codecpar->codec_id != AV_CODEC_ID_RAWVIDEO) { - av_log(opengl, AV_LOG_ERROR, "Only a single video stream is supported.\n"); + par->codec_type != AVMEDIA_TYPE_VIDEO || + (par->codec_id != AV_CODEC_ID_WRAPPED_AVFRAME && par->codec_id != AV_CODEC_ID_RAWVIDEO)) { + av_log(opengl, AV_LOG_ERROR, "Only a single raw or wrapped avframe video stream is supported.\n"); return AVERROR(EINVAL); } st = h->streams[0]; @@ -1075,7 +1080,7 @@ static av_cold int opengl_write_header(AVFormatContext *h) if ((ret = opengl_create_window(h))) goto fail; - if ((ret = opengl_read_limits(opengl)) < 0) + if ((ret = opengl_read_limits(h)) < 0) goto fail; if (opengl->width > opengl->max_texture_size || opengl->height > opengl->max_texture_size) { @@ -1252,7 +1257,13 @@ static int opengl_draw(AVFormatContext *h, void *input, int repaint, int is_pkt) static int opengl_write_packet(AVFormatContext *h, AVPacket *pkt) { - return opengl_draw(h, pkt, 0, 1); + AVCodecParameters *par = h->streams[0]->codecpar; + if (par->codec_id == AV_CODEC_ID_WRAPPED_AVFRAME) { + AVFrame *frame = (AVFrame *)pkt->data; + return opengl_draw(h, frame, 0, 0); + } else { + return opengl_draw(h, pkt, 0, 1); + } } static int opengl_write_frame(AVFormatContext *h, int stream_index, @@ -1266,7 +1277,7 @@ static int opengl_write_frame(AVFormatContext *h, int stream_index, #define OFFSET(x) offsetof(OpenGLContext, x) #define ENC AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { - { "background", "set background color", OFFSET(background), AV_OPT_TYPE_COLOR, {.str = "black"}, CHAR_MIN, CHAR_MAX, ENC }, + { "background", "set background color", OFFSET(background), AV_OPT_TYPE_COLOR, {.str = "black"}, 0, 0, ENC }, { "no_window", "disable default window", OFFSET(no_window), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, ENC }, { "window_title", "set window title", OFFSET(window_title), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, ENC }, { "window_size", "set window size", OFFSET(window_width), AV_OPT_TYPE_IMAGE_SIZE, {.str = NULL}, 0, 0, ENC }, @@ -1281,12 +1292,12 @@ static const AVClass opengl_class = { .category = AV_CLASS_CATEGORY_DEVICE_VIDEO_OUTPUT, }; -AVOutputFormat ff_opengl_muxer = { +const AVOutputFormat ff_opengl_muxer = { .name = "opengl", .long_name = NULL_IF_CONFIG_SMALL("OpenGL output"), .priv_data_size = sizeof(OpenGLContext), .audio_codec = AV_CODEC_ID_NONE, - .video_codec = AV_CODEC_ID_RAWVIDEO, + .video_codec = AV_CODEC_ID_WRAPPED_AVFRAME, .write_header = opengl_write_header, .write_packet = opengl_write_packet, .write_uncoded_frame = opengl_write_frame,