Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • videolan/vlc
  • chouquette/vlc
  • bakiewicz.marek122/vlc
  • devnexen/vlc
  • rohanrajpal/vlc
  • blurrrb/vlc
  • gsoc/gsoc2019/darkapex/vlc
  • b1ue/vlc
  • fkuehne/vlc
  • magsoft/vlc
  • chub/vlc
  • cramiro9/vlc
  • robUx4/vlc
  • rom1v/vlc
  • akshayaky/vlc
  • tmk907/vlc
  • akymaster/vlc
  • govind.sharma/vlc
  • psilokos/vlc
  • xjbeta/vlc
  • jahan/vlc
  • 1480c1/vlc
  • amanchande/vlc
  • aaqib/vlc
  • rist/vlc
  • apol/vlc
  • mindfreeze/vlc
  • alexandre-janniaux/vlc
  • sandsmark/vlc
  • jagannatharjun/vlc
  • gsoc/gsoc2020/matiaslgonzalez/vlc
  • gsoc/gsoc2020/jagannatharjun/vlc
  • mstorsjo/vlc
  • gsoc/gsoc2020/vedenta/vlc
  • gsoc/gsoc2020/arnav-ishaan/vlc
  • gsoc/gsoc2020/andreduong/vlc
  • fuzun/vlc
  • gsoc/gsoc2020/vatsin/vlc
  • gsoc/gsoc2020/sagid/vlc
  • yaron/vlc
  • Phoenix/vlc
  • Garf/vlc
  • ePiratWorkarounds/vlc
  • tguillem/vlc
  • jnqnfe/vlc
  • mdc/vlc
  • Vedaa/vlc
  • rasa/vlc
  • quink/vlc
  • yealo/vlc
  • aleksey_ak/vlc
  • ePirat/vlc
  • ilya.yanok/vlc
  • asenat/vlc
  • m/vlc
  • bunjee/vlc
  • BLumia/vlc
  • sagudev/vlc
  • hamedmonji30/vlc
  • nullgemm/vlc
  • DivyamAhuja/vlc
  • thesamesam/vlc
  • dag7/vlc
  • snehil101/vlc
  • haasn/vlc
  • jbk/vlc
  • ValZapod/vlc
  • mfkl/vlc
  • WangChuan/vlc
  • core1024/vlc
  • GhostVaibhav/vlc
  • dfuhrmann/vlc
  • davide.prade/vlc
  • tmatth/vlc
  • Courmisch/vlc
  • zouya/vlc
  • hpi/vlc
  • EwoutH/vlc
  • aleung27/vlc
  • hengwu0/vlc
  • saladin/vlc
  • ashuio/vlc
  • richselwood/vlc
  • verma16Ayush/vlc
  • chemicalflash/vlc
  • PoignardAzur/vlc
  • huangjieNT/vlc
  • Blake-Haydon/vlc
  • AnuthaDev/vlc
  • gsoc/gsoc2021/mpd/vlc
  • nicolas_lequec/vlc
  • sambassaly/vlc
  • thresh/vlc
  • bonniegong/vlc
  • myaashish/vlc
  • stavros.vagionitis/vlc
  • ileoo/vlc
  • louis-santucci/vlc
  • cchristiansen/vlc
  • sabyasachi07/vlc
  • AbduAmeen/vlc
  • ashishb0410/vlc
  • urbanhusky/vlc
  • davidepietrasanta/vlc
  • riksleutelstad/vlc
  • jeremyVignelles/vlc
  • komh/vlc
  • iamjithinjohn/vlc
  • JohannesKauffmann/vlc2
  • kunglao/vlc
  • natzberg/vlc
  • jill/vlc
  • cwendling/vlc
  • adufou/vlc
  • ErwanAirone/vlc
  • HasinduDilshan10/vlc
  • vagrantc/vlc
  • rafiv/macos-bigsur-icon
  • Aymeriic/vlc
  • saranshg20/vlc
  • metzlove24/vlc
  • linkfanel/vlc
  • Ds886/vlc
  • metehan-arslan/vlc
  • Skantes/vlc
  • kgsandundananjaya96/vlc
  • mitchcapper/vlc
  • advaitgupta/vlc
  • StefanBruens/vlc
  • ratajs/vlc
  • T.M.F.B.3761/vlc
  • m222059/vlc
  • casemerrick/vlc
  • joshuaword2alt/vlc
  • sjwaddy/vlc
  • dima/vlc
  • Ybalrid/vlc
  • umxprime/vlc
  • eschmidt/vlc
  • vannieuwenhuysenmichelle/vlc
  • badcf00d/vlc
  • wesinator/vlc
  • louis/vlc
  • xqq/vlc
  • EmperorYP7/vlc
  • NicoLiam/vlc
  • loveleen/vlc
  • rofferom/vlc
  • rbultje/vlc
  • TheUnamed/vlc
  • pratiksharma341/vlc
  • Saurab17/vlc
  • purist.coder/vlc
  • Shuicheng/vlc
  • mdrrubel292/vlc
  • silverbleu00/vlc
  • metif12/vlc
  • asher-m/vlc
  • jeffk/vlc
  • Brandonbr1/vlc
  • beautyyuyanli/vlc
  • rego21/vlc
  • muyangren907/vlc
  • collectionbylawrencejason/vlc
  • evelez/vlc
  • GSMgeeth/vlc
  • Oneric/vlc
  • TJ5/vlc
  • XuanTung95/vlc
  • darrenjenny21/vlc
  • Trenly/vlc
  • RockyTDR/vlc
  • mjakubowski/vlc
  • caprica/vlc
  • ForteFrankie/vlc
  • seannamiller19/vlc
  • junlon2006/vlc
  • kiwiren6666/vlc
  • iuseiphonexs/vlc
  • fenngtun/vlc
  • Rajdutt999/vlc
  • typx/vlc
  • leon.vitanos/vlc
  • robertogarci0938/vlc
  • gsoc/gsoc2022/luc65r/vlc-mpd
  • skeller/vlc
  • MCJack123/vlc
  • luc65r/vlc-mpd
  • popov895/vlc
  • claucambra/vlc
  • brad/vlc
  • matthewmurua88/vlc
  • Tomas8874/vlc
  • philenotfound/vlc
  • makita-do3/vlc
  • LZXCorp/vlc
  • mar0x/vlc
  • senojetkennedy0102/vlc
  • shaneb243/vlc
  • ahmadbader/vlc
  • rajduttcse26/vlc-audio-filters
  • Juniorzito8415/vlc
  • achernyakov/vlc
  • lucasjetgroup/vlc
  • pupdoggy666/vlc
  • gmde9363/vlc
  • alexnwayne/vlc
  • bahareebrahimi781/vlc
  • hamad633666/vlc
  • umghof3112/vlc
  • joe0199771874/vlc
  • Octocats66666666/vlc
  • jjm_223/vlc
  • btech10110.19/vlc
  • sunnykfc028/vlc-audio-filters
  • loic/vlc
  • nguyenminhducmx1/vlc
  • JanekKrueger/vlc
  • bstubbington2/vlc
  • rcombs/vlc
  • Ordissimo/vlc
  • king7532/vlc
  • noobsauce101/vlc
  • schong0525/vlc
  • myQwil/vlc
  • apisbg91/vlc
  • geeboy0101017/vlc
  • kim.faughey/vlc
  • nurupo/vlc
  • yyusea/vlc
  • 0711235879.khco/vlc
  • ialo/vlc
  • iloveyeye2/vlc
  • gdtdftdqtd/vlc
  • leandroconsiglio/vlc
  • AndyHTML2012/vlc
  • ncz/vlc
  • lucenticus/vlc
  • knr1931/vlc
  • kjoonlee/vlc
  • chandrakant100/vlc-qt
  • johge42/vlc
  • polter/vlc
  • hexchain/vlc
  • Tushwrld/vlc
  • mztea928/vlc
  • jbelloncastro/vlc
  • alvinhochun/vlc
  • ghostpiratecrow/vlc
  • ujjwaltwitx/vlc
  • alexsonarin06/vlc
  • adrianbon76/vlc
  • altsod/vlc
  • damien.lucas44/vlc
  • dmytrivtaisa/vlc
  • utk202/vlc
  • aaxhrj/vlc
  • thomas.hermes/vlc
  • structurenewworldorder/vlc
  • slomo/vlc
  • wantlamy/vlc
  • musc.o3cminc/vlc
  • thebarshablog/vlc
  • kerrick/vlc
  • kratos142518/vlc
  • leogps/vlc
  • vacantron/vlc
  • luna_koly/vlc
  • Ratio2/vlc
  • anuoshemohammad/vlc
  • apsun/vlc
  • aaa1115910/vlc
  • alimotmoyo/vlc
  • Ambossmann/vlc
  • Sam-LearnsToCode/vlc
  • Chilledheart/vlc
  • Labnann/vlc
  • ktcoooot1/vlc
  • mohit-marathe/vlc
  • johnddx/vlc
  • manstabuk/vlc
  • Omar-ahmed314/vlc
  • vineethkm/vlc
  • 9Enemi86/vlc
  • radoslav.m.panteleev/vlc
  • ashishami2002/vlc
  • Corbax/vlc
  • firnasahmed/vlc
  • pelayarmalam4/vlc
  • c0ff330k/vlc
  • shikhindahikar/vlc
  • l342723951/vlc
  • christianschwandner/vlc
  • douniwan5788/vlc
  • 7damian7/vlc
  • ferdnyc/vlc
  • f.ales1/vlc
  • pandagby/vlc
  • BaaBaa/vlc
  • jewe37/vlc
  • w00drow/vlc
  • russelltg/vlc
  • ironicallygod/vlc
  • soumyaDghosh/vlc
  • linzihao1999/vlc
  • deyayush6/vlc
  • mibi88/vlc
  • newabdallah10/vlc
  • jhorbincolombia/vlc
  • rimvihaqueshupto/vlc
  • andrewkhon98/vlc
  • fab78/vlc
  • lapaz17/vlc
  • amanna13/vlc
  • mdakram28/vlc
  • 07jw1980/vlc
  • sohamgupta/vlc
  • Eson-Jia1/vlc
  • Sumou/vlc
  • vikram-kangotra/vlc
  • chalice191/vlc
  • olivercalder/vlc
  • aaasg4001/vlc
  • zipdox/vlc
  • kwizart/vlc
  • Dragon-S/vlc
  • jdemeule/vlc
  • gabriel_lt/vlc
  • locutusofborg/vlc
  • sammirata/vlc-librist
  • another/vlc
  • Benjamin_Loison/vlc
  • ahmedmoselhi/vlc
  • petergaal/vlc
  • huynhsontung/vlc
  • dariusmihut/vlc
  • tvermaashutosh/vlc
  • buti/vlc
  • Niram7777/vlc
  • rohan-here/vlc
  • balaji-sivasakthi/vlc
  • rlindner81/vlc
  • Kakadus/vlc
  • djain/vlc
  • ABBurmeister/vlc
  • craighuggins/vlc
  • orbea/vlc
  • maxos/vlc
  • aakarshmj/vlc
  • kblaschke/vlc
  • ankitm/vlc
  • advait-0/vlc
  • mohak2003/vlc
  • yselkowitz/vlc
  • AZM999/vlc-azm
  • andrey.turkin/vlc
  • Disha-Baghel/vlc
  • nowrep/vlc
  • Apeng/vlc
  • Choucroute_melba/vlc
  • autra/vlc
  • eclipseo/vlc
  • fhuber/vlc
  • olafhering/vlc
  • sdasda7777/vlc
  • 1div0/vlc
  • skosnits/vlc-extended-playlist-support
  • dnicolson/vlc
  • Timshel/vlc
  • octopols/vlc
  • MangalK/vlc
  • nima64/vlc
  • misawai/vlc
  • Alexander-Wilms/vlc
  • Maxime2/vlc-fork-for-visualizer
  • ww/vlc
  • jeske/vlc
  • sgross-emlix/vlc
  • morenonatural/vlc
  • freakingLovesVLC/vlc
  • borisgolovnev/vlc
  • mpromonet/vlc
  • diogo.simao-marques/vlc
  • masstock/vlc
  • pratikpatel8982/vlc
  • hugok79/vlc
  • longervision/vlc
  • abhiudaysurya/vlc
  • rishabhgarg/vlc
  • tumic/vlc
  • cart/vlc
  • shubham442/vlc
  • Aditya692005/vlc
  • sammirata/vlc4
  • syrykh/vlc
  • Vvorcun/macos-new-icon
  • AyaanshC/vlc
  • nasso/vlc
  • Quark/vlc
  • sebastinas/vlc
  • rhstone/vlc
  • talregev/vlc
  • Managor/vlc
403 results
Show changes
Commits on Source (7)
Showing
with 775 additions and 38 deletions
......@@ -2484,7 +2484,7 @@ AC_ARG_ENABLE([gst-decode],
have_gst_decode="no"
AS_IF([test "${enable_gst_decode}" != "no"], [
PKG_CHECK_MODULES([GST_APP], [gstreamer-app-1.0], [
PKG_CHECK_MODULES([GST_VIDEO], [gstreamer-video-1.0], [
PKG_CHECK_MODULES([GST_VIDEO], [gstreamer-video-1.0 gstreamer-allocators-1.0], [
have_gst_decode="yes"
], [
AC_MSG_WARN([${GST_VIDEO_PKG_ERRORS}. GStreamer decoder module will not be built.])
......
......@@ -588,6 +588,7 @@ enum vlc_decoder_device_type
VLC_DECODER_DEVICE_AWINDOW,
VLC_DECODER_DEVICE_NVDEC,
VLC_DECODER_DEVICE_MMAL,
VLC_DECODER_DEVICE_GSTDECODE,
};
struct vlc_decoder_device_operations
......
......@@ -439,6 +439,9 @@
#define VLC_CODEC_CVPX_BGRA VLC_FOURCC('C','V','P','B')
#define VLC_CODEC_CVPX_P010 VLC_FOURCC('C','V','P','P')
/* GStreamer Memory opaque buffer type */
#define VLC_CODEC_GST_MEM_OPAQUE VLC_FOURCC('G','S','T','M')
/* Image codec (video) */
#define VLC_CODEC_PNG VLC_FOURCC('p','n','g',' ')
#define VLC_CODEC_PPM VLC_FOURCC('p','p','m',' ')
......
......@@ -98,6 +98,7 @@ enum vlc_video_context_type
VLC_VIDEO_CONTEXT_NVDEC, //!< empty
VLC_VIDEO_CONTEXT_CVPX, //!< private: cvpx_video_context*
VLC_VIDEO_CONTEXT_MMAL, //!< empty
VLC_VIDEO_CONTEXT_GSTDECODE, //!< empty
};
VLC_API vlc_video_context * vlc_video_context_Create(vlc_decoder_device *,
......
......@@ -614,6 +614,9 @@ libgstdecode_plugin_la_SOURCES = codec/gstreamer/gstdecode.c \
codec/gstreamer/gstvlcvideopool.h \
codec/gstreamer/gstvlcvideosink.c \
codec/gstreamer/gstvlcvideosink.h \
codec/gstreamer/gstcopypicture.c \
codec/gstreamer/gstcopypicture.h \
codec/gstreamer/gst_mem.h \
codec/gstreamer/fourcc.c
libgstdecode_plugin_la_CFLAGS = $(AM_CFLAGS) $(GST_VIDEO_CFLAGS) $(GST_APP_CFLAGS)
libgstdecode_plugin_la_LIBADD = $(GST_VIDEO_LIBS) $(GST_APP_LIBS)
......
/*****************************************************************************
* gst_mem.h: GStreamer Memory picture context for VLC
*****************************************************************************
* Copyright (C) 2022 VLC authors and VideoLAN
*
* Author: Yann Lochet <yann@l0chet.fr>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef VLC_GST_MEM_H
#define VLC_GST_MEM_H
#include <vlc_picture.h>
#include <gst/gst.h>
#include <gst/video/video.h>
struct gst_mem_pic_context
{
picture_context_t s;
GstBuffer *p_buf;
GstVideoInfo *p_vinfo;
};
#endif
/*****************************************************************************
* gstcopypicture.h: copy GStreamer frames into pictures
*****************************************************************************
* Copyright (C) 2022 VLC authors and VideoLAN
*
* Author: Yann Lochet <yann@l0chet.fr>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#include <vlc_picture.h>
#include <gst/gst.h>
#include <gst/video/video.h>
#include "gstcopypicture.h"
/* Copy the frame data from the GstBuffer (from decoder)
* to the picture obtained from downstream in VLC.
* This function should be avoided as much
* as possible, since it involves a complete frame copy. */
void gst_CopyPicture( picture_t *p_pic, GstVideoFrame *p_frame )
{
int i_plane, i_planes, i_line, i_dst_stride, i_src_stride;
uint8_t *p_dst, *p_src;
int i_w, i_h;
i_planes = p_pic->i_planes;
for( i_plane = 0; i_plane < i_planes; i_plane++ )
{
p_dst = p_pic->p[i_plane].p_pixels;
p_src = GST_VIDEO_FRAME_PLANE_DATA( p_frame, i_plane );
i_dst_stride = p_pic->p[i_plane].i_pitch;
i_src_stride = GST_VIDEO_FRAME_PLANE_STRIDE( p_frame, i_plane );
i_w = GST_VIDEO_FRAME_COMP_WIDTH( p_frame,
i_plane ) * GST_VIDEO_FRAME_COMP_PSTRIDE( p_frame, i_plane );
i_h = GST_VIDEO_FRAME_COMP_HEIGHT( p_frame, i_plane );
for( i_line = 0;
i_line < __MIN( p_pic->p[i_plane].i_lines, i_h );
i_line++ )
{
memcpy( p_dst, p_src, i_w );
p_src += i_src_stride;
p_dst += i_dst_stride;
}
}
}
/*****************************************************************************
* gstcopypicture.h: copy GStreamer frames into pictures
*****************************************************************************
* Copyright (C) 2022 VLC authors and VideoLAN
*
* Author: Yann Lochet <yann@l0chet.fr>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifndef VLC_GSTCOPYPICTURE_H
#define VLC_GSTCOPYPICTURE_H
#include <gst/gst.h>
#include <gst/video/video.h>
void gst_CopyPicture( picture_t *p_pic, GstVideoFrame *p_frame );
#endif
......@@ -34,12 +34,15 @@
#include <gst/gst.h>
#include <gst/video/video.h>
#include <gst/video/gstvideometa.h>
#include <gst/allocators/gstdmabuf.h>
#include <gst/app/gstappsrc.h>
#include <gst/gstatomicqueue.h>
#include "gstvlcpictureplaneallocator.h"
#include "gstvlcvideosink.h"
#include "gstcopypicture.h"
#include "gst_mem.h"
typedef struct
{
......@@ -56,6 +59,8 @@ typedef struct
GstAtomicQueue *p_que;
bool b_prerolled;
bool b_running;
vlc_video_context *vctx;
} decoder_sys_t;
typedef struct
......@@ -71,6 +76,7 @@ static int OpenDecoder( vlc_object_t* );
static void CloseDecoder( vlc_object_t* );
static int DecodeBlock( decoder_t*, block_t* );
static void Flush( decoder_t * );
static int OpenDecoderDevice( vlc_decoder_device*, vlc_window_t* );
#define MODULE_DESCRIPTION N_( "Uses GStreamer framework's plugins " \
"to decode the media codecs" )
......@@ -104,8 +110,37 @@ vlc_module_begin( )
USEDECODEBIN_LONGTEXT )
add_bool( "use-vlcpool", false, USEVLCPOOL_TEXT,
USEVLCPOOL_LONGTEXT )
add_submodule( )
set_callback_dec_device( OpenDecoderDevice, 100 )
add_shortcut( "gstdecode" )
vlc_module_end( )
static void gst_mem_pic_context_Destroy( struct picture_context_t *ctx )
{
struct gst_mem_pic_context *gst_mem_ctx = container_of( ctx,
struct gst_mem_pic_context, s );
gst_buffer_unref( gst_mem_ctx->p_buf );
free( gst_mem_ctx );
}
static picture_context_t *gst_mem_pic_context_Copy(
struct picture_context_t *ctx )
{
struct gst_mem_pic_context *gst_mem_ctx = container_of( ctx,
struct gst_mem_pic_context, s );
struct gst_mem_pic_context *gst_mem_ctx_copy = calloc( 1,
sizeof( *gst_mem_ctx_copy ) );
if( unlikely( gst_mem_ctx_copy == NULL ) )
return NULL;
*gst_mem_ctx_copy = *gst_mem_ctx;
vlc_video_context_Hold( gst_mem_ctx_copy->s.vctx );
gst_buffer_ref( gst_mem_ctx_copy->p_buf );
return &gst_mem_ctx_copy->s;
}
void gst_vlc_dec_ensure_empty_queue( decoder_t *p_dec )
{
decoder_sys_t *p_sys = p_dec->p_sys;
......@@ -148,6 +183,35 @@ static gboolean seek_data_cb( GstAppSrc *p_src, guint64 l_offset,
return TRUE;
}
/* Emitted by decodebin when an autoplugged element not yet
* downstream-linked does a query.
* Used here for format and allocator negotiation. */
static gboolean autoplug_query_cb( GstElement *p_bin, GstPad *p_pad,
GstElement *p_element, GstQuery *p_query,
gpointer p_data )
{
VLC_UNUSED( p_bin );
decoder_t *p_dec = p_data;
decoder_sys_t *p_sys = p_dec->p_sys;
if( ( p_pad->direction == GST_PAD_SRC ) &&
GST_IS_VIDEO_DECODER( p_element ) )
{
switch( GST_QUERY_TYPE ( p_query ) ){
case GST_QUERY_CAPS:
return gst_vlc_video_sink_query_caps( p_query );
case GST_QUERY_ALLOCATION:
GstBaseSink *p_bsink = GST_BASE_SINK_CAST( p_sys->p_decode_out );
GstBaseSinkClass *p_bclass = GST_BASE_SINK_GET_CLASS( p_bsink );
return p_bclass->propose_allocation( p_bsink, p_query );
default:
return FALSE;
}
}
return FALSE;
}
/* Emitted by decodebin and links decodebin to vlcvideosink.
* Since only one elementary codec stream is fed to decodebin,
* this signal cannot be emitted more than once. */
......@@ -215,39 +279,6 @@ static void frame_handoff_cb( GstElement *p_ele, GstBuffer *p_buf,
gst_atomic_queue_push( p_sys->p_que, gst_buffer_ref( p_buf ) );
}
/* Copy the frame data from the GstBuffer (from decoder)
* to the picture obtained from downstream in VLC.
* This function should be avoided as much
* as possible, since it involves a complete frame copy. */
static void gst_CopyPicture( picture_t *p_pic, GstVideoFrame *p_frame )
{
int i_plane, i_planes, i_line, i_dst_stride, i_src_stride;
uint8_t *p_dst, *p_src;
int i_w, i_h;
i_planes = p_pic->i_planes;
for( i_plane = 0; i_plane < i_planes; i_plane++ )
{
p_dst = p_pic->p[i_plane].p_pixels;
p_src = GST_VIDEO_FRAME_PLANE_DATA( p_frame, i_plane );
i_dst_stride = p_pic->p[i_plane].i_pitch;
i_src_stride = GST_VIDEO_FRAME_PLANE_STRIDE( p_frame, i_plane );
i_w = GST_VIDEO_FRAME_COMP_WIDTH( p_frame,
i_plane ) * GST_VIDEO_FRAME_COMP_PSTRIDE( p_frame, i_plane );
i_h = GST_VIDEO_FRAME_COMP_HEIGHT( p_frame, i_plane );
for( i_line = 0;
i_line < __MIN( p_pic->p[i_plane].i_lines, i_h );
i_line++ )
{
memcpy( p_dst, p_src, i_w );
p_src += i_src_stride;
p_dst += i_dst_stride;
}
}
}
/* Check if the element can use this caps */
static gint find_decoder_func( gconstpointer p_p1, gconstpointer p_p2 )
{
......@@ -564,6 +595,8 @@ static int OpenDecoder( vlc_object_t *p_this )
g_signal_connect( G_OBJECT( p_sys->p_decode_in ), "pad-added",
G_CALLBACK( pad_added_cb ), p_dec );
g_signal_connect( G_OBJECT( p_sys->p_decode_in ), "autoplug-query",
G_CALLBACK( autoplug_query_cb ), p_dec );
}
/* videosink: will emit signal for every available buffer */
......@@ -623,6 +656,20 @@ static int OpenDecoder( vlc_object_t *p_this )
p_dec->pf_decode = DecodeBlock;
p_dec->pf_flush = Flush;
vlc_decoder_device *dec_device = decoder_GetDecoderDevice( p_dec );
if( dec_device == NULL )
{
msg_Err( p_dec, "failed to get a decoder device" );
goto fail;
}
p_sys->vctx = vlc_video_context_Create( dec_device, VLC_VIDEO_CONTEXT_GSTDECODE, 0, NULL );
vlc_decoder_device_Release( dec_device );
if( unlikely( p_sys->vctx == NULL ) )
{
msg_Err( p_dec, "failed to create a video context" );
goto fail;
}
return VLC_SUCCESS;
fail:
......@@ -775,22 +822,84 @@ static int DecodeBlock( decoder_t *p_dec, block_t *p_block )
GstBuffer *p_buf = GST_BUFFER_CAST(
gst_atomic_queue_pop( p_sys->p_que ));
GstMemory *p_mem;
p_mem = gst_buffer_peek_memory( p_buf, 0 );
if(( p_mem = gst_buffer_peek_memory( p_buf, 0 )) &&
bool b_copy_picture = true;
if( p_mem &&
GST_IS_VLC_PICTURE_PLANE_ALLOCATOR( p_mem->allocator ))
{
b_copy_picture = false;
p_pic = picture_Hold(( (GstVlcPicturePlane*) p_mem )->p_pic );
}
else
else if( p_mem && gst_is_dmabuf_memory(p_mem) )
{
b_copy_picture = false;
switch( p_dec->fmt_out.video.i_chroma ) {
case VLC_CODEC_NV12:
p_dec->fmt_out.video.i_chroma = p_dec->fmt_out.i_codec =
VLC_CODEC_GST_MEM_OPAQUE;
break;
case VLC_CODEC_GST_MEM_OPAQUE:
break;
/* fallback */
default:
b_copy_picture = true;
}
if( !b_copy_picture )
{
/* Get a new picture */
if( decoder_UpdateVideoOutput( p_dec, p_sys->vctx ) )
{
gst_buffer_unref( p_buf );
goto done;
}
p_pic = decoder_NewPicture( p_dec );
if( !p_pic )
{
gst_buffer_unref( p_buf );
goto done;
}
struct gst_mem_pic_context *pctx = calloc( 1, sizeof( *pctx ) );
if( unlikely( pctx == NULL ) )
{
gst_buffer_unref( p_buf );
return VLCDEC_ECRITICAL;
}
pctx->s = ( picture_context_t ) {
gst_mem_pic_context_Destroy, gst_mem_pic_context_Copy,
p_sys->vctx,
};
vlc_video_context_Hold( pctx->s.vctx );
pctx->p_buf = p_buf;
gst_buffer_ref( p_buf );
pctx->p_vinfo = &p_sys->vinfo;
p_pic->context = &pctx->s;
}
}
if( b_copy_picture )
{
GstVideoFrame frame;
/* Get a new picture */
if( decoder_UpdateVideoFormat( p_dec ) )
{
gst_buffer_unref( p_buf );
goto done;
}
p_pic = decoder_NewPicture( p_dec );
if( !p_pic )
{
gst_buffer_unref( p_buf );
goto done;
}
if( unlikely( !gst_video_frame_map( &frame,
&p_sys->vinfo, p_buf, GST_MAP_READ ) ) )
......@@ -804,6 +913,10 @@ static int DecodeBlock( decoder_t *p_dec, block_t *p_block )
gst_video_frame_unmap( &frame );
}
if( p_pic != NULL )
p_pic->b_progressive = ( p_sys->vinfo.interlace_mode ==
GST_VIDEO_INTERLACE_MODE_PROGRESSIVE );
if( likely( GST_BUFFER_PTS_IS_VALID( p_buf ) ) )
p_pic->date = gst_util_uint64_scale(
GST_BUFFER_PTS( p_buf ), GST_MSECOND, GST_SECOND );
......@@ -892,5 +1005,22 @@ static void CloseDecoder( vlc_object_t *p_this )
if( p_sys->p_decoder )
gst_object_unref( p_sys->p_decoder );
if( p_sys->vctx )
vlc_video_context_Release( p_sys->vctx );
free( p_sys );
}
static const struct vlc_decoder_device_operations gstdecode_device_ops = {
.close = NULL,
};
static int OpenDecoderDevice(vlc_decoder_device *device, vlc_window_t *window)
{
VLC_UNUSED(window);
device->ops = &gstdecode_device_ops;
device->type = VLC_DECODER_DEVICE_GSTDECODE;
return VLC_SUCCESS;
}
......@@ -132,7 +132,7 @@ static GstMemory* gst_vlc_picture_plane_copy(
return NULL;
}
static vlc_fourcc_t gst_vlc_to_map_format( const char* psz_fourcc )
vlc_fourcc_t gst_vlc_to_map_format( const char* psz_fourcc )
{
if( !psz_fourcc )
return VLC_CODEC_UNKNOWN;
......
......@@ -79,6 +79,7 @@ bool gst_vlc_picture_plane_allocator_query_format(
GstVideoAlignment *p_align, GstCaps *p_caps );
bool gst_vlc_set_vout_fmt( GstVideoInfo *p_info, GstVideoAlignment *p_align,
GstCaps *p_caps, decoder_t *p_dec );
vlc_fourcc_t gst_vlc_to_map_format( const char* psz_fourcc );
void gst_vlc_dec_ensure_empty_queue( decoder_t* p_dec );
bool gst_vlc_picture_plane_allocator_hold( GstVlcPicturePlaneAllocator
*p_allocator, GstBuffer *p_buffer );
......
......@@ -25,6 +25,7 @@
*****************************************************************************/
#include "gstvlcvideopool.h"
#include "gstvlcvideosink.h"
#include "gstvlcpictureplaneallocator.h"
#include <vlc_common.h>
......@@ -57,7 +58,9 @@ static GstStaticPadTemplate sink_template =
static gboolean gst_vlc_video_sink_setcaps( GstBaseSink *p_bsink,
GstCaps *p_caps );
static gboolean gst_vlc_video_sink_propose_allocation( GstBaseSink *p_bsink,
GstQuery *p_query);
GstQuery *p_query );
static gboolean gst_vlc_video_sink_query( GstBaseSink *p_bsink,
GstQuery *p_query );
static GstFlowReturn gst_vlc_video_sink_chain( GstBaseSink *p_vsink,
GstBuffer *p_buffer );
......@@ -127,6 +130,8 @@ static void gst_vlc_video_sink_class_init( GstVlcVideoSinkClass *p_klass )
p_gstbasesink_class->propose_allocation =
gst_vlc_video_sink_propose_allocation;
p_gstbasesink_class->query = gst_vlc_video_sink_query;
p_gstbasesink_class->render = gst_vlc_video_sink_chain;
}
......@@ -262,6 +267,52 @@ invalid_caps:
}
}
gboolean gst_vlc_video_sink_query_caps( GstQuery *p_query )
{
GstCaps *p_query_caps;
gst_query_parse_caps( p_query, &p_query_caps );
if( p_query_caps == NULL )
return FALSE;
/* gst_caps_normalize takes ownership of the cap */
gst_caps_ref( p_query_caps );
GstCaps *p_normalized = gst_caps_normalize( p_query_caps );
p_normalized = gst_caps_make_writable( p_normalized );
guint i = 0;
while( i < gst_caps_get_size( p_normalized ) )
{
GstStructure *p_str = gst_caps_get_structure( p_normalized, i );
const char* psz_fourcc = gst_structure_get_string( p_str, "format" );
if( ( psz_fourcc != NULL ) && gst_vlc_to_map_format( psz_fourcc ) ==
VLC_CODEC_UNKNOWN )
{
gst_caps_remove_structure( p_normalized, i );
}
else
{
i++;
}
}
gst_query_set_caps_result( p_query, p_normalized );
return TRUE;
}
static gboolean gst_vlc_video_sink_query( GstBaseSink *p_bsink,
GstQuery *p_query )
{
if( GST_QUERY_TYPE( p_query ) == GST_QUERY_CAPS )
{
return gst_vlc_video_sink_query_caps( p_query );
}
return GST_BASE_SINK_CLASS( parent_class )->query( p_bsink, p_query );
}
static GstFlowReturn gst_vlc_video_sink_chain( GstBaseSink *p_bsink,
GstBuffer *p_buffer )
{
......
......@@ -81,4 +81,6 @@ struct _GstVlcVideoSinkClass
GType gst_vlc_video_sink_get_type (void);
gboolean gst_vlc_video_sink_query_caps( GstQuery *p_query );
#endif /* __GST_VLC_VIDEO_SINK_H__ */
......@@ -89,6 +89,15 @@ if HAVE_DARWIN
chroma_LTLIBRARIES += libcvpx_plugin.la
endif
libgst_mem_plugin_la_SOURCES = video_chroma/gst_mem.c \
codec/gstreamer/gstcopypicture.c codec/gstreamer/gstcopypicture.h codec/gstreamer/gst_mem.h
libgst_mem_plugin_la_CFLAGS = $(AM_CFLAGS) $(GST_VIDEO_CFLAGS) $(GST_APP_CFLAGS)
libgst_mem_plugin_la_LIBADD = $(GST_VIDEO_LIBS) $(GST_APP_LIBS)
if HAVE_GST_DECODE
chroma_LTLIBRARIES += libgst_mem_plugin.la
endif
# Tests
chroma_copy_sse_test_SOURCES = $(libchroma_copy_la_SOURCES)
chroma_copy_sse_test_CFLAGS = -DCOPY_TEST
......
/*****************************************************************************
* gst_mem.c: GStreamer Memory to picture converter
*****************************************************************************
* Copyright (C) 2022 VLC authors and VideoLAN
*
* Author: Yann Lochet <yann@l0chet.fr>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <gst/gst.h>
#include <gst/video/video.h>
#include <gst/video/video-format.h>
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_filter.h>
#include <vlc_picture.h>
#include "../codec/gstreamer/gstcopypicture.h"
#include "../codec/gstreamer/gst_mem.h"
static picture_t * Filter(filter_t *p_filter, picture_t *src)
{
struct gst_mem_pic_context *pctx = container_of(src->context,
struct gst_mem_pic_context, s);
GstBuffer *p_buf = pctx->p_buf;
picture_t *dst = filter_NewPicture(p_filter);
if (!dst)
return NULL;
picture_CopyProperties(dst, src);
GstVideoFrame frame;
if (unlikely(!gst_video_frame_map(&frame, pctx->p_vinfo, p_buf, GST_MAP_READ)))
{
msg_Err(p_filter, "failed to map gst video frame");
return NULL;
}
gst_CopyPicture(dst, &frame);
gst_video_frame_unmap(&frame);
picture_Release(src);
return dst;
}
static picture_t * Filter_chain( filter_t *p_filter, picture_t *src )
{
filter_chain_t *p_chain = p_filter->p_sys;
return filter_chain_VideoFilter(p_chain, src);
}
static const struct vlc_filter_operations filter_ops = {
.filter_video = Filter,
};
static const struct vlc_filter_operations chain_ops = {
.filter_video = Filter_chain,
};
static int Open(filter_t *p_filter)
{
if(p_filter->fmt_in.video.i_chroma != VLC_CODEC_GST_MEM_OPAQUE)
return VLC_EGENERIC;
if(p_filter->fmt_out.video.i_chroma == VLC_CODEC_NV12)
{
p_filter->ops = &filter_ops;
return VLC_SUCCESS;
}
es_format_t fmt_intermediate;
es_format_Copy(&fmt_intermediate, &p_filter->fmt_out);
fmt_intermediate.video.i_chroma = fmt_intermediate.i_codec = VLC_CODEC_NV12;
filter_chain_t *p_chain = filter_chain_NewVideo(p_filter, false, &p_filter->owner);
if (p_chain == NULL)
return VLC_ENOMEM;
filter_chain_Reset(p_chain, &p_filter->fmt_in, p_filter->vctx_in, &p_filter->fmt_out);
int ret;
ret = filter_chain_AppendConverter(p_chain, &fmt_intermediate);
if (ret != 0)
return VLC_EGENERIC;
ret = filter_chain_AppendConverter(p_chain, NULL);
if (ret != 0)
return VLC_EGENERIC;
p_filter->p_sys = p_chain;
p_filter->ops = &chain_ops;
return VLC_SUCCESS;
}
vlc_module_begin()
set_shortname(N_("GST_MEM converter"))
set_description(N_("GST_MEM Chroma Converter filter"))
set_subcategory(SUBCAT_VIDEO_VFILTER)
set_callback_video_converter(Open, 10)
vlc_module_end()
......@@ -119,6 +119,12 @@ vout_LTLIBRARIES += \
libcaeagl_ios_plugin.la
endif
libglinterop_gst_mem_plugin_la_SOURCES = video_output/opengl/interop_gst_mem.c \
video_output/opengl/interop.h codec/gstreamer/gst_mem.h
libglinterop_gst_mem_plugin_la_CFLAGS = $(AM_CFLAGS) $(GL_CFLAGS) $(GST_VIDEO_CFLAGS) \
$(GST_APP_CFLAGS)
libglinterop_gst_mem_plugin_la_LIBADD = $(GST_VIDEO_LIBS) $(GST_APP_LIBS)
libglinterop_vaapi_plugin_la_SOURCES = video_output/opengl/interop_vaapi.c \
video_output/opengl/interop.h \
hw/vaapi/vlc_vaapi.c hw/vaapi/vlc_vaapi.h
......@@ -135,6 +141,10 @@ if HAVE_EGL
if HAVE_VAAPI
vout_LTLIBRARIES += libglinterop_vaapi_plugin.la
endif
if HAVE_GST_DECODE
vout_LTLIBRARIES += libglinterop_gst_mem_plugin.la
endif
endif # HAVE_EGL
if HAVE_VDPAU
......
/*****************************************************************************
* interop_gst_mem.c: OpenGL GStreamer Memory opaque converter
*****************************************************************************
* Copyright (C) 2022 VLC authors and VideoLAN
*
* Author: Yann Lochet <yann@l0chet.fr>
* Heavily inspired by interop_vaapi.c
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <gst/gst.h>
#include <gst/video/video.h>
#include <gst/video/video-format.h>
#include <gst/allocators/gstdmabuf.h>
#include <vlc_common.h>
#include <vlc_window.h>
#include <vlc_codec.h>
#include <vlc_plugin.h>
#include "gl_util.h"
#include "interop.h"
#include "../../codec/gstreamer/gst_mem.h"
#define DRM_FORMAT_MOD_LINEAR 0ULL
struct priv
{
PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES;
struct
{
EGLDisplay display;
EGLDisplay (*getCurrentDisplay)();
const char *(*queryString)(EGLDisplay, EGLint);
EGLImage (*createImageKHR)(EGLDisplay, EGLContext, EGLenum target, EGLClientBuffer buffer,
const EGLint *attrib_list);
void (*destroyImageKHR)(EGLDisplay, EGLImage image);
} egl;
struct
{
PFNGLBINDTEXTUREPROC BindTexture;
} gl;
EGLint drm_fourccs[3];
};
static void
egl_image_destroy(const struct vlc_gl_interop *interop, EGLImageKHR image)
{
struct priv *priv = interop->priv;
priv->egl.destroyImageKHR(priv->egl.display, image);
}
static int
egl_update(const struct vlc_gl_interop *interop, uint32_t textures[],
const int32_t tex_width[], const int32_t tex_height[],
picture_t *pic, const size_t *plane_offset)
{
(void) plane_offset;
struct priv *priv = interop->priv;
struct gst_mem_pic_context *pctx = container_of( pic->context,
struct gst_mem_pic_context, s );
GstBuffer *p_buf = pctx->p_buf;
GstVideoMeta *p_meta = gst_buffer_get_video_meta(p_buf);
GstMemory *p_mem = gst_buffer_peek_memory(p_buf, 0);
int dmabuf_fd = gst_dmabuf_memory_get_fd(p_mem);
int egl_color_space;
switch (interop->fmt_in.space)
{
case COLOR_SPACE_BT601:
egl_color_space = EGL_ITU_REC601_EXT;
break;
case COLOR_SPACE_BT709:
egl_color_space = EGL_ITU_REC709_EXT;
break;
case COLOR_SPACE_BT2020:
egl_color_space = EGL_ITU_REC2020_EXT;
break;
default:
goto error;
}
int egl_color_range;
switch (interop->fmt_in.color_range)
{
case COLOR_RANGE_FULL:
egl_color_range = EGL_YUV_FULL_RANGE_EXT;
break;
case COLOR_RANGE_LIMITED:
egl_color_range = EGL_YUV_NARROW_RANGE_EXT;
break;
default:
vlc_assert_unreachable();
}
const EGLint attribs[] = {
EGL_WIDTH, tex_width[0],
EGL_HEIGHT, tex_height[0],
EGL_LINUX_DRM_FOURCC_EXT, priv->drm_fourccs[0],
EGL_DMA_BUF_PLANE0_FD_EXT, dmabuf_fd,
EGL_DMA_BUF_PLANE0_OFFSET_EXT, p_meta->offset[0],
EGL_DMA_BUF_PLANE0_PITCH_EXT, p_meta->stride[0],
EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT, DRM_FORMAT_MOD_LINEAR & 0xffffffff,
EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT, (DRM_FORMAT_MOD_LINEAR >> 32) & 0xffffffff,
EGL_DMA_BUF_PLANE1_FD_EXT, dmabuf_fd,
EGL_DMA_BUF_PLANE1_OFFSET_EXT, p_meta->offset[1],
EGL_DMA_BUF_PLANE1_PITCH_EXT, p_meta->stride[1],
EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT, DRM_FORMAT_MOD_LINEAR & 0xffffffff,
EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT, (DRM_FORMAT_MOD_LINEAR >> 32) & 0xffffffff,
EGL_YUV_COLOR_SPACE_HINT_EXT, egl_color_space,
EGL_SAMPLE_RANGE_HINT_EXT, egl_color_range,
EGL_NONE
};
EGLImageKHR egl_image = priv->egl.createImageKHR(priv->egl.display, EGL_NO_CONTEXT,
EGL_LINUX_DMA_BUF_EXT, NULL,
attribs);
if( egl_image == NULL )
goto error;
priv->gl.BindTexture(interop->tex_target, textures[0]);
priv->glEGLImageTargetTexture2DOES(interop->tex_target, egl_image);
egl_image_destroy(interop, egl_image);
return VLC_SUCCESS;
error:
return VLC_EGENERIC;
}
static void
Close(struct vlc_gl_interop *interop)
{
struct priv *priv = interop->priv;
free(priv);
}
static int
Open(vlc_object_t *obj)
{
struct vlc_gl_interop *interop = (void *) obj;
struct priv *priv = NULL;
if (interop->vctx == NULL)
return VLC_EGENERIC;
vlc_decoder_device *dec_device = vlc_video_context_HoldDevice(interop->vctx);
if (dec_device->type != VLC_DECODER_DEVICE_GSTDECODE)
goto error;
priv = interop->priv = calloc(1, sizeof(struct priv));
if (unlikely(priv == NULL))
goto error;
switch (interop->fmt_in.i_chroma)
{
case VLC_CODEC_GST_MEM_OPAQUE:
interop->tex_count = 1;
interop->texs[0] = (struct vlc_gl_tex_cfg) {
.w = {1, 1},
.h = {1, 1},
.internal = GL_RGBA,
.format = GL_RGBA,
.type = GL_UNSIGNED_BYTE,
};
priv->drm_fourccs[0] = VLC_FOURCC('N', 'V', '1', '2');
break;
default:
goto error;
}
struct vlc_gl_extension_vt extension_vt;
vlc_gl_LoadExtensionFunctions(interop->gl, &extension_vt);
/* GL_OES_EGL_image_external is required for GL_TEXTURE_EXTERNAL_OES */
if (!vlc_gl_HasExtension(&extension_vt, "GL_OES_EGL_image_external"))
goto error;
priv->egl.getCurrentDisplay = vlc_gl_GetProcAddress(interop->gl, "eglGetCurrentDisplay");
if (priv->egl.getCurrentDisplay == EGL_NO_DISPLAY)
goto error;
priv->egl.display = priv->egl.getCurrentDisplay();
if (priv->egl.display == EGL_NO_DISPLAY)
goto error;
priv->egl.queryString = vlc_gl_GetProcAddress(interop->gl, "eglQueryString");
if (priv->egl.queryString == NULL)
goto error;
/* EGL_EXT_image_dma_buf_import implies EGL_KHR_image_base */
const char *eglexts = priv->egl.queryString(priv->egl.display, EGL_EXTENSIONS);
if (eglexts == NULL || !vlc_gl_StrHasToken(eglexts, "EGL_EXT_image_dma_buf_import"))
goto error;
priv->egl.createImageKHR =
vlc_gl_GetProcAddress(interop->gl, "eglCreateImageKHR");
if (priv->egl.createImageKHR == NULL)
goto error;
priv->egl.destroyImageKHR =
vlc_gl_GetProcAddress(interop->gl, "eglDestroyImageKHR");
if (priv->egl.destroyImageKHR == NULL)
goto error;
priv->glEGLImageTargetTexture2DOES =
vlc_gl_GetProcAddress(interop->gl, "glEGLImageTargetTexture2DOES");
if (priv->glEGLImageTargetTexture2DOES == NULL)
goto error;
priv->gl.BindTexture =
vlc_gl_GetProcAddress(interop->gl, "glBindTexture");
if (priv->gl.BindTexture == NULL)
goto error;
/* The pictures are uploaded upside-down */
video_format_TransformBy(&interop->fmt_out, TRANSFORM_VFLIP);
interop->tex_target = GL_TEXTURE_EXTERNAL_OES;
interop->fmt_out.i_chroma = VLC_CODEC_RGB32;
interop->fmt_out.space = COLOR_SPACE_UNDEF;
static const struct vlc_gl_interop_ops ops = {
.update_textures = egl_update,
.close = Close,
};
interop->ops = &ops;
vlc_decoder_device_Release(dec_device);
return VLC_SUCCESS;
error:
vlc_decoder_device_Release(dec_device);
free(priv);
return VLC_EGENERIC;
}
vlc_module_begin ()
set_description("GST_MEM OpenGL surface converter")
set_capability("glinterop", 1)
set_callback(Open)
set_subcategory(SUBCAT_VIDEO_VOUT)
add_shortcut("gst_mem")
vlc_module_end ()
......@@ -835,6 +835,8 @@ static const struct
{ { VLC_CODEC_CVPX_P010, 0 }, FAKE_FMT() },
{ { VLC_CODEC_GST_MEM_OPAQUE, 0 }, FAKE_FMT() },
{ { VLC_CODEC_VAAPI_420, VLC_CODEC_VAAPI_420_10BPP },
FAKE_FMT() },
......