commit 8bb6d4027c42002701cbd2927c89d134b77baede Author: Toshaan Bharvani Date: Sun Oct 9 01:26:11 2022 +0200 initial package creation Signed-off-by: Toshaan Bharvani diff --git a/SOURCES/LICENSE b/SOURCES/LICENSE new file mode 100644 index 0000000..f0dfa3e --- /dev/null +++ b/SOURCES/LICENSE @@ -0,0 +1,14 @@ +Legal Disclaimer +The Crystal HD video decoder open source software is provided under the GNU Lesser General Public License, version 2.1, as published by the Free Software Foundation ("LGPL"). This software is distributed in the hope that it will be useful, but WITHOUT ANY SUPPORT OR WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the LGPL for more details. A copy of the LGPL is available at http://www.broadcom.com/licenses/LGPLv2.1.php or by writing to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +The BCM70015 and BCM70012 device firmware (binary files bcm70015fw.bin and bcm70012fw.bin) is distributed under the following terms: + +Copyright 2007-2010 Broadcom Corporation. + +Redistribution and use in binary forms of this software, without modification, are permitted provided that the following conditions are met: + +* Redistributions must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +* Neither the name of Broadcom nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/SOURCES/README_07032010 b/SOURCES/README_07032010 new file mode 100644 index 0000000..9d6675e --- /dev/null +++ b/SOURCES/README_07032010 @@ -0,0 +1,65 @@ +Broadcom CrystalHD Linux Software Release 07032010 + +This is beta release of the Linux driver and application software with support for the BCM70012 and BCM70015 + +This is a pure source release with no distribution binary packages + +FEATURES SUPPORTED - + +Playback support for H.264 and other codecs using the default media players for Ubuntu and Meego. This includes support for GStreamer based applications. + +Support both BCM70012 and BCM70015 + +FIXED ISSUES +Kernel oops during driver load +64-bit support +Power management +HW scaling + +KNOWN ISSUES + +Seeking hangs the player +Playlist functionality does not work correctly +VC-1 not functional + +BUILD and INSTALL instructions + +Required packages - + +Under Ubuntu the following additional packages are required, install them using "sudo apt-get " + +build-essential +g++ +automake +autoconf +libtool +libgstreamer0.10-dev +libgstreamer-plugins-base0.10-dev + +In order to build and install the driver - + +In the driver/linux folder, run the following commands - + +autoconf +./configure +make +sudo make install + +In order to build and install the library - + +In the linux_lib/libcrystalhd folder, run the following commands - + +make +sudo make install + +In order to build and install the media player application library (gstreamer plugin) - + +In the filters/gst/gst-plugin/, run the following commands - + +./autogen.sh +make +sudo make install + +Finally copy the firmware files from firmware/fwbin/70015 and firmware/fwbin/70012 directories to /lib/firmware + +If HW scaling is necessary - in libcrystalhd_if.cpp in line 1240 uncomment the Ctx->EnableScaling line diff --git a/SOURCES/bcm70012fw.bin b/SOURCES/bcm70012fw.bin new file mode 100644 index 0000000..80a1f87 Binary files /dev/null and b/SOURCES/bcm70012fw.bin differ diff --git a/SOURCES/bcm70015fw.bin b/SOURCES/bcm70015fw.bin new file mode 100644 index 0000000..48b03b2 Binary files /dev/null and b/SOURCES/bcm70015fw.bin differ diff --git a/SOURCES/crystalhd-gst-Port-to-GStreamer-1.0-API.patch b/SOURCES/crystalhd-gst-Port-to-GStreamer-1.0-API.patch new file mode 100644 index 0000000..f5ef218 --- /dev/null +++ b/SOURCES/crystalhd-gst-Port-to-GStreamer-1.0-API.patch @@ -0,0 +1,1087 @@ +diff --git a/filters/gst/gst-plugin/configure.ac b/filters/gst/gst-plugin/configure.ac +index 99b3713..a3c6467 100644 +--- a/filters/gst/gst-plugin/configure.ac ++++ b/filters/gst/gst-plugin/configure.ac +@@ -1,9 +1,9 @@ + AC_INIT + + dnl versions of gstreamer and plugins-base +-GST_MAJORMINOR=0.10 +-GST_REQUIRED=0.10.0 +-GSTPB_REQUIRED=0.10.0 ++GST_MAJORMINOR=1.0 ++GST_REQUIRED=1.0 ++GSTPB_REQUIRED=1.0 + + dnl fill in your package name and version here + dnl the fourth (nano) number should be 0 for a release, 1 for CVS, +@@ -56,7 +56,7 @@ dnl And we can also ask for the right version of gstreamer + + PKG_CHECK_MODULES(GST, \ + gstreamer-$GST_MAJORMINOR >= $GST_REQUIRED +- gstreamer-video-0.10, ++ gstreamer-video-1.0, + HAVE_GST=yes,HAVE_GST=no) + + dnl Give error and exit if we don't have gstreamer +diff --git a/filters/gst/gst-plugin/src/gstbcmdec.c b/filters/gst/gst-plugin/src/gstbcmdec.c +index ed01c14..a51bd59 100644 +--- a/filters/gst/gst-plugin/src/gstbcmdec.c ++++ b/filters/gst/gst-plugin/src/gstbcmdec.c +@@ -8,6 +8,7 @@ + * AU + * + * HISTORY: ++ * Updated for 1.0 by Guido Guenther + * + ******************************************************************* + * +@@ -40,6 +41,7 @@ + #include + #include + #include ++#include + + #ifdef HAVE_CONFIG_H + #include +@@ -51,8 +53,8 @@ + #include "parse.h" + #include "gstbcmdec.h" + +-GST_DEBUG_CATEGORY_STATIC (gst_bcmdec_debug); +-#define GST_CAT_DEFAULT gst_bcmdec_debug ++GST_DEBUG_CATEGORY_STATIC (gst_bcm_dec_debug); ++#define GST_CAT_DEFAULT gst_bcm_dec_debug + + //#define YV12__ + +@@ -64,16 +66,18 @@ static GstFlowReturn bcmdec_send_buff_detect_error(GstBcmDec *bcmdec, GstBuffer + guint8 flags) + { + BC_STATUS sts = BC_STS_SUCCESS; ++ GstMapInfo info; + + GST_DEBUG_OBJECT(bcmdec, "Attempting to Send Buffer"); + + sts = decif_send_buffer(&bcmdec->decif, pbuffer, size, tCurrent, flags); + + if (sts != BC_STS_SUCCESS) { ++ gst_buffer_map(buf, &info, GST_MAP_READ); + GST_ERROR_OBJECT(bcmdec, "proc input failed sts = %d", sts); + GST_ERROR_OBJECT(bcmdec, "Chain: timeStamp = %llu size = %d data = %p", +- GST_BUFFER_TIMESTAMP(buf), GST_BUFFER_SIZE(buf), +- GST_BUFFER_DATA (buf)); ++ GST_BUFFER_DTS(buf), info.size, info.data); ++ gst_buffer_unmap(buf, &info); + return GST_FLOW_ERROR; + } + +@@ -92,7 +96,7 @@ enum { + }; + + +-GLB_INST_STS *g_inst_sts = NULL; ++static GLB_INST_STS *g_inst_sts = NULL; + + /* + * the capabilities of the inputs and outputs. +@@ -111,35 +115,29 @@ GstStaticPadTemplate sink_factory_bcm70012 = GST_STATIC_PAD_TEMPLATE("sink", GST + + #ifdef YV12__ + static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE("src", GST_PAD_SRC, GST_PAD_ALWAYS, +- GST_STATIC_CAPS("video/x-raw-yuv, " "format = (fourcc) { YV12 }, " "width = (int) [ 1, MAX ], " ++ GST_STATIC_CAPS("video/x-raw, " "format = (string) { YV12 }, " "width = (int) [ 1, MAX ], " + "height = (int) [ 1, MAX ], " "framerate = (fraction) [ 0/1, 2147483647/1 ]")); + #define BUF_MULT (12 / 8) + #define BUF_MODE MODE420 + #else + static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE("src", GST_PAD_SRC, GST_PAD_ALWAYS, +- GST_STATIC_CAPS("video/x-raw-yuv, " "format = (fourcc) { YUY2 } , " "framerate = (fraction) [0,MAX], " +- "width = (int) [1,MAX], " "height = (int) [1,MAX]; " "video/x-raw-yuv, " +- "format = (fourcc) { UYVY } , " "framerate = (fraction) [0,MAX], " "width = (int) [1,MAX], " ++ GST_STATIC_CAPS("video/x-raw, " "format = (string) { YUY2 } , " "framerate = (fraction) [0,MAX], " ++ "width = (int) [1,MAX], " "height = (int) [1,MAX]; " "video/x-raw, " ++ "format = (string) { UYVY } , " "framerate = (fraction) [0,MAX], " "width = (int) [1,MAX], " + "height = (int) [1,MAX]; ")); + #define BUF_MULT (16 / 8) + #define BUF_MODE MODE422_YUY2 + #endif + +-GST_BOILERPLATE(GstBcmDec, gst_bcmdec, GstElement, GST_TYPE_ELEMENT); ++G_DEFINE_TYPE(GstBcmDec, gst_bcm_dec, GST_TYPE_ELEMENT); + + /* GObject vmethod implementations */ + +-static void gst_bcmdec_base_init(gpointer gclass) ++static void gst_bcm_dec_base_init(gpointer gclass) + { +- static GstElementDetails element_details; + BC_HW_CAPS hwCaps; + +- GST_DEBUG_OBJECT(gclass, "gst_bcmdec_base_init"); +- +- element_details.klass = (gchar *)"Codec/Decoder/Video"; +- element_details.longname = (gchar *)"Generic Video Decoder"; +- element_details.description = (gchar *)"Decodes various Video Formats using CrystalHD Decoders"; +- element_details.author = (gchar *)"Broadcom Corp."; ++ GST_DEBUG_OBJECT(gclass, "gst_bcm_dec_base_init"); + + GstElementClass *element_class = GST_ELEMENT_CLASS(gclass); + +@@ -153,11 +151,15 @@ static void gst_bcmdec_base_init(gpointer gclass) + } + else + gst_element_class_add_pad_template(element_class, gst_static_pad_template_get (&sink_factory_bcm70012)); +- gst_element_class_set_details(element_class, &element_details); ++ gst_element_class_set_metadata(element_class, ++ "Codec/Decoder/Video", ++ "Generic Video Decoder", ++ "Decodes various Video Formats using CrystalHD Decoders", ++ "Broadcom Corp."); + } + + /* initialize the bcmdec's class */ +-static void gst_bcmdec_class_init(GstBcmDecClass *klass) ++static void gst_bcm_dec_class_init(GstBcmDecClass *klass) + { + GObjectClass *gobject_class; + GstElementClass *gstelement_class; +@@ -165,13 +167,15 @@ static void gst_bcmdec_class_init(GstBcmDecClass *klass) + gobject_class = (GObjectClass *)klass; + gstelement_class = (GstElementClass *)klass; + +- GST_DEBUG_OBJECT(klass, "gst_bcmdec_class_init"); ++ GST_DEBUG_OBJECT(klass, "gst_bcm_dec_class_init"); ++ ++ gst_bcm_dec_base_init(klass); + +- gstelement_class->change_state = gst_bcmdec_change_state; ++ gstelement_class->change_state = gst_bcm_dec_change_state; + +- gobject_class->set_property = gst_bcmdec_set_property; +- gobject_class->get_property = gst_bcmdec_get_property; +- gobject_class->finalize = gst_bcmdec_finalize; ++ gobject_class->set_property = gst_bcm_dec_set_property; ++ gobject_class->get_property = gst_bcm_dec_get_property; ++ gobject_class->finalize = gst_bcm_dec_finalize; + + g_object_class_install_property(gobject_class, PROP_SILENT, + g_param_spec_boolean("silent", "Silent", +@@ -185,14 +189,14 @@ static void gst_bcmdec_class_init(GstBcmDecClass *klass) + * set pad calback functions + * initialize instance structure + */ +-static void gst_bcmdec_init(GstBcmDec *bcmdec, GstBcmDecClass *gclass) ++static void gst_bcm_dec_init(GstBcmDec *bcmdec) + { + pid_t pid; + BC_STATUS sts = BC_STS_SUCCESS; + int shmid = 0; + BC_HW_CAPS hwCaps; + +- GST_DEBUG_OBJECT(bcmdec, "gst_bcmdec_init"); ++ GST_DEBUG_OBJECT(bcmdec, "gst_bcm_dec_init"); + + bcmdec_reset(bcmdec); + +@@ -204,17 +208,16 @@ static void gst_bcmdec_init(GstBcmDec *bcmdec, GstBcmDecClass *gclass) + else + bcmdec->sinkpad = gst_pad_new_from_static_template(&sink_factory_bcm70012, "sink"); + +- gst_pad_set_event_function(bcmdec->sinkpad, GST_DEBUG_FUNCPTR(gst_bcmdec_sink_event)); ++ gst_pad_set_event_function(bcmdec->sinkpad, ++ GST_DEBUG_FUNCPTR(gst_bcm_dec_sink_event)); + +- gst_pad_set_setcaps_function(bcmdec->sinkpad, GST_DEBUG_FUNCPTR(gst_bcmdec_sink_set_caps)); +- gst_pad_set_getcaps_function(bcmdec->sinkpad, GST_DEBUG_FUNCPTR(gst_bcmdec_getcaps)); +- gst_pad_set_chain_function(bcmdec->sinkpad, GST_DEBUG_FUNCPTR(gst_bcmdec_chain)); ++ gst_pad_set_chain_function(bcmdec->sinkpad, ++ GST_DEBUG_FUNCPTR(gst_bcm_dec_chain)); + + bcmdec->srcpad = gst_pad_new_from_static_template (&src_factory, "src"); + +- gst_pad_set_getcaps_function(bcmdec->srcpad, GST_DEBUG_FUNCPTR(gst_bcmdec_getcaps)); +- +- gst_pad_set_event_function(bcmdec->srcpad, GST_DEBUG_FUNCPTR(gst_bcmdec_src_event)); ++ gst_pad_set_event_function(bcmdec->srcpad, ++ GST_DEBUG_FUNCPTR(gst_bcm_dec_src_event)); + + gst_pad_use_fixed_caps(bcmdec->srcpad); + bcmdec_negotiate_format(bcmdec); +@@ -223,7 +226,7 @@ static void gst_bcmdec_init(GstBcmDec *bcmdec, GstBcmDecClass *gclass) + gst_element_add_pad(GST_ELEMENT(bcmdec), bcmdec->srcpad); + bcmdec->silent = FALSE; + pid = getpid(); +- GST_DEBUG_OBJECT(bcmdec, "gst_bcmdec_init _-- PID = %x",pid); ++ GST_DEBUG_OBJECT(bcmdec, "gst_bcm_dec_init _-- PID = %x",pid); + + sts = bcmdec_create_shmem(bcmdec, &shmid); + +@@ -231,25 +234,25 @@ static void gst_bcmdec_init(GstBcmDec *bcmdec, GstBcmDecClass *gclass) + } + + /* plugin close function*/ +-static void gst_bcmdec_finalize(GObject *object) ++static void gst_bcm_dec_finalize(GObject *object) + { +- GstBcmDec *bcmdec = GST_BCMDEC(object); ++ GstBcmDec *bcmdec = GST_BCM_DEC(object); + + bcmdec_del_shmem(bcmdec); +- /*gst_bcmdec_cleanup(bcmdec);*/ +- GST_DEBUG_OBJECT(bcmdec, "gst_bcmdec_finalize"); +- G_OBJECT_CLASS(parent_class)->finalize(object); ++ /*gst_bcm_dec_cleanup(bcmdec);*/ ++ GST_DEBUG_OBJECT(bcmdec, "gst_bcm_dec_finalize"); ++ G_OBJECT_CLASS(gst_bcm_dec_parent_class)->finalize(object); + } + +-static void gst_bcmdec_set_property(GObject *object, guint prop_id, ++static void gst_bcm_dec_set_property(GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) + { +- GstBcmDec *bcmdec = GST_BCMDEC(object); ++ GstBcmDec *bcmdec = GST_BCM_DEC(object); + + switch (prop_id) { + case PROP_SILENT: + bcmdec->silent = g_value_get_boolean (value); +- GST_DEBUG_OBJECT(bcmdec, "gst_bcmdec_set_property PROP_SILENT"); ++ GST_DEBUG_OBJECT(bcmdec, "gst_bcm_dec_set_property PROP_SILENT"); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); +@@ -257,18 +260,18 @@ static void gst_bcmdec_set_property(GObject *object, guint prop_id, + } + + if (!bcmdec->silent) +- GST_DEBUG_OBJECT(bcmdec, "gst_bcmdec_set_property"); ++ GST_DEBUG_OBJECT(bcmdec, "gst_bcm_dec_set_property"); + } + +-static void gst_bcmdec_get_property(GObject *object, guint prop_id, ++static void gst_bcm_dec_get_property(GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) + { +- GstBcmDec *bcmdec = GST_BCMDEC(object); ++ GstBcmDec *bcmdec = GST_BCM_DEC(object); + + switch (prop_id) { + case PROP_SILENT: + g_value_set_boolean (value, bcmdec->silent); +- GST_DEBUG_OBJECT(bcmdec, "gst_bcmdec_get_property PROP_SILENT"); ++ GST_DEBUG_OBJECT(bcmdec, "gst_bcm_dec_get_property PROP_SILENT"); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); +@@ -276,27 +279,33 @@ static void gst_bcmdec_get_property(GObject *object, guint prop_id, + } + + if (!bcmdec->silent) +- GST_DEBUG_OBJECT(bcmdec, "gst_bcmdec_get_property"); ++ GST_DEBUG_OBJECT(bcmdec, "gst_bcm_dec_get_property"); + } + + /* GstElement vmethod implementations */ +-static gboolean gst_bcmdec_sink_event(GstPad* pad, GstEvent* event) ++static gboolean gst_bcm_dec_sink_event(GstPad* pad, ++ GstObject* parent, ++ GstEvent* event) + { + GstBcmDec *bcmdec; + BC_STATUS sts = BC_STS_SUCCESS; +- bcmdec = GST_BCMDEC(gst_pad_get_parent(pad)); ++ bcmdec = GST_BCM_DEC(gst_pad_get_parent(pad)); + + gboolean result = TRUE; + + switch (GST_EVENT_TYPE(event)) { +- case GST_EVENT_NEWSEGMENT: +- GstFormat newsegment_format; +- gint64 newsegment_start; ++ case GST_EVENT_CAPS: ++ GstCaps *caps; ++ gst_event_parse_caps (event, &caps); ++ result = gst_bcm_dec_sink_set_caps (pad, caps); ++ break; ++ ++ case GST_EVENT_SEGMENT: ++ const GstSegment *newsegment; + +- gst_event_parse_new_segment(event, NULL, NULL, &newsegment_format, +- &newsegment_start, NULL, NULL); ++ gst_event_parse_segment(event, &newsegment); + +- bcmdec->base_clock_time = newsegment_start; ++ bcmdec->base_clock_time = newsegment->start; + bcmdec->cur_stream_time = 0; + + if (!bcmdec->silent) +@@ -356,30 +365,24 @@ static gboolean gst_bcmdec_sink_event(GstPad* pad, GstEvent* event) + + gst_object_unref(bcmdec); + if (!bcmdec->silent) +- GST_DEBUG_OBJECT(bcmdec, "gst_bcmdec_sink_event %u", GST_EVENT_TYPE(event)); ++ GST_DEBUG_OBJECT(bcmdec, "gst_bcm_dec_sink_event %u", GST_EVENT_TYPE(event)); + return result; + } + +-static GstCaps *gst_bcmdec_getcaps (GstPad * pad) +-{ +- return gst_caps_copy (gst_pad_get_pad_template_caps (pad)); +-} +- + /* this function handles the link with other elements */ +-static gboolean gst_bcmdec_sink_set_caps(GstPad *pad, GstCaps *caps) ++static gboolean gst_bcm_dec_sink_set_caps(GstPad *pad, GstCaps *caps) + { + GstBcmDec *bcmdec; +- bcmdec = GST_BCMDEC(gst_pad_get_parent(pad)); ++ bcmdec = GST_BCM_DEC(gst_pad_get_parent(pad)); + GstStructure *structure; ++ GstMapInfo info; + GstCaps *intersection; + const gchar *mime; + guint num = 0; + guint den = 0; + const GValue *g_value; + int version = 0; +- GstBuffer *buffer; +- guint8 *data; +- guint size; ++ GstBuffer *buffer = NULL; + guint index; + + GST_DEBUG_OBJECT (pad, "setcaps called"); +@@ -484,53 +487,66 @@ static gboolean gst_bcmdec_sink_set_caps(GstPad *pad, GstCaps *caps) + GST_DEBUG_OBJECT(bcmdec, "InFmt H.264 (AVC1)"); + + buffer = gst_value_get_buffer(g_value); +- data = GST_BUFFER_DATA(buffer); +- size = GST_BUFFER_SIZE(buffer); +- +- GST_DEBUG_OBJECT(bcmdec, "codec_data size = %d", size); ++ if(!gst_buffer_map(buffer, ++ &info, ++ GST_MAP_READ)) ++ goto map_error; ++ GST_DEBUG_OBJECT(bcmdec, ++ "codec_data size = %d", ++ info.size); + + /* parse the avcC data */ +- if (size < 7) { +- GST_ERROR_OBJECT(bcmdec, "avcC size %u < 7", size); +- goto avcc_error; ++ if (info.size < 7) { ++ GST_ERROR_OBJECT(bcmdec, ++ "avcC size %u < 7", ++ info.size); ++ goto out; + } + /* parse the version, this must be 1 */ +- if (data[0] != 1) +- goto wrong_version; ++ if (info.data[0] != 1) { ++ GST_ERROR_OBJECT(bcmdec, "wrong avcC version"); ++ goto out; ++ } + + if (bcmdec->codec_params.sps_pps_buf == NULL) +- bcmdec->codec_params.sps_pps_buf = (guint8 *)malloc(size * 2); +- if (bcmdec_insert_sps_pps(bcmdec, buffer) != BC_STS_SUCCESS) { ++ bcmdec->codec_params.sps_pps_buf = (guint8 *)malloc(info.size * 2); ++ if (bcmdec_insert_sps_pps(bcmdec, &info) != BC_STS_SUCCESS) { + bcmdec->codec_params.pps_size = 0; + } + } else if (!strcmp("video/x-wmv", mime)) { +- buffer = gst_value_get_buffer(g_value); +- data = GST_BUFFER_DATA(buffer); +- size = GST_BUFFER_SIZE(buffer); +- +- GST_DEBUG_OBJECT(bcmdec, "codec_data size = %d", size); +- if (size == 4) { ++ buffer = gst_value_get_buffer(g_value); ++ if(!gst_buffer_map(buffer, ++ &info, ++ GST_MAP_READ)) ++ goto map_error; ++ ++ GST_DEBUG_OBJECT(bcmdec, ++ "codec_data size = %d", ++ info.size); ++ if (info.size == 4) { + // Simple or Main Profile + bcmdec->input_format = BC_MSUBTYPE_WMV3; + GST_DEBUG_OBJECT(bcmdec, "InFmt VC-1 (SP/MP)"); + if (bcmdec->codec_params.sps_pps_buf == NULL) + bcmdec->codec_params.sps_pps_buf = (guint8 *)malloc(4); +- memcpy(bcmdec->codec_params.sps_pps_buf, data, 4); ++ memcpy(bcmdec->codec_params.sps_pps_buf, ++ info.data, 4); + bcmdec->codec_params.pps_size = 4; + } else { + bcmdec->input_format = BC_MSUBTYPE_VC1; + GST_DEBUG_OBJECT(bcmdec, "InFmt VC-1 (AP)"); +- for (index = 0; index < size; index++) { +- data += index; +- if (((size - index) >= 4) && (*data == 0x00) && (*(data + 1) == 0x00) && +- (*(data + 2) == 0x01) && (*(data + 3) == 0x0f)) { ++ for (index = 0; index < info.size; ++ index++) { ++ info.data += index; ++ if (((info.size - index) >= 4) && (*info.data == 0x00) && (*(info.data + 1) == 0x00) && ++ (*(info.data + 2) == 0x01) && (*(info.data + 3) == 0x0f)) { + GST_DEBUG_OBJECT(bcmdec, "VC1 Sequence Header Found for Adv Profile"); + +- if ((size - index + 1) > MAX_ADV_PROF_SEQ_HDR_SZ) ++ if ((info.size - index + 1) > MAX_ADV_PROF_SEQ_HDR_SZ) + bcmdec->codec_params.pps_size = MAX_ADV_PROF_SEQ_HDR_SZ; + else +- bcmdec->codec_params.pps_size = size - index + 1; +- memcpy(bcmdec->codec_params.sps_pps_buf, data, bcmdec->codec_params.pps_size); ++ bcmdec->codec_params.pps_size = info.size - index + 1; ++ memcpy(bcmdec->codec_params.sps_pps_buf, info.data, bcmdec->codec_params.pps_size); + break; + } + } +@@ -546,16 +562,16 @@ static gboolean gst_bcmdec_sink_set_caps(GstPad *pad, GstCaps *caps) + } else { + // No Codec data. So try with FourCC for VC1/WMV9 + if (!strcmp("video/x-wmv", mime)) { +- guint32 fourcc; +- if (gst_structure_get_fourcc (structure, "format", &fourcc)) { +- if ((fourcc == GST_MAKE_FOURCC ('W', 'V', 'C', '1')) || +- (fourcc == GST_MAKE_FOURCC ('W', 'M', 'V', 'A'))) { ++ if (gst_structure_has_field (structure, "format")) { ++ const char* fourcc = gst_structure_get_string(structure, "format"); ++ ++ if (!g_strcmp0(fourcc, "WVC1") || ++ !g_strcmp0(fourcc, "WMVA")) { + bcmdec->input_format = BC_MSUBTYPE_VC1; + GST_DEBUG_OBJECT(bcmdec, "InFmt VC-1 (AP)"); + } else { + GST_DEBUG_OBJECT(bcmdec, "no codec_data. Don't know how to handle"); +- gst_object_unref(bcmdec); +- return FALSE; ++ goto out; + } + } + } +@@ -570,8 +586,7 @@ static gboolean gst_bcmdec_sink_set_caps(GstPad *pad, GstCaps *caps) + } + else { + GST_DEBUG_OBJECT(bcmdec, "no codec_data. Don't know how to handle"); +- gst_object_unref(bcmdec); +- return FALSE; ++ goto out; + } + } + } +@@ -581,54 +596,40 @@ static gboolean gst_bcmdec_sink_set_caps(GstPad *pad, GstCaps *caps) + bcmdec_process_play(bcmdec); + } + ++ gst_buffer_unmap(buffer, &info); + gst_object_unref(bcmdec); + + return TRUE; + + /* ERRORS */ +-avcc_error: +- { +- gst_object_unref(bcmdec); +- return FALSE; +- } +- +-wrong_version: +- { +- GST_ERROR_OBJECT(bcmdec, "wrong avcC version"); +- gst_object_unref(bcmdec); +- return FALSE; +- } +-} +- +-void bcmdec_msleep(gint msec) +-{ +- gint cnt = msec; +- +- while (cnt) { +- usleep(1000); +- cnt--; +- } ++out: ++ if (buffer) ++ gst_buffer_unmap(buffer, &info); ++map_error: ++ gst_object_unref(bcmdec); ++ return FALSE; + } + + /* + * chain function + * this function does the actual processing + */ +-static GstFlowReturn gst_bcmdec_chain(GstPad *pad, GstBuffer *buf) ++static GstFlowReturn gst_bcm_dec_chain(GstPad *pad, ++ GstObject *parent, ++ GstBuffer *buf) + { + GstBcmDec *bcmdec; +-// BC_STATUS sts = BC_STS_SUCCESS; ++ GstMapInfo info; + guint32 offset = 0; + GstClockTime tCurrent = 0; + guint8 *pbuffer; + guint32 size = 0; +-// guint32 vc1_buff_sz = 0; +- ++ GstFlowReturn ret; + + #ifdef FILE_DUMP__ + guint32 bytes_written =0; + #endif +- bcmdec = GST_BCMDEC (GST_OBJECT_PARENT (pad)); ++ bcmdec = GST_BCM_DEC (GST_OBJECT_PARENT (pad)); + + #ifdef FILE_DUMP__ + if (bcmdec->fhnd == NULL) +@@ -637,8 +638,8 @@ static GstFlowReturn gst_bcmdec_chain(GstPad *pad, GstBuffer *buf) + + if (bcmdec->flushing) { + GST_DEBUG_OBJECT(bcmdec, "input while flushing"); +- gst_buffer_unref(buf); +- return GST_FLOW_OK; ++ ret = GST_FLOW_OK; ++ goto out; + } + + if (GST_CLOCK_TIME_NONE != GST_BUFFER_TIMESTAMP(buf)) { +@@ -654,32 +655,44 @@ static GstFlowReturn gst_bcmdec_chain(GstPad *pad, GstBuffer *buf) + bcmdec_process_play(bcmdec); + } else if (!bcmdec->streaming) { + GST_DEBUG_OBJECT(bcmdec, "input while streaming is false"); +- gst_buffer_unref(buf); +- return GST_FLOW_WRONG_STATE; ++ ret = GST_FLOW_FLUSHING; ++ goto out; + } + +- pbuffer = GST_BUFFER_DATA (buf); +- size = GST_BUFFER_SIZE(buf); ++ if (!gst_buffer_map(buf, &info, GST_MAP_READ)) { ++ ret = GST_FLOW_ERROR; ++ goto out; ++ } ++ pbuffer = info.data; ++ size = info.size; + ++ /* FIXME: better send mapinfo? */ + if (GST_FLOW_OK != bcmdec_send_buff_detect_error(bcmdec, buf, pbuffer, size, offset, tCurrent, bcmdec->proc_in_flags)) { +- gst_buffer_unref(buf); +- return GST_FLOW_ERROR; ++ ret = GST_FLOW_ERROR; ++ goto unmapout; + } + + #ifdef FILE_DUMP__ + bytes_written = fwrite(GST_BUFFER_DATA(buf), sizeof(unsigned char), GST_BUFFER_SIZE(buf), bcmdec->fhnd); + #endif + ++ ret = GST_FLOW_OK; ++ ++unmapout: ++ gst_buffer_unmap(buf, &info); ++out: + gst_buffer_unref(buf); +- return GST_FLOW_OK; ++ return ret; + } + +-static gboolean gst_bcmdec_src_event(GstPad *pad, GstEvent *event) ++static gboolean gst_bcm_dec_src_event(GstPad *pad, ++ GstObject *parent, ++ GstEvent *event) + { + gboolean result; + GstBcmDec *bcmdec; + +- bcmdec = GST_BCMDEC(GST_OBJECT_PARENT(pad)); ++ bcmdec = GST_BCM_DEC(GST_OBJECT_PARENT(pad)); + + result = gst_pad_push_event(bcmdec->sinkpad, event); + +@@ -695,6 +708,7 @@ static gboolean bcmdec_negotiate_format(GstBcmDec *bcmdec) + GstStructure *s1; + const GValue *framerate_value; + GstVideoFormat vidFmt; ++ GstVideoInfo info; + + #ifdef YV12__ + vidFmt = GST_VIDEO_FORMAT_YV12; +@@ -703,21 +717,21 @@ static gboolean bcmdec_negotiate_format(GstBcmDec *bcmdec) + #endif + GST_DEBUG_OBJECT(bcmdec, "framerate = %f", bcmdec->output_params.framerate); + +- if(bcmdec->interlace) { +- caps = gst_video_format_new_caps_interlaced(vidFmt, bcmdec->output_params.width, +- bcmdec->output_params.height, num, den, +- bcmdec->output_params.aspectratio_x, +- bcmdec->output_params.aspectratio_y, +- TRUE); +- } else { +- caps = gst_video_format_new_caps(vidFmt, bcmdec->output_params.width, +- bcmdec->output_params.height, num, den, +- bcmdec->output_params.aspectratio_x, +- bcmdec->output_params.aspectratio_y); +- } +- ++ gst_video_info_init (&info); ++ gst_video_info_set_format (&info, ++ vidFmt, ++ bcmdec->output_params.width, ++ bcmdec->output_params.height); ++ info.fps_n = num; ++ info.fps_d = den; ++ info.par_n = bcmdec->output_params.aspectratio_x; ++ info.par_d = bcmdec->output_params.aspectratio_y; ++ info.interlace_mode = bcmdec->interlace ? ++ GST_VIDEO_INTERLACE_MODE_INTERLEAVED : ++ GST_VIDEO_INTERLACE_MODE_PROGRESSIVE; ++ caps = gst_video_info_to_caps (&info); + result = gst_pad_set_caps(bcmdec->srcpad, caps); +- GST_DEBUG_OBJECT(bcmdec, "gst_bcmdec_negotiate_format %d", result); ++ GST_DEBUG_OBJECT(bcmdec, "gst_bcm_dec_negotiate_format %d", result); + + if (bcmdec->output_params.clr_space == MODE422_YUY2) { + bcmdec->output_params.y_size = bcmdec->output_params.width * bcmdec->output_params.height * BUF_MULT; +@@ -842,10 +856,10 @@ static gboolean bcmdec_process_play(GstBcmDec *bcmdec) + return TRUE; + } + +-static GstStateChangeReturn gst_bcmdec_change_state(GstElement *element, GstStateChange transition) ++static GstStateChangeReturn gst_bcm_dec_change_state(GstElement *element, GstStateChange transition) + { + GstStateChangeReturn result = GST_STATE_CHANGE_SUCCESS; +- GstBcmDec *bcmdec = GST_BCMDEC(element); ++ GstBcmDec *bcmdec = GST_BCM_DEC(element); + BC_STATUS sts = BC_STS_SUCCESS; + int ret = 0; + +@@ -960,7 +974,7 @@ static GstStateChangeReturn gst_bcmdec_change_state(GstElement *element, GstStat + GST_DEBUG_OBJECT(bcmdec, "default %d", transition); + break; + } +- result = GST_ELEMENT_CLASS(parent_class)->change_state(element, transition); ++ result = GST_ELEMENT_CLASS(gst_bcm_dec_parent_class)->change_state(element, transition); + if (result == GST_STATE_CHANGE_FAILURE) { + GST_ERROR_OBJECT(bcmdec, "parent class state change failed"); + return result; +@@ -968,7 +982,7 @@ static GstStateChangeReturn gst_bcmdec_change_state(GstElement *element, GstStat + + if(transition == GST_STATE_CHANGE_READY_TO_NULL) { + GST_DEBUG_OBJECT(bcmdec, "GST_STATE_CHANGE_READY_TO_NULL"); +- sts = gst_bcmdec_cleanup(bcmdec); ++ sts = gst_bcm_dec_cleanup(bcmdec); + if (sts == BC_STS_SUCCESS) + GST_DEBUG_OBJECT(bcmdec, "dev close success"); + else +@@ -978,38 +992,26 @@ static GstStateChangeReturn gst_bcmdec_change_state(GstElement *element, GstStat + return result; + } + +- +-GstClockTime gst_get_current_timex (void) +-{ +- GTimeVal tv; +- +- g_get_current_time(&tv); +- return GST_TIMEVAL_TO_TIME(tv); +-} +- +-clock_t bcm_get_tick_count() +-{ +- tms tm; +- return times(&tm); +-} +- +-static gboolean bcmdec_get_buffer(GstBcmDec *bcmdec, GstBuffer **obuf) ++static gboolean bcmdec_get_buffer(GstBcmDec *bcmdec, ++ gint size, ++ GstBuffer **obuf) + { + GstFlowReturn ret; +- GST_DEBUG_OBJECT(bcmdec, "gst_pad_alloc_buffer_and_set_caps "); ++ GST_DEBUG_OBJECT(bcmdec, "%s", __func__); + +- ret = gst_pad_alloc_buffer_and_set_caps(bcmdec->srcpad, +- GST_BUFFER_OFFSET_NONE, +- bcmdec->output_params.width * bcmdec->output_params.height * BUF_MULT, +- GST_PAD_CAPS (bcmdec->srcpad), obuf); +- if (ret != GST_FLOW_OK) { ++ *obuf = gst_buffer_new_allocate (NULL, ++ size, ++ NULL); ++ ++ if (obuf == NULL) { + GST_ERROR_OBJECT(bcmdec, "gst_pad_alloc_buffer_and_set_caps failed %d ",ret); + return FALSE; + } + ++#if 0 + if (((uintptr_t)GST_BUFFER_DATA(*obuf)) % 4) + GST_DEBUG_OBJECT(bcmdec, "buf is not aligned"); +- ++#endif + return TRUE; + } + +@@ -1382,6 +1384,7 @@ static void * bcmdec_process_output(void *ctx) + GstClockTime cur_stream_time_diff = 0; + int wait_cnt = 0; + guint32 nextPicNumFlags = 0; ++ GstMapInfo info; + + gboolean is_paused = FALSE; + +@@ -1427,7 +1430,8 @@ static void * bcmdec_process_output(void *ctx) + guint8* data_ptr; + if (gstbuf == NULL) { + if (!bcmdec->rbuf_thread_running) { +- if (!bcmdec_get_buffer(bcmdec, &gstbuf)) { ++ gint size = bcmdec->output_params.width * bcmdec->output_params.height * BUF_MULT; ++ if (!bcmdec_get_buffer(bcmdec, size, &gstbuf)) { + usleep(30 * 1000); + continue; + } +@@ -1460,9 +1464,16 @@ static void * bcmdec_process_output(void *ctx) + else + GST_DEBUG_OBJECT(bcmdec, "re-using rbuf, going to proc output"); + +- data_ptr = GST_BUFFER_DATA(gstbuf); +- ++ if(!gst_buffer_map(gstbuf, ++ &info, ++ GST_MAP_WRITE)) { ++ GST_ERROR_OBJECT(bcmdec, "Failed to map buffer"); ++ continue; ++ } ++ data_ptr = info.data; + bcmdec_init_procout(bcmdec, &pout, data_ptr); ++ gst_buffer_unmap(gstbuf, &info); ++ + rx_flush = TRUE; + pout.PicInfo.picture_number = 0; + // For interlaced content, if I am holding a buffer but the next buffer is not from the same picture +@@ -1473,7 +1484,7 @@ static void * bcmdec_process_output(void *ctx) + if(pic_number == 0) + gst_buffer_unref(gstbuf); + else if (gst_queue_element) { +- GST_BUFFER_FLAG_SET(gstbuf, GST_VIDEO_BUFFER_ONEFIELD); ++ GST_BUFFER_FLAG_SET(gstbuf, GST_VIDEO_BUFFER_FLAG_ONEFIELD); + gst_queue_element->gstbuf = gstbuf; + bcmdec_ins_buf(bcmdec, gst_queue_element); + bcmdec->prev_pic = pic_number; +@@ -1489,7 +1500,7 @@ static void * bcmdec_process_output(void *ctx) + } + if (bEOS) { + if (gstbuf) { +- gst_buffer_unref(gstbuf); ++ gst_buffer_unref(gstbuf); + gstbuf = NULL; + } + if (gst_queue_element) { +@@ -1561,14 +1572,6 @@ static void * bcmdec_process_output(void *ctx) + GST_DEBUG_OBJECT(bcmdec, "LOST PICTURE pic_no = %d, prev = %d", pic_number, bcmdec->prev_pic); + } + +-/* if ((bcmdec->prev_pic == pic_number) && (bcmdec->ses_nbr == pout.PicInfo.sess_num) && !bcmdec->interlace) { +- if (!bcmdec->silent) +- GST_DEBUG_OBJECT(bcmdec, "rp"); +- +- if (!(pout.PicInfo.flags & VDEC_FLAG_LAST_PICTURE)) +- continue; +- }*/ +- + if (!bcmdec->interlace || bcmdec->sec_field) { + GST_DEBUG_OBJECT(bcmdec, "Progressive or Second Field"); + GST_BUFFER_OFFSET(gstbuf) = 0; +@@ -1597,13 +1600,11 @@ static void * bcmdec_process_output(void *ctx) + } + } + +- GST_BUFFER_SIZE(gstbuf) = bcmdec->output_params.width * bcmdec->output_params.height * BUF_MULT; +- + if (!bcmdec->interlace || bcmdec->sec_field) { + if (gst_queue_element) { + // If interlaced, set the GST_VIDEO_BUFFER_TFF flags + if(bcmdec->sec_field) +- GST_BUFFER_FLAG_SET(gstbuf, GST_VIDEO_BUFFER_TFF); ++ GST_BUFFER_FLAG_SET(gstbuf, GST_VIDEO_BUFFER_FLAG_TFF); + gst_queue_element->gstbuf = gstbuf; + bcmdec_ins_buf(bcmdec, gst_queue_element); + bcmdec->prev_pic = pic_number; +@@ -1674,7 +1675,7 @@ static void * bcmdec_process_output(void *ctx) + } + if (rx_flush) { + if (!bcmdec->flushing) { +-// GST_DEBUG_OBJECT(bcmdec, "DtsFlushRxCapture called"); ++ GST_DEBUG_OBJECT(bcmdec, "DtsFlushRxCapture called"); + // sts = decif_flush_rxbuf(&bcmdec->decif, FALSE); + // if (sts != BC_STS_SUCCESS) + // GST_DEBUG_OBJECT(bcmdec, "DtsFlushRxCapture failed"); +@@ -1880,11 +1881,11 @@ static void bcmdec_process_flush_start(GstBcmDec *bcmdec) + GST_ERROR_OBJECT(bcmdec, "flush_dec failed sts %d", sts); + } + +-static BC_STATUS gst_bcmdec_cleanup(GstBcmDec *bcmdec) ++static BC_STATUS gst_bcm_dec_cleanup(GstBcmDec *bcmdec) + { + BC_STATUS sts = BC_STS_SUCCESS; + +- GST_DEBUG_OBJECT(bcmdec, "gst_bcmdec_cleanup - enter"); ++ GST_DEBUG_OBJECT(bcmdec, "gst_bcm_dec_cleanup - enter"); + bcmdec->streaming = FALSE; + + bcmdec_release_mem_buf_que_pool(bcmdec); +@@ -2117,11 +2118,11 @@ static GSTBUF_LIST * bcmdec_rem_buf(GstBcmDec *bcmdec) + return temp; + } + +-static BC_STATUS bcmdec_insert_sps_pps(GstBcmDec *bcmdec, GstBuffer* gstbuf) ++static BC_STATUS bcmdec_insert_sps_pps(GstBcmDec *bcmdec, GstMapInfo* info) + { + BC_STATUS sts = BC_STS_SUCCESS; +- guint8 *data = GST_BUFFER_DATA(gstbuf); +- guint32 data_size = GST_BUFFER_SIZE(gstbuf); ++ guint8 *data = info->data; ++ guint32 data_size = info->size; + gint profile; + guint nal_size; + guint num_sps, num_pps, i; +@@ -2436,7 +2437,6 @@ static void * bcmdec_process_get_rbuf(void *ctx) + + while (bcmdec->streaming && get_buf_start) + { +- //GST_DEBUG_OBJECT(bcmdec, "process get rbuf start...."); + gstbuf = NULL; + + if (!bcmdec->recv_thread && !bcmdec->streaming) { +@@ -2446,9 +2446,8 @@ static void * bcmdec_process_get_rbuf(void *ctx) + break; + } + +- // If we have enough buffers from the renderer then don't get any more + if(bcmdec->gst_padbuf_que_cnt >= GST_RENDERER_BUF_POOL_SZ) { +- usleep(100 * 1000); ++ usleep(100 * 1000); /* we have enought buffers from the renderer */ + GST_DEBUG_OBJECT(bcmdec, "SLEEPING because we have enough buffers"); + continue; + } +@@ -2467,13 +2466,10 @@ static void * bcmdec_process_get_rbuf(void *ctx) + bufSz = bcmdec->output_params.width * bcmdec->output_params.height * BUF_MULT; + + GST_DEBUG_OBJECT(bcmdec, "process get rbuf gst_pad_alloc_buffer_and_set_caps ...."); +- ret = gst_pad_alloc_buffer_and_set_caps(bcmdec->srcpad, GST_BUFFER_OFFSET_NONE, +- bufSz, GST_PAD_CAPS(bcmdec->srcpad), &gstbuf); +- if (ret != GST_FLOW_OK) { +- if (!bcmdec->silent) +- GST_ERROR_OBJECT(bcmdec, "gst_pad_alloc_buffer_and_set_caps failed %d ",ret); +- usleep(30 * 1000); +- continue; ++ if (!bcmdec_get_buffer(bcmdec, bufSz, &gstbuf)) { ++ GST_ERROR_OBJECT(bcmdec, "gst_pad_alloc_buffer_and_set_caps failed %d ",ret); ++ usleep(30 * 1000); ++ continue; + } + + GST_DEBUG_OBJECT(bcmdec, "Got GST Buf RCnt:%d", bcmdec->gst_padbuf_que_cnt); +@@ -2501,9 +2497,6 @@ static gboolean bcmdec_start_get_rbuf_thread(GstBcmDec *bcmdec) + gint ret = 0; + pthread_attr_t thread_attr; + +-// if (!bcmdec_alloc_mem_rbuf_que_pool(bcmdec)) +-// GST_ERROR_OBJECT(bcmdec, "rend pool alloc failed/n"); +- + bcmdec->gst_padbuf_que_hd = bcmdec->gst_padbuf_que_tl = NULL; + + ret = sem_init(&bcmdec->rbuf_ins_event, 0, 0); +@@ -2658,18 +2651,14 @@ static GSTBUF_LIST *bcmdec_rem_padbuf(GstBcmDec *bcmdec) + */ + static gboolean plugin_init(GstPlugin *bcmdec) + { +- //printf("BcmDec_init"); +- + /* + * debug category for fltering log messages +- * +- * exchange the string 'Template bcmdec' with your description + */ +- GST_DEBUG_CATEGORY_INIT(gst_bcmdec_debug, "bcmdec", 0, "Broadcom video decoder"); ++ GST_DEBUG_CATEGORY_INIT(gst_bcm_dec_debug, "bcmdec", 0, "Broadcom video decoder"); + +- return gst_element_register(bcmdec, "bcmdec", GST_BCMDEC_RANK, GST_TYPE_BCMDEC); ++ return gst_element_register(bcmdec, "bcmdec", GST_BCM_DEC_RANK, GST_TYPE_BCM_DEC); + } + + /* gstreamer looks for this structure to register bcmdec */ +-GST_PLUGIN_DEFINE(GST_VERSION_MAJOR, GST_VERSION_MINOR, "bcmdec", "Video decoder", plugin_init, VERSION, "LGPL", "bcmdec", "http://broadcom.com/") ++GST_PLUGIN_DEFINE(GST_VERSION_MAJOR, GST_VERSION_MINOR, bcmdec, "Video decoder", plugin_init, VERSION, "LGPL", "bcmdec", "http://broadcom.com/") + +diff --git a/filters/gst/gst-plugin/src/gstbcmdec.h b/filters/gst/gst-plugin/src/gstbcmdec.h +index 6e5b100..5c02c8a 100644 +--- a/filters/gst/gst-plugin/src/gstbcmdec.h ++++ b/filters/gst/gst-plugin/src/gstbcmdec.h +@@ -23,11 +23,11 @@ + * along with this library. If not, see . + * + *******************************************************************/ +-#ifndef __GST_BCMDEC_H__ +-#define __GST_BCMDEC_H__ ++#ifndef __GST_BCM_DEC_H__ ++#define __GST_BCM_DEC_H__ + + +-#define GST_BCMDEC_RANK 0xffff ++#define GST_BCM_DEC_RANK 0xffff + + #define CLOCK_BASE 9LL + #define CLOC_FREQ_CLOC_BASE * 10000 +@@ -127,16 +127,16 @@ typedef struct { + + G_BEGIN_DECLS + +-#define GST_TYPE_BCMDEC \ +- (gst_bcmdec_get_type()) +-#define GST_BCMDEC(obj) \ +- (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_BCMDEC,GstBcmDec)) +-#define GST_BCMDEC_CLASS(klass) \ +- (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_BCMDEC,GstBcmDecClass)) +-#define GST_IS_BCMDEC(obj) \ +- (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_BCMDEC)) +-#define GST_IS_BCMDEC_CLASS(klass) \ +- (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_BCMDEC)) ++#define GST_TYPE_BCM_DEC \ ++ (gst_bcm_dec_get_type()) ++#define GST_BCM_DEC(obj) \ ++ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_BCM_DEC,GstBcmDec)) ++#define GST_BCM_DEC_CLASS(klass) \ ++ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_BCM_DEC,GstBcmDecClass)) ++#define GST_IS_BCM_DEC(obj) \ ++ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_BCM_DEC)) ++#define GST_IS_BCM_DEC_CLASS(klass) \ ++ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_BCM_DEC)) + + typedef struct _GstBcmDec GstBcmDec; + typedef struct _GstBcmDecClass GstBcmDecClass; +@@ -188,7 +188,7 @@ struct _GstBcmDec + + gboolean flushing; + sem_t push_stop_event; +- sem_t push_start_event; ++ sem_t push_start_event; + sem_t recv_stop_event; + guint ses_nbr; + gboolean insert_pps; +@@ -233,49 +233,50 @@ struct _GstBcmDecClass + GstElementClass parent_class; + }; + +-GType gst_bcmdec_get_type (void); ++GType gst_bcm_dec_get_type (void); + + static void +-gst_bcmdec_base_init (gpointer gclass); ++gst_bcm_dec_base_init (gpointer gclass); + + static void +-gst_bcmdec_class_init(GstBcmDecClass * klass); ++gst_bcm_dec_class_init(GstBcmDecClass * klass); + + static void +-gst_bcmdec_init(GstBcmDec * bcmdec, +- GstBcmDecClass * gclass); ++gst_bcm_dec_init(GstBcmDec * bcmdec); ++ + + static void +-gst_bcmdec_finalize(GObject * object); ++gst_bcm_dec_finalize(GObject * object); + + static GstFlowReturn +-gst_bcmdec_chain(GstPad * pad, ++gst_bcm_dec_chain(GstPad * pad, ++ GstObject * parent, + GstBuffer * buffer); + + static GstStateChangeReturn +-gst_bcmdec_change_state(GstElement * element, ++gst_bcm_dec_change_state(GstElement * element, + GstStateChange transition); + + static gboolean +-gst_bcmdec_sink_set_caps(GstPad * pad, ++gst_bcm_dec_sink_set_caps(GstPad * pad, + GstCaps * caps); + +-static GstCaps *gst_bcmdec_getcaps (GstPad * pad); +- + static gboolean +-gst_bcmdec_src_event(GstPad * pad, ++gst_bcm_dec_src_event(GstPad * pad, ++ GstObject * parent, + GstEvent * event); + + static gboolean +-gst_bcmdec_sink_event(GstPad * pad, ++gst_bcm_dec_sink_event(GstPad * pad, ++ GstObject * parent, + GstEvent * event); + + static void +-gst_bcmdec_set_property (GObject * object, guint prop_id, ++gst_bcm_dec_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); + + static void +-gst_bcmdec_get_property (GObject * object, guint prop_id, ++gst_bcm_dec_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); + + static gboolean +@@ -285,7 +286,7 @@ static void + bcmdec_reset(GstBcmDec * bcmdec); + + static gboolean +-bcmdec_get_buffer(GstBcmDec * bcmdec, GstBuffer ** obuf); ++bcmdec_get_buffer(GstBcmDec * bcmdec, gint size, GstBuffer ** obuf); + + static void* + bcmdec_process_output(void * ctx); +@@ -300,7 +301,7 @@ static gboolean + bcmdec_format_change(GstBcmDec * filter,BC_PIC_INFO_BLOCK* pic_info); + + static BC_STATUS +-gst_bcmdec_cleanup(GstBcmDec *filter); ++gst_bcm_dec_cleanup(GstBcmDec *filter); + + static gboolean + bcmdec_start_recv_thread(GstBcmDec * bcmdec); +@@ -339,7 +340,7 @@ bcmdec_start_push_thread(GstBcmDec * bcmdec); + //bcmdec_insert_startcode(GstBcmDec* filter,GstBuffer* gstbuf, guint8* dest_buf,guint32* sz); + + static BC_STATUS +-bcmdec_insert_sps_pps(GstBcmDec* filter,GstBuffer* gstbuf); ++bcmdec_insert_sps_pps(GstBcmDec* filter, GstMapInfo* gstbuf); + + static void + bcmdec_set_aspect_ratio(GstBcmDec *filter,BC_PIC_INFO_BLOCK* pic_info); +@@ -383,7 +384,6 @@ bcmdec_ins_padbuf(GstBcmDec *filter,GSTBUF_LIST *gst_queue_element); + static GSTBUF_LIST* + bcmdec_rem_padbuf(GstBcmDec *filter); + +- + G_END_DECLS + +-#endif /* __GST_BCMDEC_H__ */ ++#endif /* __GST_BCM_DEC_H__ */ diff --git a/SOURCES/libcrystalhd-20120405.tar.bz2 b/SOURCES/libcrystalhd-20120405.tar.bz2 new file mode 100644 index 0000000..9c9eee2 Binary files /dev/null and b/SOURCES/libcrystalhd-20120405.tar.bz2 differ diff --git a/SOURCES/libcrystalhd-nosse2.patch b/SOURCES/libcrystalhd-nosse2.patch new file mode 100644 index 0000000..e8a81cd --- /dev/null +++ b/SOURCES/libcrystalhd-nosse2.patch @@ -0,0 +1,105 @@ +diff -up libcrystalhd-20120405/linux_lib/libcrystalhd/libcrystalhd_int_if.cpp.nosse2 libcrystalhd-20120405/linux_lib/libcrystalhd/libcrystalhd_int_if.cpp +--- libcrystalhd-20120405/linux_lib/libcrystalhd/libcrystalhd_int_if.cpp.nosse2 2011-03-14 21:02:54.000000000 +0100 ++++ libcrystalhd-20120405/linux_lib/libcrystalhd/libcrystalhd_int_if.cpp 2012-08-03 20:04:23.700362339 +0200 +@@ -33,7 +33,9 @@ + #include "libcrystalhd_int_if.h" + #include "libcrystalhd_fwcmds.h" + ++#if __SSE2__ || !defined __GNUC__ + #include ++#endif + + #define SV_MAX_LINE_SZ 128 + #define PCI_GLOBAL_CONTROL MISC2_GLOBAL_CTRL +@@ -1425,11 +1427,14 @@ BC_STATUS DtsCopyNV12(DTS_LIB_CONTEXT *C + } + + // TODO: add sse2 detection ++#if __SSE2__ + static bool gSSE2 = true; // most of the platforms will have it anyway: ++#endif + // 64 bits: no test necessary + // mac: no test necessary + // linux/windows: we might have to do the test. + ++#if __SSE2__ + static void fast_memcpy(uint8_t *dst, const uint8_t *src, uint32_t count) + { + // tested +@@ -1466,6 +1471,9 @@ static void fast_memcpy(uint8_t *dst, co + while (count --) + *dst++ = *src++; + } ++#else ++#define fast_memcpy(a,b,c) memcpy(a,b,c) ++#endif + + // this is not good. + // if we have 3 buffers, we cannot assume V is after U +@@ -1504,6 +1512,7 @@ static BC_STATUS DtsCopy422ToUYVY(uint8_ + + for (__y = 0; __y < height; __y++) + { ++#if __SSE2__ + if (gSSE2) + { + if (((((uintptr_t) dstY) & 0xf) == 0) && ((((uintptr_t) srcY) & 0xf) == 0)) +@@ -1529,6 +1538,7 @@ static BC_STATUS DtsCopy422ToUYVY(uint8_ + } + } + } ++#endif + + while (x < srcWidth-1) + { +@@ -1548,6 +1558,7 @@ static BC_STATUS DtsCopy422ToUYVY(uint8_ + // convert to NV12 + static BC_STATUS DtsCopy422ToNV12(uint8_t *dstY, uint8_t *dstUV, const uint8_t *srcY, uint32_t srcWidth, uint32_t dstWidth, uint32_t height, uint32_t strideY, uint32_t strideUV) + { ++#if __SSE2__ + // tested + uint32_t x, __y; + +@@ -1667,6 +1678,9 @@ static BC_STATUS DtsCopy422ToNV12(uint8_ + dstY += strideY; + } + return BC_STS_SUCCESS; ++#else ++ return BC_STS_INV_ARG; ++#endif + } + + +@@ -1681,6 +1695,7 @@ static BC_STATUS DtsCopy420ToYV12(uint8_ + + static BC_STATUS DtsCopy420ToYUY2(uint8_t *dstY, uint8_t *dstUV, const uint8_t *srcY, const uint8_t *srcUV, uint32_t srcWidth, uint32_t dstWidth, uint32_t height, uint32_t strideY, uint32_t strideUV) + { ++#if __SSE2__ + // TODO, test this + uint32_t x, __y; + +@@ -1836,10 +1851,14 @@ static BC_STATUS DtsCopy420ToYUY2(uint8_ + } + + return BC_STS_SUCCESS; ++#else ++ return BC_STS_INV_ARG; ++#endif + } + + static BC_STATUS DtsCopy420ToUYVY(uint8_t *dstY, uint8_t *dstUV, const uint8_t *srcY, const uint8_t *srcUV, uint32_t srcWidth, uint32_t dstWidth, uint32_t height, uint32_t strideY, uint32_t strideUV) + { ++#if __SSE2__ + // TODO, test this + uint32_t x, __y; + +@@ -1993,6 +2012,9 @@ static BC_STATUS DtsCopy420ToUYVY(uint8_ + } + + return BC_STS_SUCCESS; ++#else ++ return BC_STS_INV_ARG; ++#endif + } + + static BC_STATUS DtsCopy420ToNV12(uint8_t *dstY, uint8_t *dstUV, const uint8_t *srcY, const uint8_t *srcUV, uint32_t srcWidth, uint32_t dstWidth, uint32_t height, uint32_t strideY, uint32_t strideUV) diff --git a/SOURCES/libcrystalhd-snapshot.sh b/SOURCES/libcrystalhd-snapshot.sh new file mode 100755 index 0000000..560ace2 --- /dev/null +++ b/SOURCES/libcrystalhd-snapshot.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +set -e + +tmp=$(mktemp -d) + +trap cleanup EXIT +cleanup() { + set +e + [ -z "$tmp" -o ! -d "$tmp" ] || rm -rf "$tmp" +} + +unset CDPATH +pwd=$(pwd) +date=$(date +%Y%m%d) +package=libcrystalhd +svn={$date} +svn=HEAD + +cd "$tmp" +svn export --force https://xbmc.svn.sourceforge.net/svnroot/xbmc/trunk/lib/libcrystalhd/ ${package}-${date} +tar cJf "$pwd"/${package}-${date}.tar.xz ${package}-${date} +cd - >/dev/null diff --git a/SPECS/libcrystalhd.spec b/SPECS/libcrystalhd.spec new file mode 100644 index 0000000..8e2716f --- /dev/null +++ b/SPECS/libcrystalhd.spec @@ -0,0 +1,250 @@ +%global majorminor 1.0 +%global date 20120405 +# Avoid to emit gstreamer provides - rhbz#1184975 +%undefine __gstreamer1_provides + +Summary: Broadcom Crystal HD device interface library +Name: libcrystalhd +Version: 3.10.0 +Release: 27%{?dist} +License: LGPLv2 +URL: http://www.broadcom.com/support/crystal-hd/ +ExcludeArch: s390 s390x + +#Source: http://www.broadcom.com/docs/support/crystalhd/crystalhd_linux_20100703.zip +# This tarball and README are inside the above zip file... +# Patch generated from http://git.linuxtv.org/jarod/crystalhd.git +Source0: libcrystalhd-%{date}.tar.bz2 +Source1: README_07032010 +# We're going to use even newer firmware for now +Source2: bcm70012fw.bin +Source3: bcm70015fw.bin +# LICENSE file is copy-n-pasted from http://www.broadcom.com/support/crystal_hd/ +Source4: LICENSE +Source5: libcrystalhd-snapshot.sh +Patch0: libcrystalhd-nosse2.patch +# https://patchwork2.kernel.org/patch/2247431/ +Patch1: crystalhd-gst-Port-to-GStreamer-1.0-API.patch + +BuildRequires: gcc-c++ +BuildRequires: autoconf automake libtool +BuildRequires: gstreamer1-devel >= %{majorminor} +BuildRequires: gstreamer1-plugins-base-devel >= %{majorminor} +BuildRequires: make +Requires: crystalhd-firmware + +%description +The libcrystalhd library provides userspace access to Broadcom Crystal HD +video decoder devices. The device supports hardware decoding of MPEG-2, +h.264 and VC1 video codecs, up to 1080p at 40fps for the first-generation +bcm970012 hardware, and up to 1080p at 60fps for the second-generation +bcm970015 hardware. + +%package devel +Summary: Development libs for libcrystalhd +Requires: %{name} = %{version}-%{release} + +%description devel +Development libraries needed to build applications against libcrystalhd. + +%package -n crystalhd-firmware +Summary: Firmware for the Broadcom Crystal HD video decoder +License: Redistributable, no modification permitted +BuildArch: noarch +Requires: %{name} = %{version}-%{release} + +%description -n crystalhd-firmware +Firmwares for the Broadcom Crystal HD (bcm970012 and bcm970015) +video decoders. + +%package -n gstreamer-plugin-crystalhd +Summary: Gstreamer crystalhd decoder plugin +Requires: %{name} = %{version}-%{release} +Requires: gstreamer1-plugins-base + +%description -n gstreamer-plugin-crystalhd +Gstreamer crystalhd decoder plugin + +%prep +%setup -q -n libcrystalhd-%{date} +cp %{SOURCE1} %{SOURCE4} . +%ifnarch %{ix86} ia64 x86_64 +%patch0 -p1 -b .nosse2 +sed -i -e 's|-msse2||' linux_lib/libcrystalhd/Makefile +%endif +%patch1 -p1 -b .gst1 + +%build +pushd linux_lib/libcrystalhd/ > /dev/null 2>&1 +sed -i -e 's|-D__LINUX_USER__|-D__LINUX_USER__ %{optflags}|' Makefile +%{make_build} +popd > /dev/null 2>&1 + +pushd filters/gst/gst-plugin/ > /dev/null 2>&1 +sh autogen.sh || : + +%configure +make %{?_smp_mflags} \ + CFLAGS="%{optflags} -I%{_builddir}/%{buildsubdir}/include -I%{_builddir}/%{buildsubdir}/linux_lib/libcrystalhd" \ + BCMDEC_LDFLAGS="%{?__global_ldflags} -L%{_builddir}/%{buildsubdir}/linux_lib/libcrystalhd -lcrystalhd" +popd > /dev/null 2>&1 + +%install +pushd linux_lib/libcrystalhd/ > /dev/null 2>&1 +make install LIBDIR=%{_libdir} DESTDIR=$RPM_BUILD_ROOT +popd > /dev/null 2>&1 + +pushd filters/gst/gst-plugin/ > /dev/null 2>&1 +make install DESTDIR=$RPM_BUILD_ROOT +rm -f $RPM_BUILD_ROOT%{_libdir}/gstreamer-1.0/libgstbcmdec.{a,la} +popd > /dev/null 2>&1 + +rm -rf $RPM_BUILD_ROOT/lib/firmware/ +mkdir -p $RPM_BUILD_ROOT%{_prefix}/lib/firmware/ +install -pm 0644 %{SOURCE2} $RPM_BUILD_ROOT%{_prefix}/lib/firmware/ +install -pm 0644 %{SOURCE3} $RPM_BUILD_ROOT%{_prefix}/lib/firmware/ + +#Install udev rule +mkdir -p $RPM_BUILD_ROOT%{_prefix}/lib/udev/rules.d +install -pm 0644 driver/linux/20-crystalhd.rules \ + $RPM_BUILD_ROOT%{_prefix}/lib/udev/rules.d + + +%ldconfig_scriptlets + +%files +%doc README_07032010 LICENSE +%{_libdir}/libcrystalhd.so.* + +%files devel +%dir %{_includedir}/libcrystalhd +%{_includedir}/libcrystalhd/* +%{_libdir}/libcrystalhd.so + +%files -n crystalhd-firmware +%doc LICENSE +%{_prefix}/lib/udev/rules.d/20-crystalhd.rules +%{_prefix}/lib/firmware/bcm70012fw.bin +%{_prefix}/lib/firmware/bcm70015fw.bin + +%files -n gstreamer-plugin-crystalhd +%{_libdir}/gstreamer-%{majorminor}/*.so + + +%changelog +* Thu Jan 20 2022 Fedora Release Engineering - 3.10.0-27 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + +* Thu Jul 22 2021 Fedora Release Engineering - 3.10.0-26 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + +* Tue Jan 26 2021 Fedora Release Engineering - 3.10.0-25 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Tue Jul 28 2020 Fedora Release Engineering - 3.10.0-24 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Wed Jan 29 2020 Fedora Release Engineering - 3.10.0-23 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Thu Jul 25 2019 Fedora Release Engineering - 3.10.0-22 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + +* Fri Feb 01 2019 Fedora Release Engineering - 3.10.0-21 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Tue Jul 17 2018 Nicolas Chauvet - 3.10.0-20 +- Add missng cc + +* Fri Jul 13 2018 Fedora Release Engineering - 3.10.0-19 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Wed Feb 07 2018 Fedora Release Engineering - 3.10.0-18 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Thu Aug 03 2017 Fedora Release Engineering - 3.10.0-17 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 3.10.0-16 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Mon Feb 13 2017 Nicolas Chauvet - 3.10.0-15 +- Add cflags/ldflags - rhbz#1411018 + +* Fri Feb 10 2017 Fedora Release Engineering - 3.10.0-14 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Wed Jul 20 2016 Nicolas Chauvet - 3.10.0-13 +- Fix perm on firmware files - rhbz#1321530 + +* Thu Feb 04 2016 Fedora Release Engineering - 3.10.0-12 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Mon Aug 03 2015 Nicolas Chauvet - 3.10.0-11 +- Avoid to emit gstreamer1 provides - rhbz#1184975 + +* Wed Jun 17 2015 Fedora Release Engineering - 3.10.0-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Sat May 02 2015 Kalev Lember - 3.10.0-9 +- Rebuilt for GCC 5 C++11 ABI change + +* Sun Aug 17 2014 Fedora Release Engineering - 3.10.0-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Sat Jun 07 2014 Fedora Release Engineering - 3.10.0-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Mon Oct 07 2013 Nicolas Chauvet - 3.10.0-6 +- Don't install udev rules in /etc/udev/rules.d - rhbz#979542 + +* Sat Aug 03 2013 Fedora Release Engineering - 3.10.0-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Sun Apr 14 2013 Peter Robinson 3.10.0-4 +- Add patch to port to gstreamer 1.0 and update spec + +* Thu Feb 14 2013 Fedora Release Engineering - 3.10.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Fri Aug 03 2012 Nicolas Chauvet - 3.10.0-2 +- Fix build on non-SSE2 arches +- Install CrystalHD udev rule +- Clean spec file + +* Thu Apr 05 2012 Nicolas Chauvet - 3.10.0-1 +- Update to 3.10.0 + +* Fri Jan 13 2012 Fedora Release Engineering - 3.5.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Mon Feb 07 2011 Fedora Release Engineering - 3.5.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Sat Aug 28 2010 Jarod Wilson - 3.5.1-1 +- Update to v3.5.1, now with nv12 support + +* Sun Jul 25 2010 Jarod Wilson - 3.5.0-2 +- Tarball had object files in it, clean them out before building + +* Sat Jul 24 2010 Jarod Wilson - 3.5.0-1 +- Rebase to 07032010 crystalhd sources +- Large version-bump as driver and lib are now essentially 100% + in sync with the Windows driver and lib +- Ship firmware, now that Broadcom has posted a redistribution, + no modification license to cover it +- Build the gstreamer decoder plugin (will be moved to its own + package sooner or later) + +* Sun Apr 04 2010 Jarod Wilson - 0.9.25-4 +- Fix segfault on firmware upload + +* Fri Mar 26 2010 Jarod Wilson - 0.9.25-3 +- Update to pre-0.9.26 libcrystalhd, which contains support + for the new Broadcom BCM970015 Crystal HD decoder card + +* Thu Mar 11 2010 Jarod Wilson - 0.9.25-2 +- Minor fixups to the as-yet-not-enabled firmware sub-package + +* Wed Jan 06 2010 Jarod Wilson - 0.9.25-1 +- Initial package