First working version of iOS tutorial 3

This commit is contained in:
Xavi Artigas 2013-05-08 11:22:17 +02:00
parent b2fadd6d90
commit 809581ccaf
10 changed files with 187 additions and 6 deletions

View file

@ -63,6 +63,7 @@
C6B6129517396231003FC410 /* appicon-3-iPad@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = C6B6129117396231003FC410 /* appicon-3-iPad@2x.png */; };
C6B6129617396231003FC410 /* appicon-3-iPhone.png in Resources */ = {isa = PBXBuildFile; fileRef = C6B6129217396231003FC410 /* appicon-3-iPhone.png */; };
C6B6129717396231003FC410 /* appicon-3-iPhone@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = C6B6129317396231003FC410 /* appicon-3-iPhone@2x.png */; };
C6EB857C173A4D9500C3953D /* EaglUIVIew.m in Sources */ = {isa = PBXBuildFile; fileRef = C6EB857B173A4D9500C3953D /* EaglUIVIew.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@ -138,6 +139,8 @@
C6B6129117396231003FC410 /* appicon-3-iPad@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "appicon-3-iPad@2x.png"; sourceTree = "<group>"; };
C6B6129217396231003FC410 /* appicon-3-iPhone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "appicon-3-iPhone.png"; sourceTree = "<group>"; };
C6B6129317396231003FC410 /* appicon-3-iPhone@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "appicon-3-iPhone@2x.png"; sourceTree = "<group>"; };
C6EB857A173A4D9500C3953D /* EaglUIVIew.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EaglUIVIew.h; sourceTree = "<group>"; };
C6EB857B173A4D9500C3953D /* EaglUIVIew.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EaglUIVIew.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -301,6 +304,8 @@
C6B6126417395CF2003FC410 /* Tutorial 3 */ = {
isa = PBXGroup;
children = (
C6EB857A173A4D9500C3953D /* EaglUIVIew.h */,
C6EB857B173A4D9500C3953D /* EaglUIVIew.m */,
C6B6128F17396231003FC410 /* Images */,
C6B6128817395D4F003FC410 /* GStreamerBackend.h */,
C6B6128917395D4F003FC410 /* GStreamerBackend.m */,
@ -511,6 +516,7 @@
C6B6127E17395CF2003FC410 /* ViewController.m in Sources */,
C6B6128B17395D4F003FC410 /* GStreamerBackend.m in Sources */,
C6B6128E17395EE2003FC410 /* gst_ios_init.c in Sources */,
C6EB857C173A4D9500C3953D /* EaglUIVIew.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1037,6 +1043,7 @@
C6B6128717395CF2003FC410 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};

View file

@ -0,0 +1,55 @@
/*
* GStreamer Player demo app for IOS
* Copyright (C) 2013 Collabora Ltd.
* @author: Thiago Santos <thiago.sousa.santos@collabora.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Alternatively, the contents of this file may be used under the
* GNU Lesser General Public License Version 2.1 (the "LGPL"), in
* which case the following provisions apply instead of the ones
* mentioned above:
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>
#include <OpenGLES/ES2/gl.h>
#include <OpenGLES/ES2/glext.h>
@interface EaglUIView : UIView
{
}
@end

View file

@ -0,0 +1,66 @@
/*
* GStreamer Player demo app for IOS
* Copyright (C) 2013 Collabora Ltd.
* @author: Thiago Santos <thiago.sousa.santos@collabora.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Alternatively, the contents of this file may be used under the
* GNU Lesser General Public License Version 2.1 (the "LGPL"), in
* which case the following provisions apply instead of the ones
* mentioned above:
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#import "EaglUIVIew.h"
#import <QuartzCore/QuartzCore.h>
@implementation EaglUIView
+ (Class) layerClass
{
return [CAEAGLLayer class];
}
- (id) initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame]))
{
}
return self;
}
@end

View file

@ -4,8 +4,9 @@
@interface GStreamerBackend : NSObject
/* Initialization method. Pass the delegate that will take care of the UI.
* This delegate must implement the GStreamerBackendDelegate protocol */
-(id) init:(id) uiDelegate;
* This delegate must implement the GStreamerBackendDelegate protocol.
* Pass also the UIView object that will hold the video window. */
-(id) init:(id) uiDelegate videoView:(UIView*) video_view;
/* Set the pipeline to PLAYING */
-(void) play;

View file

@ -1,6 +1,7 @@
#import "GStreamerBackend.h"
#include <gst/gst.h>
#include <gst/interfaces/xoverlay.h>
GST_DEBUG_CATEGORY_STATIC (debug_category);
#define GST_CAT_DEFAULT debug_category
@ -14,20 +15,23 @@ GST_DEBUG_CATEGORY_STATIC (debug_category);
@implementation GStreamerBackend {
id ui_delegate; /* Class that we use to interact with the user interface */
GstElement *pipeline; /* The running pipeline */
GstElement *video_sink;/* The video sink element which receives XOverlay commands */
GMainContext *context; /* GLib context used to run the main loop */
GMainLoop *main_loop; /* GLib main loop */
gboolean initialized; /* To avoid informing the UI multiple times about the initialization */
UIView *ui_video_view; /* UIView that holds the video */
}
/*
* Interface methods
*/
-(id) init:(id) uiDelegate
-(id) init:(id) uiDelegate videoView:(UIView *)video_view
{
if (self = [super init])
{
self->ui_delegate = uiDelegate;
self->ui_video_view = video_view;
GST_DEBUG_CATEGORY_INIT (debug_category, "tutorial-2", 0, "iOS tutorial 2");
gst_debug_set_threshold_for_name("tutorial-2", GST_LEVEL_DEBUG);
@ -136,7 +140,7 @@ static void state_changed_cb (GstBus *bus, GstMessage *msg, GStreamerBackend *se
g_main_context_push_thread_default(context);
/* Build pipeline */
pipeline = gst_parse_launch("audiotestsrc ! audioconvert ! audioresample ! autoaudiosink", &error);
pipeline = gst_parse_launch("videotestsrc ! warptv ! ffmpegcolorspace ! autovideosink", &error);
if (error) {
gchar *message = g_strdup_printf("Unable to build pipeline: %s", error->message);
g_clear_error (&error);
@ -144,7 +148,17 @@ static void state_changed_cb (GstBus *bus, GstMessage *msg, GStreamerBackend *se
g_free (message);
return;
}
/* Set the pipeline to READY, so it can already accept a window handle */
gst_element_set_state(pipeline, GST_STATE_READY);
video_sink = gst_bin_get_by_interface(GST_BIN(pipeline), GST_TYPE_X_OVERLAY);
if (!video_sink) {
GST_ERROR ("Could not retrieve video sink");
return;
}
gst_x_overlay_set_window_handle(GST_X_OVERLAY(video_sink), (guintptr) (id) ui_video_view);
/* Instruct the bus to emit signals for each received message, and connect to the interesting signals */
bus = gst_element_get_bus (pipeline);
bus_source = gst_bus_create_watch (bus);

View file

@ -5,6 +5,7 @@
IBOutlet UILabel *message_label;
IBOutlet UIBarButtonItem *play_button;
IBOutlet UIBarButtonItem *pause_button;
IBOutlet UIView *video_view;
}
-(IBAction) play:(id)sender;

View file

@ -21,7 +21,7 @@
play_button.enabled = FALSE;
pause_button.enabled = FALSE;
gst_backend = [[GStreamerBackend alloc] init:self];
gst_backend = [[GStreamerBackend alloc] init:self videoView:video_view];
}
- (void)didReceiveMemoryWarning

View file

@ -36,14 +36,21 @@
<barButtonItem style="plain" systemItem="flexibleSpace" id="urI-U7-ALw"/>
</items>
</toolbar>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="6tN-97-YoQ" userLabel="Video" customClass="EaglUIView">
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="trailing" secondItem="6tN-97-YoQ" secondAttribute="trailing" constant="20" symbolic="YES" type="user" id="Ah6-li-39g"/>
<constraint firstItem="6tN-97-YoQ" firstAttribute="top" secondItem="CqS-Gu-I1O" secondAttribute="top" constant="20" symbolic="YES" type="user" id="Aql-a6-cst"/>
<constraint firstItem="iLX-h1-Ko5" firstAttribute="bottom" secondItem="MUi-CE-Ydy" secondAttribute="top" constant="8" symbolic="YES" type="user" id="FXP-eH-VSK"/>
<constraint firstItem="MUi-CE-Ydy" firstAttribute="leading" secondItem="CqS-Gu-I1O" secondAttribute="leading" constant="20" symbolic="YES" type="user" id="OM9-gE-OVP"/>
<constraint firstAttribute="trailing" secondItem="iLX-h1-Ko5" secondAttribute="trailing" constant="20" symbolic="YES" type="user" id="Xdr-12-E1r"/>
<constraint firstItem="iLX-h1-Ko5" firstAttribute="leading" secondItem="CqS-Gu-I1O" secondAttribute="leading" constant="20" symbolic="YES" type="user" id="bT2-TE-X7Q"/>
<constraint firstItem="MUi-CE-Ydy" firstAttribute="trailing" secondItem="CqS-Gu-I1O" secondAttribute="trailing" constant="20" symbolic="YES" type="user" id="iRT-XF-W0f"/>
<constraint firstItem="6tN-97-YoQ" firstAttribute="leading" secondItem="CqS-Gu-I1O" secondAttribute="leading" constant="20" symbolic="YES" type="user" id="mV8-P0-4eW"/>
<constraint firstItem="iLX-h1-Ko5" firstAttribute="top" secondItem="6tN-97-YoQ" secondAttribute="bottom" constant="8" symbolic="YES" type="default" id="rJy-I3-pX7"/>
<constraint firstItem="MUi-CE-Ydy" firstAttribute="bottom" secondItem="CqS-Gu-I1O" secondAttribute="bottom" constant="20" symbolic="YES" type="user" id="w6K-xy-EJe"/>
</constraints>
</view>
@ -52,6 +59,7 @@
<outlet property="message_label" destination="iLX-h1-Ko5" id="Q0Y-3J-zis"/>
<outlet property="pause_button" destination="J3O-8j-Tkt" id="Dls-sg-FPm"/>
<outlet property="play_button" destination="UlF-Ga-2VX" id="243-yq-GEe"/>
<outlet property="video_view" destination="6tN-97-YoQ" id="Q0n-dR-hqv"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iRS-GG-bR6" sceneMemberID="firstResponder"/>
@ -59,6 +67,9 @@
</scene>
</scenes>
<classes>
<class className="EaglUIView" superclassName="UIView">
<source key="sourceIdentifier" type="project" relativePath="./Classes/EaglUIView.h"/>
</class>
<class className="ViewController" superclassName="UIViewController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/ViewController.h"/>
<relationships>
@ -68,6 +79,7 @@
<relationship kind="outlet" name="message_label" candidateClass="UILabel"/>
<relationship kind="outlet" name="pause_button" candidateClass="UIBarButtonItem"/>
<relationship kind="outlet" name="play_button" candidateClass="UIBarButtonItem"/>
<relationship kind="outlet" name="video_view" candidateClass="UIView"/>
</relationships>
</class>
</classes>

View file

@ -36,15 +36,22 @@
<barButtonItem style="plain" systemItem="flexibleSpace" id="hSc-4x-myS"/>
</items>
</toolbar>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="EZT-e2-iX7" userLabel="Video" customClass="EaglUIView">
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
</view>
</subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints>
<constraint firstItem="EZT-e2-iX7" firstAttribute="top" secondItem="JOS-rK-Hts" secondAttribute="top" constant="20" symbolic="YES" type="user" id="3UH-b4-lHN"/>
<constraint firstItem="8wd-E5-Owx" firstAttribute="bottom" secondItem="o22-1p-nvT" secondAttribute="top" constant="8" symbolic="YES" type="user" id="CHF-CI-6CL"/>
<constraint firstItem="8wd-E5-Owx" firstAttribute="top" secondItem="EZT-e2-iX7" secondAttribute="bottom" constant="8" symbolic="YES" type="user" id="V6c-5k-eSb"/>
<constraint firstAttribute="trailing" secondItem="8wd-E5-Owx" secondAttribute="trailing" constant="20" symbolic="YES" type="user" id="WDw-jT-tbz"/>
<constraint firstItem="o22-1p-nvT" firstAttribute="leading" secondItem="JOS-rK-Hts" secondAttribute="leading" constant="20" symbolic="YES" type="user" id="Zvb-2h-v7A"/>
<constraint firstItem="o22-1p-nvT" firstAttribute="bottom" secondItem="JOS-rK-Hts" secondAttribute="bottom" constant="20" symbolic="YES" type="user" id="l3D-e3-Z7R"/>
<constraint firstItem="8wd-E5-Owx" firstAttribute="leading" secondItem="JOS-rK-Hts" secondAttribute="leading" constant="20" symbolic="YES" type="user" id="lwj-ty-IXl"/>
<constraint firstItem="o22-1p-nvT" firstAttribute="trailing" secondItem="JOS-rK-Hts" secondAttribute="trailing" constant="20" symbolic="YES" type="user" id="mL0-QH-ra6"/>
<constraint firstItem="EZT-e2-iX7" firstAttribute="leading" secondItem="JOS-rK-Hts" secondAttribute="leading" constant="20" symbolic="YES" type="user" id="onN-nz-NjL"/>
<constraint firstAttribute="trailing" secondItem="EZT-e2-iX7" secondAttribute="trailing" constant="20" symbolic="YES" type="user" id="sLo-Ka-Lf5"/>
</constraints>
</view>
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics"/>
@ -52,12 +59,30 @@
<outlet property="message_label" destination="8wd-E5-Owx" id="7Xw-cg-3hH"/>
<outlet property="pause_button" destination="bfY-YY-jiu" id="GBf-vm-mbR"/>
<outlet property="play_button" destination="6LZ-7a-xKf" id="Tk2-4w-9Px"/>
<outlet property="video_view" destination="EZT-e2-iX7" id="Ep9-eG-Grh"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="25z-hu-OZW" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
<classes>
<class className="EaglUIView" superclassName="UIView">
<source key="sourceIdentifier" type="project" relativePath="./Classes/EaglUIView.h"/>
</class>
<class className="ViewController" superclassName="UIViewController">
<source key="sourceIdentifier" type="project" relativePath="./Classes/ViewController.h"/>
<relationships>
<relationship kind="action" name="pause:"/>
<relationship kind="action" name="play:"/>
<relationship kind="outlet" name="label" candidateClass="UILabel"/>
<relationship kind="outlet" name="message_label" candidateClass="UILabel"/>
<relationship kind="outlet" name="pause_button" candidateClass="UIBarButtonItem"/>
<relationship kind="outlet" name="play_button" candidateClass="UIBarButtonItem"/>
<relationship kind="outlet" name="video_view" candidateClass="UIView"/>
</relationships>
</class>
</classes>
<simulatedMetricsContainer key="defaultSimulatedMetrics">
<simulatedStatusBarMetrics key="statusBar"/>
<simulatedOrientationMetrics key="orientation"/>

View file

@ -16,7 +16,7 @@
#define GST_IOS_PLUGINS_SYS
//#define GST_IOS_PLUGINS_VIS
#define GST_IOS_PLUGINS_PLAYBACK
//#define GST_IOS_PLUGINS_EFFECTS
#define GST_IOS_PLUGINS_EFFECTS
//#define GST_IOS_PLUGINS_CODECS
//#define GST_IOS_PLUGINS_NET