Flow of events during Media Player creation in Android

  • 215 views
Uploaded on

This document is a code walk through for the media player subsystem in Android

This document is a code walk through for the media player subsystem in Android

More in: Technology , Education
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
215
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
6
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Flow of events during Media Player Creation in Android Somenath Mukhopadhyay som.mukhopadhyay@gmail.com The flow of events of the Android media player is complex. This document will serve as a hand-holding for code walkthrough of the Android multimedia framework for the Android lovers. To start with, let me give you the call stack of the media player framework in Android. This has been depicted as in the following diagram. Now lets come to the fact findings. There are two sides of the Android Media Framework. What we as an user see is the Java interface which is called the Mediaplayer.java. However, this java interface interacts with a native mediaplayer object through Java Native Interface (JNI) mechanism. This interaction is done through the functionalities defined in Android_media_Mediaplayer.cpp. In this file the framework engineers have kept all the necessary JNI functions. Now when we are about to start the MediaPlayer, the JNI function that is called is the private native final void native_setup. This function is actually responsible for creating a C++ mediaplayer object in the native side and storing it as an opaque reference in the Java client side. So when we interact with the client side Java mediaplayer object, we internally interact with this native C++ object.
  • 2. The JNI layer actually delegates its task to a Mediaplayer object. The functionalities of this C++ class are defined in the file Mediaplayer.cpp. Now the next step is that we set a data source in the Java side using the function setDataSource function in which the URI of the data source is passed. This in turn calls the native function android_media_MediaPlayer_setDataSource(JNIEnv *env, jobject thiz, jstring path) In the native source, this function is defined as adodmdaMdalyrstaaoreJIn *n,jbetti,jtigpt) nri_ei_eiPae_eDtSuc(NEv ev ojc hz srn ah { s < e i P a e >m =g t e i P a e ( n , t i ) pMdalyr  p   eMdalyrev hz; i  ( p =  N L  ) { f m = UL jihoEcpinev "aaln/leaSaexeto" NL) nTrwxeto(n, jv/agIlglttEcpin, UL; rtr; eun } i  ( a h =  N L ) { f pt = UL jihoEcpinev "aaln/leaAgmnEcpin,NL) nTrwxeto(n, jv/agIlglruetxeto" UL; rtr; eun } c n tc a  * a h t =e v > e S r n U F h r ( a h N L ) os  hr ptSr   n-GttigTCaspt, UL; i  ( a h t =  N L ) { / O t o m m r f ptSr = UL / u f eoy jihoEcpinev "aaln/utmEcpin,"u o mmr"; nTrwxeto(n, jv/agRniexeto" Ot f eoy) rtr; eun } LG(staaore pt %" ptSr; OV"eDtSuc: ah s, aht) s a u _  o S a u =m - s t a a o r e p t S r ; ttst ptts   p>eDtSuc(aht) / Mk sr ta lclrfi rlae bfr aptnilecpin / ae ue ht oa e s eesd eoe oeta xeto ev>eesSrnUFhr(ah ptSr; n-RlaetigTCaspt, aht) poesmdapae_al ev ti,oSau,"aai/Oxeto" "eDtSuc rcs_ei_lyrcl( n, hz ptts jv/oIEcpin, staaore f i e .  ) ald" ; } Look at the line: status_t opStatus = mp->setDataSource(pathStr); This function is defined as s a u _  M d a l y r : e D t S u c ( o s  c a  * r ) ttst eiPae:staaorecnt hr ul { LG(staaore%),ul; OV"eDtSuc(s" r) s a u _  e r =B D V L E ttst r   A_AU; i  ( r !  N L ) { f ul = UL c n ts < M d a l y r e v c >  s r i e g t e i P a e S r i e ) ; os  pIeiPaeSrie& evc(eMdalyrevc() i  ( e v c !  0 { f srie = )
  • 3. s < M d a l y r  p a e ( e v c - c e t ( e p d ) t i , u l ) pIeiPae> lyrsrie>raegti(, hs r); e r =s t a a o r e p a e ) r   eDtSuc(lyr; } } r t r  e r eun r; } Look at the line : sp<IMediaPlayer> player(service->create(getpid(), this, url)); It actually takes the help of the IMediaPlayerservice layer and calls the create function on this. This function can be found in basemedialibmediaIMediaPlayerService.cpp file. The create function of the MediaPlayerService looks like the following. It can be found at basemedialibmediaplayerserviceMediaPlayerService.cpp. sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const s < M d a l y r  M d a l y r e v c : c e t ( i _  p d c n ts < M d a l y r l e t & pIeiPae> eiPaeSrie:raepdt i, os  pIeiPaeCin> c i n , c n tc a *u l let os  hr  r) { i t 2 tc n I =a d o d a o i _ n ( m e t o n d ; n3_  ond   nri_tmcic&NxCnI) s < l e t  c =n wC i n ( h s p d c n I , c i n ) pCin>   e  letti, i, ond let; LG(Cet nwcin(d fo pd%,ul%,cnI=d,cnI,pd ul cnI) OV"rae e let%) rm i d r=s ond%" ond i, r, ond; i  ( O E R R !  c > e D t S u c ( r ) f N_RO = -staaoreul) { ccer) .la(; r t r  c eun ; } w < l e t  w =c pCin>   ; Mtx:uooklc(Lc) ue:Atlc okmok; mlet.d() Cinsadw; r t r  c eun ; } Look at the line : sp<Client> c = new Client(this, pid, connId, client) The client constructor is as the following: s < M d a l y r  M d a l y r e v c : c e t ( i _  p d c n ts < M d a l y r l e t & pIeiPae> eiPaeSrie:raepdt i, os  pIeiPaeCin> c i n , c n tc a *u l let os  hr  r) { i t 2 tc n I =a d o d a o i _ n ( m e t o n d ; n3_  ond   nri_tmcic&NxCnI) s < l e t  c =n wC i n ( h s p d c n I , c i n ) pCin>   e  letti, i, ond let;
  • 4. LG(Cet nwcin(d fo pd%,ul%,cnI=d,cnI,pd ul cnI) OV"rae e let%) rm i d r=s ond%" ond i, r, ond; i  ( O E R R !  c > e D t S u c ( r ) f N_RO = -staaoreul) { ccer) .la(; r t r  c eun ; } w < l e t  w =c pCin>   ; Mtx:uooklc(Lc) ue:Atlc okmok; mlet.d() Cinsadw; r t r  c eun ; } Now look at the following line (line number 6) of sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url) if (NO_ERROR != c->setDataSource(url)) So we are basically calling the setDataSource on the Client. This function is like the following: s a u _  M d a l y r e v c : C i n : s t a a o r e c n tc a  * r ) ttst eiPaeSrie:let:eDtSuc(os  hr ul { LG(staaore%),ul; OV"eDtSuc(s" r) i  ( r =  N L ) f ul = UL r t r  U K O N E R R eun NNW_RO; i  ( t n m ( r , " o t n : / , 1 ) =  0 { f srcpul cnet/" 0 = ) / gtafldsrpo frtecnetUiad / e ieecitr o h otn r n / ps i t testaaoref)mto / as t o h eDtSuc(d ehd Srn1 ul6ul; tig6 r1(r) i tf =a d o d : p n o t n P o i e F l ( r 1 ) n  d   nri:oeCnetrvdrieul6; i  ( d <0 f f   ) { LG(Cud' oe f fr%" ul; OE"olnt pn d o s, r) r t r  U K O N E R R eun NNW_RO; } staaoref,0 07ffffL) / ti st mtts eDtSuc(d , xfffffL; / hs es Sau coef) ls(d; r t r  m t t s eun Sau; } e s  { le p a e _ y e p a e T p =g t l y r y e u l ; lyrtp lyrye   ePaeTp(r) LG(pae tp =%" paeTp) OV"lyr ye d, lyrye; / cet tergttp o pae / rae h ih ye f lyr s < e i P a e B s >p =c e t P a e ( l y r y e ; pMdalyrae    raelyrpaeTp) i  ( =  N L ) r t r  N _ N T f p = UL eun OII; i  ( p > a d a e u p t ) { f !-hrwrOtu()
  • 5. m u i O t u =n wA d o u p t ) Adoupt   e  uiOtu(; sai_atMdalyrnefc*(.e()>eAdoikmuiOtu) ttccs<eiPaeItrae>pgt)-stuiSn(Adoupt; } / nwstdt suc / o e aa ore LG( staaore) OV" eDtSuc"; m t t s =p > e D t S u c ( r ) Sau   -staaoreul; i  ( S a u =  N _ R O ) m l y r =p f mtts = OERR Pae   ; r t r  m t t s eun Sau; } } From the above code snippet it becomes clear that either we do i  ( t n m ( r , " o t n : / , 1 ) =  0 { f srcpul cnet/" 0 = ) / gtafldsrpo frtecnetUiad / e ieecitr o h otn r n / ps i t testaaoref)mto / as t o h eDtSuc(d ehd Srn1 ul6ul; tig6 r1(r) i tf =a d o d : p n o t n P o i e F l ( r 1 ) n  d   nri:oeCnetrvdrieul6; i  ( d <0 f f   ) { LG(Cud' oe f fr%" ul; OE"olnt pn d o s, r) r t r  U K O N E R R eun NNW_RO; } staaoref,0 07ffffL) / ti st mtts eDtSuc(d , xfffffL; / hs es Sau coef) ls(d; r t r  m t t s eun Sau; ● ● or we do the following: e s  { le p a e _ y e p a e T p =g t l y r y e u l ; / h r i e t a t t e P a e T p f o lyrtp lyrye   ePaeTp(r) /ee t xrcs h lyr ye rm teUL h R. LG(pae tp =%" paeTp) OV"lyr ye d, lyrye; / cet tergttp o pae / rae h ih ye f lyr s < e i P a e B s >p =c e t P a e ( l y r y e ; pMdalyrae    raelyrpaeTp) ....... ....... ....... ....... I t e f r t c s  t e s t a a o r e ( i e 1 ) f n t o l o s l k t e f l o i g n h is ae h eDtSuc ln 2 ucin ok ie h olwn: s a u _  M d a l y r e v c : C i n : s t a a o r e i tf , i t 4 to f e , i t 4 tl n t ) ttst eiPaeSrie:let:eDtSuc(n  d n6_  fst n6_  egh {
  • 6. LG(staaoref=d ofe=ld lnt=ld,f,ofe,lnt) OV"eDtSuc d%, fst%l, egh%l" d fst egh; s r c  s a s ; tut tt b i tr t =f t t f , & b ; n  e   sa(d s) i  ( e !  0 { f rt = ) LG(ftt%)fie:%,%" f,rt srro(rn); OE"sa(d ald d s, d e, terrero) r t r  U K O N E R R eun NNW_RO; } LG(s_e =%l" s.tdv; OV"tdv lu, bs_e) LG(s_oe=%" s.tmd) OV"tmd u, bs_oe; LG(s_i =%u,s.tud; OV"tud l" bs_i) LG(s_i =%u,s.tgd; OV"tgd l" bs_i) LG(s_ie=%l" s.tsz) OV"tsz lu, bs_ie; i  ( f s t >  s . t s z ) { f ofe = bs_ie LG(ofe err) OE"fst ro"; :coef) :ls(d; r t r  U K O N E R R eun NNW_RO; } i  ( f s t +l n t >s . t s z ) { f ofe   egh   bs_ie l n t =s . t s z -o f e ; egh   bs_ie   fst LG(cluae lnt =%l" lnt) OV"acltd egh ld, egh; } p a e _ y e p a e T p =g t l y r y e f , o f e , l n t ) / h r i g t t e f l t p lyrtp lyrye   ePaeTp(d fst egh; /ee t es h ie ye fo teFl dsrpo rm h ie ecitr LG(pae tp =%" paeTp) OV"lyr ye d, lyrye; / cet tergttp o pae / rae h ih ye f lyr s < e i P a e B s >p =c e t P a e ( l y r y e ; pMdalyrae    raelyrpaeTp) i  ( =  N L ) r t r  N _ N T f p = UL eun OII; i  ( p > a d a e u p t ) { f !-hrwrOtu() m u i O t u =n wA d o u p t ) Adoupt   e  uiOtu(; sai_atMdalyrnefc*(.e()>eAdoikmuiOtu) ttccs<eiPaeItrae>pgt)-stuiSn(Adoupt; } / nwstdt suc / o e aa ore m t t s =p > e D t S u c ( d o f e , l n t ) Sau   -staaoref, fst egh; i  ( S a u =  N _ R O ) m l y r =p f mtts = OERR Pae   ; r t r  m t t s eun Sau; } Look at the line : sp<MediaPlayerBase> p = createPlayer(playerType). It becomes clear that we create the player here. The sp<MediaPlayerBase> p = createPlayer (playerType) actually creates the right player.
  • 7. In the second case (the else part) we call sp<MediaPlayerBase> p = createPlayer(playerType) at line 6. We extract the file type from the URL. This helps us in creating the right player object. The createPlayer function looks like the following: s < e i P a e B s >M d a l y r e v c : C i n : c e t P a e ( l y r t p p a e T p ) pMdalyrae  eiPaeSrie:let:raelyrpae_ye lyrye { / dtriei w hv tergtpae tp / eemn f e ae h ih lyr ye s < e i P a e B s >p =m l y r pMdalyrae    Pae; i  ( p !  N L ) &  ( - p a e T p ( !  p a e T p ) { f ( = UL & p>lyrye) = lyrye) LG(dlt pae"; OV"eee lyr) pcer) .la(; } i  ( =  N L ) { f p = UL p =a d o d : r a e l y r p a e T p , t i , n t f )   nri:cetPae(lyrye hs oiy; } r t r  p eun ; } Hence it actually delegates the task to p = android::createPlayer(playerType, this, notify); The above function is as follows; s a i  s < e i P a e B s >c e t P a e ( l y r t p p a e T p , v i *c o i , ttc pMdalyrae  raelyrpae_ye lyrye od  oke ntf_alakfntfFn) oiyclbc_ oiyuc { s < e i P a e B s >p pMdalyrae  ; s i c  ( l y r y e { wth paeTp) #fdfN_PNOE ine OOECR c s  P _ L Y R ae VPAE: LG( cet PPae"; OV" rae Vlyr) p =n wP P a e ( ;   e  Vlyr) bek ra; #ni edf c s  S N V X P A E : ae OIO_LYR LG( cet MdFl"; OV" rae iiie) p =n wM d F l ( ;   e  iiie) bek ra; c s  V R I _ L Y R ae OBSPAE: LG( cet VriPae"; OV" rae obslyr) p =n wV r i P a e ( ;   e  obslyr) bek ra; } i  ( !  N L ) { f p = UL i  ( - i i C e k ) =  N _ R O ) { f p>nthc( = OERR p>eNtfClbc(oke ntfFn) -stoiyalakcoi, oiyuc; } e s  { le pcer) .la(; }
  • 8. } i  ( =  N L ) { f p = UL LG(Fie t cet pae ojc"; OE"ald o rae lyr bet) } r t r  p eun ; } Thus we find that the right player is created through the parameterized factory function createPlayer. i hope this explains how the right mediaplayer is created from the Uri passed in the Java client side interface of the Mediaplyer.