一篇不错的gstream的component开发代码

来源:互联网 发布:微信淘宝客 编辑:程序博客网 时间:2024/05/29 16:24

http://publicsvn.songbirdnest.com/browser/trunk/components/mediacore/playback/gstreamer/src/sbGStreamerSimple.cpp?rev=2484

 

  Developer Center Add-ons Community Support Blog About Jobs  

root/trunk/components/mediacore/playback/gstreamer/src/sbGStreamerSimple.cpp

Revision 2484, 16.3 kB (checked in by ben, 2 years ago)

Updating line ending restrictions

  • Property svn:eol-style set to LF
Line   1 #include "sbGStreamerSimple.h" 2 #include "nsIInterfaceRequestorUtils.h" 3   4 #include "nsIWebNavigation.h" 5 #include "nsIDOMDocument.h" 6 #include "nsIDOMDocumentView.h" 7 #include "nsIDOMXULElement.h" 8 #include "nsIDOMAbstractView.h" 9 #include "nsIDocShellTreeItem.h" 10 #include "nsIDocShellTreeOwner.h" 11 #include "nsIDOMEventTarget.h" 12 #include "nsIDOMEvent.h" 13 #include "nsIDOMEventListener.h" 14 #include "nsIDOMWindow.h" 15 #include "nsIDocument.h" 16 #include "nsIScriptGlobalObject.h" 17 #include "nsIBaseWindow.h" 18 #include "nsIWidget.h" 19 #include "nsIBoxObject.h" 20 #include "nsString.h" 21 #include "prlog.h" 22   23 #if defined( PR_LOGGING ) 24 extern PRLogModuleInfo* gGStreamerLog; 25 #define LOG(args) PR_LOG(gGStreamerLog, PR_LOG_DEBUG, args) 26 #else 27 #define LOG(args) 28 #endif 29   30 NS_IMPL_ISUPPORTS2(sbGStreamerSimple, sbIGStreamerSimple, nsIDOMEventListener) 31   32 static GstBusSyncReply 33 syncHandlerHelper(GstBus* bus, GstMessage* message, gpointer data) 34 { 35   sbGStreamerSimple* gsts = NS_STATIC_CAST(sbGStreamerSimple*, data); 36   return gsts->SyncHandler(bus, message); 37 } 38   39 static void 40 streamInfoSetHelper(GObject* obj, GParamSpec* pspec, sbGStreamerSimple* gsts) 41 { 42   gsts->StreamInfoSet(obj, pspec); 43 } 44   45 static void 46 capsSetHelper(GObject* obj, GParamSpec* pspec, sbGStreamerSimple* gsts) 47 { 48   gsts->CapsSet(obj, pspec); 49 } 50   51 sbGStreamerSimple::sbGStreamerSimple() : 52   mInitialized(PR_FALSE), 53   mPlay(NULL), 54   mBus(NULL), 55   mPixelAspectRatioN(1), 56   mPixelAspectRatioD(1), 57   mVideoSink(NULL), 58   mGdkWin(NULL), 59   mIsAtEndOfStream(PR_TRUE), 60   mLastErrorCode(0), 61   mVideoOutputElement(nsnull), 62   mDomWindow(nsnull) 63 { 64   mArtist.Assign(EmptyString()); 65   mAlbum.Assign(EmptyString()); 66   mTitle.Assign(EmptyString()); 67   mGenre.Assign(EmptyString()); 68 } 69   70 sbGStreamerSimple::~sbGStreamerSimple() 71 { 72   if(mPlay != NULL && GST_IS_ELEMENT(mPlay)) { 73     gst_element_set_state(mPlay, GST_STATE_NULL); 74     gst_object_unref(mPlay); 75     mPlay = NULL; 76   } 77   78   // Do i need to close the video window? 79   80   mDomWindow = nsnull; 81   mVideoOutputElement = nsnull; 82 } 83   84 NS_IMETHODIMP 85 sbGStreamerSimple::Init(nsIDOMXULElement* aVideoOutput) 86 { 87   nsresult rv; 88   89   if(mInitialized) { 90     return NS_OK; 91   } 92   93   if(aVideoOutput == nsnull) { 94     return NS_ERROR_INVALID_ARG; 95   } 96   97   mVideoOutputElement = aVideoOutput; 98   99   // Get a handle to the xul element's native window 100   nsCOMPtr<nsIDOMDocument> domDocument; 101   rv = aVideoOutput->GetOwnerDocument(getter_AddRefs(domDocument)); 102   NS_ENSURE_SUCCESS(rv, rv); 103   104   nsCOMPtr<nsIDOMDocumentView> domDocumentView(do_QueryInterface(domDocument)); 105   NS_ENSURE_TRUE(domDocumentView, NS_NOINTERFACE); 106   107   nsCOMPtr<nsIDOMAbstractView> domAbstractView; 108   rv = domDocumentView->GetDefaultView(getter_AddRefs(domAbstractView)); 109   NS_ENSURE_SUCCESS(rv, rv); 110   111   nsCOMPtr<nsIWebNavigation> webNavigation(do_GetInterface(domAbstractView)); 112   nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem(do_QueryInterface(webNavigation)); 113   NS_ENSURE_TRUE(docShellTreeItem, NS_NOINTERFACE); 114   115   nsCOMPtr<nsIDocShellTreeOwner> docShellTreeOwner; 116   rv = docShellTreeItem->GetTreeOwner(getter_AddRefs(docShellTreeOwner)); 117   NS_ENSURE_SUCCESS(rv, rv); 118   119   nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(docShellTreeOwner); 120   NS_ENSURE_TRUE(baseWindow, NS_NOINTERFACE); 121   122   nsCOMPtr<nsIWidget> widget; 123   rv = baseWindow->GetMainWidget(getter_AddRefs(widget)); 124   NS_ENSURE_SUCCESS(rv, rv); 125   126   // Attach event listeners 127   nsCOMPtr<nsIDocument> document(do_QueryInterface(domDocument)); 128   NS_ENSURE_TRUE(document, NS_NOINTERFACE); 129   130   mDomWindow = do_QueryInterface(document->GetScriptGlobalObject()); 131   NS_ENSURE_TRUE(mDomWindow, NS_NOINTERFACE); 132   133   nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(mDomWindow)); 134   NS_ENSURE_TRUE(target, NS_NOINTERFACE); 135   target->AddEventListener(NS_LITERAL_STRING("resize"), this, PR_FALSE); 136   target->AddEventListener(NS_LITERAL_STRING("unload"), this, PR_FALSE); 137   138   GdkWindow* win = GDK_WINDOW(widget->GetNativeData(NS_NATIVE_WIDGET)); 139   140   LOG(("Found native window %x", win)); 141   142   // Create the video window 143   GdkWindowAttr attributes; 144   145   attributes.window_type = GDK_WINDOW_CHILD; 146   attributes.x = 0; 147   attributes.y = 0; 148   attributes.width = 0; 149   attributes.height = 0; 150   attributes.wclass = GDK_INPUT_OUTPUT; 151   attributes.event_mask = 0; 152   153   mGdkWin = gdk_window_new(win, &attributes, GDK_WA_X | GDK_WA_Y); 154   gdk_window_show(mGdkWin); 155   // Set up the playbin 156   mPlay = gst_element_factory_make("playbin", "play"); 157   GstElement *audioSink = gst_element_factory_make("gconfaudiosink", "audio-sink"); 158   g_object_set(mPlay, "audio-sink", audioSink, NULL); 159   160   // TODO: use gconf video config here? 161   mVideoSink = gst_element_factory_make("ximagesink", "video-sink"); 162   g_object_set(mPlay, "video-sink", mVideoSink, NULL); 163   164   mBus = gst_element_get_bus(mPlay); 165   gst_bus_set_sync_handler(mBus, &syncHandlerHelper, this); 166   167   // This signal lets us get info about the stream 168   g_signal_connect(mPlay, "notify::stream-info", 169     G_CALLBACK(streamInfoSetHelper), this); 170   171   mInitialized = PR_TRUE; 172   173   return NS_OK; 174 } 175   176 NS_IMETHODIMP 177 sbGStreamerSimple::GetUri(nsAString& aUri) 178 { 179   if(!mInitialized) { 180     return NS_ERROR_NOT_INITIALIZED; 181   } 182   183   GValue value = { 0, }; 184   g_value_init(&value, G_TYPE_STRING); 185   g_object_get_property(G_OBJECT(mPlay), "uri", &value); 186   187   nsCAutoString uri; 188   uri.Assign(g_value_get_string(&value)); 189   190   g_value_unset(&value); 191   192   CopyUTF8toUTF16(uri, aUri); 193   194   return NS_OK; 195 } 196 NS_IMETHODIMP 197 sbGStreamerSimple::SetUri(const nsAString& aUri) 198 { 199   if(!mInitialized) { 200     return NS_ERROR_NOT_INITIALIZED; 201   } 202   203   // XXX: What are these glib strings? 204   g_object_set(G_OBJECT(mPlay), "uri", NS_ConvertUTF16toUTF8(aUri).get(), NULL); 205   206   mArtist.Assign(EmptyString()); 207   mAlbum.Assign(EmptyString()); 208   mTitle.Assign(EmptyString()); 209   mGenre.Assign(EmptyString()); 210   211   return NS_OK; 212 } 213   214 NS_IMETHODIMP 215 sbGStreamerSimple::GetVolume(double* aVolume) 216 { 217   if(!mInitialized) { 218     return NS_ERROR_NOT_INITIALIZED; 219   } 220   221   g_object_get(G_OBJECT(mPlay), "volume", aVolume, NULL); 222   223   return NS_OK; 224 } 225   226 NS_IMETHODIMP 227 sbGStreamerSimple::SetVolume(double aVolume) 228 { 229   if(!mInitialized) { 230     return NS_ERROR_NOT_INITIALIZED; 231   } 232   233   g_object_set(mPlay, "volume", aVolume, NULL); 234   235   return NS_OK; 236 } 237   238 NS_IMETHODIMP 239 sbGStreamerSimple::GetPosition(PRUint64* aPosition) 240 { 241   if(!mInitialized) { 242     return NS_ERROR_NOT_INITIALIZED; 243   } 244   245   nsresult rv; 246   247   GstQuery *query; 248   gboolean res; 249   query = gst_query_new_position(GST_FORMAT_TIME); 250   res = gst_element_query(mPlay, query); 251   if(res) { 252     gint64 position; 253     gst_query_parse_position(query, NULL, &position); 254     *aPosition = position; 255     rv = NS_OK; 256   } 257   else { 258     rv = NS_ERROR_NOT_AVAILABLE; 259   } 260   261   gst_query_unref (query); 262   263   return rv; 264 } 265   266 NS_IMETHODIMP 267 sbGStreamerSimple::GetIsPlaying(PRBool* aIsPlaying) 268 { 269   if(!mInitialized) { 270     return NS_ERROR_NOT_INITIALIZED; 271   } 272   273   GstState cur, pending; 274   275   gst_element_get_state(mPlay, &cur, &pending, 0); 276   277   if(cur == GST_STATE_PLAYING || pending == GST_STATE_PLAYING) { 278     *aIsPlaying = PR_TRUE; 279   } 280   else { 281     *aIsPlaying = PR_FALSE; 282   } 283   284   return NS_OK; 285 } 286   287 NS_IMETHODIMP 288 sbGStreamerSimple::GetIsPaused(PRBool* aIsPaused) 289 { 290   if(!mInitialized) { 291     return NS_ERROR_NOT_INITIALIZED; 292   } 293   294   GstState cur, pending; 295   296   gst_element_get_state(mPlay, &cur, &pending, 0); 297   298   if(cur == GST_STATE_PAUSED || pending == GST_STATE_PAUSED) { 299     *aIsPaused = PR_TRUE; 300   } 301   else { 302     *aIsPaused = PR_FALSE; 303   } 304   305   return NS_OK; 306 } 307   308 NS_IMETHODIMP 309 sbGStreamerSimple::GetStreamLength(PRUint64* aStreamLength) 310 { 311   if(!mInitialized) { 312     return NS_ERROR_NOT_INITIALIZED; 313   } 314   315   nsresult rv; 316   317   GstQuery *query; 318   gboolean res; 319   query = gst_query_new_duration(GST_FORMAT_TIME); 320   res = gst_element_query(mPlay, query); 321   if(res) { 322     gint64 duration; 323     gst_query_parse_duration(query, NULL, &duration); 324     *aStreamLength = duration; 325     rv = NS_OK; 326   } 327   else { 328     rv = NS_ERROR_NOT_AVAILABLE; 329   } 330   331   gst_query_unref (query); 332   333   return rv; 334 } 335   336 NS_IMETHODIMP 337 sbGStreamerSimple::GetIsAtEndOfStream(PRBool* aIsAtEndOfStream) 338 { 339   if(!mInitialized) { 340     return NS_ERROR_NOT_INITIALIZED; 341   } 342   343   *aIsAtEndOfStream = mIsAtEndOfStream; 344   345   return NS_OK; 346 } 347   348 NS_IMETHODIMP 349 sbGStreamerSimple::GetLastErrorCode(PRInt32* aLastErrorCode) 350 { 351   if(!mInitialized) { 352     return NS_ERROR_NOT_INITIALIZED; 353   } 354   355   *aLastErrorCode = mLastErrorCode; 356   357   return NS_OK; 358 } 359   360 NS_IMETHODIMP 361 sbGStreamerSimple::GetArtist(nsAString& aArtist) 362 { 363   if(!mInitialized) { 364     return NS_ERROR_NOT_INITIALIZED; 365   } 366   367   aArtist.Assign(mArtist); 368   369   return NS_OK; 370 } 371   372 NS_IMETHODIMP 373 sbGStreamerSimple::GetAlbum(nsAString& aAlbum) 374 { 375   if(!mInitialized) { 376     return NS_ERROR_NOT_INITIALIZED; 377   } 378   379   aAlbum.Assign(mAlbum); 380   381   return NS_OK; 382 } 383   384 NS_IMETHODIMP 385 sbGStreamerSimple::GetTitle(nsAString& aTitle) 386 { 387   if(!mInitialized) { 388     return NS_ERROR_NOT_INITIALIZED; 389   } 390   391   aTitle.Assign(mTitle); 392   393   return NS_OK; 394 } 395   396 NS_IMETHODIMP 397 sbGStreamerSimple::GetGenre(nsAString& aGenre) 398 { 399   if(!mInitialized) { 400     return NS_ERROR_NOT_INITIALIZED; 401   } 402   403   aGenre.Assign(mGenre); 404   405   return NS_OK; 406 } 407   408 NS_IMETHODIMP 409 sbGStreamerSimple::Play() 410 { 411   if(!mInitialized) { 412     return NS_ERROR_NOT_INITIALIZED; 413   } 414   415   gst_element_set_state(mPlay, GST_STATE_PLAYING); 416   mIsAtEndOfStream = PR_FALSE; 417   mLastErrorCode = 0; 418   419   return NS_OK; 420 } 421   422 NS_IMETHODIMP 423 sbGStreamerSimple::Pause() 424 { 425   if(!mInitialized) { 426     return NS_ERROR_NOT_INITIALIZED; 427   } 428   429   gst_element_set_state(mPlay, GST_STATE_PAUSED); 430   431   return NS_OK; 432 } 433   434 NS_IMETHODIMP 435 sbGStreamerSimple::Stop() 436 { 437   if(!mInitialized) { 438     return NS_ERROR_NOT_INITIALIZED; 439   } 440   441   gst_element_set_state(mPlay, GST_STATE_NULL); 442   443   return NS_OK; 444 } 445   446 NS_IMETHODIMP 447 sbGStreamerSimple::Seek(PRUint64 aTimeNanos) 448 { 449   if(!mInitialized) { 450     return NS_ERROR_NOT_INITIALIZED; 451   } 452   453   gst_element_seek(mPlay, 1.0, 454       GST_FORMAT_TIME, 455       GstSeekFlags(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT), 456       GST_SEEK_TYPE_SET, aTimeNanos, 457       GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE); 458   459   return NS_OK; 460 } 461   462 // nsIDOMEventListener 463 NS_IMETHODIMP 464 sbGStreamerSimple::HandleEvent(nsIDOMEvent* aEvent) 465 { 466   nsAutoString eventType; 467   aEvent->GetType(eventType); 468   469   if(eventType.EqualsLiteral("unload")) { 470   471     // Clean up here 472     nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(mDomWindow)); 473     NS_ENSURE_TRUE(target, NS_NOINTERFACE); 474     target->RemoveEventListener(NS_LITERAL_STRING("resize"), this, PR_FALSE); 475     target->RemoveEventListener(NS_LITERAL_STRING("unload"), this, PR_FALSE); 476   477     mDomWindow = nsnull; 478     mVideoOutputElement = nsnull; 479   480     mInitialized = PR_FALSE; 481   482     return NS_OK; 483   } 484   else { 485     return Resize(); 486   } 487   488 } 489   490 NS_IMETHODIMP 491 sbGStreamerSimple::Resize() 492 { 493   PRInt32 x, y, width, height; 494   nsCOMPtr<nsIBoxObject> boxObject; 495   mVideoOutputElement->GetBoxObject(getter_AddRefs(boxObject)); 496   boxObject->GetX(&x); 497   boxObject->GetY(&y); 498   boxObject->GetWidth(&width); 499   boxObject->GetHeight(&height); 500   501   PRInt32 newX, newY, newWidth, newHeight; 502   503   if(mVideoWidth > 0 && mVideoHeight > 0) { 504   505     float ratioWidth  = (float) width  / (float) mVideoWidth; 506     float ratioHeight = (float) height / (float) mVideoHeight; 507     if(ratioWidth < ratioHeight) { 508       newWidth  = PRInt32(mVideoWidth  * ratioWidth); 509       newHeight = PRInt32(mVideoHeight * ratioWidth); 510       newX = x; 511       newY = ((height - newHeight) / 2) + y; 512     } 513     else { 514       newWidth  = PRInt32(mVideoWidth  * ratioHeight); 515       newHeight = PRInt32(mVideoHeight * ratioHeight); 516       newX = ((width - newWidth) / 2) + x; 517       newY = y; 518     } 519   520     gdk_window_move_resize(mGdkWin, newX, newY, newWidth, newHeight); 521   } 522   523   return NS_OK; 524 } 525   526 // Callbacks 527 GstBusSyncReply 528 sbGStreamerSimple::SyncHandler(GstBus* bus, GstMessage* message) 529 { 530   GstMessageType msg_type; 531   msg_type = GST_MESSAGE_TYPE(message); 532   533   switch (msg_type) { 534     case GST_MESSAGE_ERROR: { 535       GError *error = NULL; 536       gchar *debug = NULL; 537   538       gst_message_parse_error(message, &error, &debug); 539   540       LOG(("Error message: %s [%s]", GST_STR_NULL (error->message), GST_STR_NULL (debug))); 541   542       g_free (debug); 543   544       mLastErrorCode = error->code; 545       mIsAtEndOfStream = PR_TRUE; 546   547       break; 548     } 549     case GST_MESSAGE_WARNING: { 550       GError *error = NULL; 551       gchar *debug = NULL; 552   553       gst_message_parse_warning(message, &error, &debug); 554   555       LOG(("Warning message: %s [%s]", GST_STR_NULL (error->message), GST_STR_NULL (debug))); 556   557       g_warning ("%s [%s]", GST_STR_NULL (error->message), GST_STR_NULL (debug)); 558   559       g_error_free (error); 560       g_free (debug); 561       break; 562     } 563   564     case GST_MESSAGE_EOS: { 565       mIsAtEndOfStream = PR_TRUE; 566       break; 567     } 568   569     case GST_MESSAGE_STATE_CHANGED: { 570       GstState old_state, new_state; 571       gchar *src_name; 572   573       gst_message_parse_state_changed(message, &old_state, &new_state, NULL); 574   575       src_name = gst_object_get_name(message->src); 576       LOG(("stage-changed: %s changed state from %s to %s", src_name, 577           gst_element_state_get_name (old_state), 578           gst_element_state_get_name (new_state))); 579       g_free (src_name); 580       break; 581     } 582   583     case GST_MESSAGE_ELEMENT: { 584       if(gst_structure_has_name(message->structure, "prepare-xwindow-id") && mVideoSink != NULL) { 585         GstElement *element = NULL; 586         GstXOverlay *xoverlay = NULL; 587   588         if (GST_IS_BIN (mVideoSink)) { 589           element = gst_bin_get_by_interface (GST_BIN (mVideoSink), 590                                               GST_TYPE_X_OVERLAY); 591         } 592         else { 593           element = mVideoSink; 594         } 595   596         if (GST_IS_X_OVERLAY (element)) { 597           xoverlay = GST_X_OVERLAY (element); 598         } 599         else { 600           xoverlay = NULL; 601         } 602   603         XID window = GDK_WINDOW_XWINDOW(mGdkWin); 604         gst_x_overlay_set_xwindow_id(xoverlay, window); 605         LOG(("Set xoverlay %d to windowid %d/n", xoverlay, window)); 606       } 607       break; 608     } 609   610     case GST_MESSAGE_TAG: { 611       GstTagList *tag_list; 612       gchar *value = NULL; 613       nsCAutoString temp; 614   615       gst_message_parse_tag(message, &tag_list); 616   617       if(gst_tag_list_get_string(tag_list, GST_TAG_ARTIST, &value)) { 618         temp.Assign(value); 619         mArtist.Assign(NS_ConvertUTF8toUTF16(temp).get()); 620         g_free(value); 621       } 622   623       if(gst_tag_list_get_string(tag_list, GST_TAG_ALBUM, &value)) { 624         temp.Assign(value); 625         mAlbum.Assign(NS_ConvertUTF8toUTF16(temp).get()); 626         g_free(value); 627       } 628   629       if(gst_tag_list_get_string(tag_list, GST_TAG_TITLE, &value)) { 630         temp.Assign(value); 631         mTitle.Assign(NS_ConvertUTF8toUTF16(temp).get()); 632         g_free(value); 633       } 634   635       if(gst_tag_list_get_string(tag_list, GST_TAG_GENRE, &value)) { 636         temp.Assign(value); 637         mGenre.Assign(NS_ConvertUTF8toUTF16(temp).get()); 638         g_free(value); 639       } 640   641       gst_tag_list_free(tag_list); 642       break; 643     } 644   645     default: 646       LOG(("Got message: %s", gst_message_type_get_name(msg_type))); 647   } 648   649   //gst_message_unref(message); XXX: Do i need to unref this? 650   651   return GST_BUS_PASS; 652 } 653   654 void 655 sbGStreamerSimple::StreamInfoSet(GObject* obj, GParamSpec* pspec) 656 { 657   GList *streaminfo = NULL; 658   GstPad *videopad = NULL; 659   660   g_object_get (mPlay, "stream-info", &streaminfo, NULL); 661   streaminfo = g_list_copy(streaminfo); 662   g_list_foreach (streaminfo, (GFunc) g_object_ref, NULL); 663   for( ; streaminfo != NULL; streaminfo = streaminfo->next) { 664     GObject *info = (GObject*) streaminfo->data; 665     gint type; 666     GParamSpec *pspec; 667     GEnumValue *val; 668   669     if(!info) { 670       continue; 671     } 672   673     g_object_get (info, "type", &type, NULL); 674     pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (info), "type"); 675     val = g_enum_get_value (G_PARAM_SPEC_ENUM (pspec)->enum_class, type); 676   677     if(!g_strcasecmp (val->value_nick, "video")) { 678       if (!videopad) { 679         g_object_get(info, "object", &videopad, NULL); 680       } 681     } 682   } 683   684   if(videopad) { 685     GstCaps *caps; 686   687     if((caps = gst_pad_get_negotiated_caps(videopad))) { 688       CapsSet(G_OBJECT(videopad), NULL); 689       gst_caps_unref(caps); 690     } 691     g_signal_connect(videopad, "notify::caps", G_CALLBACK(capsSetHelper), this); 692   } 693   694   g_list_foreach (streaminfo, (GFunc) g_object_unref, NULL); 695   g_list_free (streaminfo); 696 } 697   698 void 699 sbGStreamerSimple::CapsSet(GObject* obj, GParamSpec* pspec) 700 { 701   GstPad *pad = GST_PAD(obj); 702   GstStructure *s; 703   GstCaps *caps; 704   705   if(!(caps = gst_pad_get_negotiated_caps(pad))) { 706     return; 707   } 708   709   s = gst_caps_get_structure(caps, 0); 710   if(s) { 711     gst_structure_get_int(s, "width", &mVideoWidth); 712     gst_structure_get_int(s, "height", &mVideoHeight); 713   714     const GValue* par = gst_structure_get_value(s, "pixel-aspect-ratio"); 715     mPixelAspectRatioN = gst_value_get_fraction_numerator(par); 716     mPixelAspectRatioD = gst_value_get_fraction_denominator(par); 717   718     Resize(); 719   } 720   721   gst_caps_unref(caps); 722 } 723  
Note: See TracBrowser for help on using the browser.
  • Home
  • About
  • Jobs

© 2005-2008 POTI, Inc. Mozilla and Firefox are registered trademarks of the Mozilla Foundation.


原创粉丝点击