Sei sulla pagina 1di 117

Fundao Universidade Federal do Rio Grande

Engenharia de Computao

Streaming de Vdeo e udio via Multicast:


A FURG TV na Internet
Rafael Vieira Coelho

Rio Grande, 17 de Janeiro de 2008


Fundao Universidade Federal do Rio Grande
Engenharia de Computao

Streaming de Vdeo e udio via Multicast:


A FURG TV na Internet
Rafael Vieira Coelho

Trabalho de Concluso de Curso de


Graduao em Engenharia de Computao
submetido avaliao, como requisito
parcial obteno do Ttulo de Engenheiro
de Computao.

Orientador (a): Prof. Dr. Nelson Duarte Filho

Rio Grande, 17 de Janeiro de 2008

2
Este trabalho foi analisado e julgado adequado para a obteno do ttulo de Engenheiro de
Computao e aprovado em sua forma final pelo orientador.

________________________________
Prof. Dr. Nelson Lopes Duarte Filho

________________________________
Prof. Dra. Silvia Silva da Costa Botelho

________________________________
Prof. MSc. Ivete Martins Pinto

Banca Examinadora:

Prof. Dr. Nelson Duarte Filho


Departamento de Matemtica FURG (Orientador)
Prof. Dra. Silvia Silva da Costa Botelho
Departamento de Fsica FURG
Prof. MSc. Ivete Martins Pinto
Departamento de Matemtica FURG

3
DEDICATRIA

Dedico este trabalho a todos os que acreditaram em mim e me apoiaram do incio ao fim.
Principalmente a minha querida famlia que sempre esteve do meu lado nos momentos bons e ruins.
Um agradecimento especial em memria a meu pai Carlos Henrique que sempre foi um
exemplo de sabedoria e tranqilidade. Serei feliz se um dia conseguir ser a metade do homem que
ele foi.
Minha me Maria da Graa, pela dedicao extrema quanto aos filhos. Possibilitando assim
todo o meu desenvolvimento como profissional e como pessoa.
Minha irm Raquel, pela ajuda que mesmo a distncia conseguiu transmitir. Sempre
dedicada aos estudos tornou-se para mim um exemplo a ser seguido.
Minha namorada Vanessa, por sempre estar do meu lado me trazendo paz e boa companhia
no desenrolar dos trabalhos que culminaram com esta monografia.
Graas a todos vocs, consegui ultrapassar mais uma barreira em minha vida. E por causa
de vocs que consigo sempre continuar neste caminho to bonito que a vida.

4
AGRADECIMENTOS

Agradeo ao meu orientador Prof. Dr. Nelson Lopes Duarte Filho por ter me ajudado
sempre que pde, mesmo com o pouco tempo que tem devido aos vrios projetos que desenvolve.
Tambm devo muito aos meus colegas de trabalho do NCC (Ncleo de Computao Cientfica) que
sempre procuraram manter um bom ambiente de trabalho e de pesquisa cientfica.

5
SUMRIO

Lista de Figuras..................................................................................................................................8

Lista de Tabelas................................................................................................................................10

Lista de Abreviaturas.......................................................................................................................11

1 INTRODUO.............................................................................................................................15

2 INFRAESTRUTURA DE COMUNICAO............................................................................20
2.1 Endereamento Multicast.............................................................................................................22
2.2 MBONE........................................................................................................................................23
2.4 UDP..............................................................................................................................................25

3 SREAMING...................................................................................................................................28
3.1 Codecs de Vdeo...........................................................................................................................28
3.2 Codecs de udio...........................................................................................................................30
3.3 Mtricas de QoS...........................................................................................................................33

4 TRANSMISSO EM TEMPO REAL.........................................................................................34


4.1 RTP...............................................................................................................................................34
4.2 RTCP............................................................................................................................................41

5 ARQUITETURA...........................................................................................................................52
5.1 Mdulo de Configurao..............................................................................................................59
5.2 Mdulo Transmissor.....................................................................................................................61
5.3 Mdulo Receptor..........................................................................................................................65

6 JAVA MEDIA FRAMEWORK...................................................................................................67


6.1 Estrutura de Classes......................................................................................................................67
6.2 Funcionamento da API JMF.........................................................................................................71

6
7 TESTES E RESULTADOS..........................................................................................................76

8 CONCLUSO................................................................................................................................79

9 REFERNCIAS BIBLIOGRFICAS........................................................................................81

7
LISTA DE FIGURAS

Figura 1: IGMP...................................................................................................................................17
Figura 2: Transmisso Multimdia.....................................................................................................19
Figura 3: Multicast e Unicast.............................................................................................................21
Figura 4: Endereo Multicast.............................................................................................................22
Figura 5: Multicast Nvel 3 e Nvel 2.................................................................................................23
Figura 6: Multicast MBONE..............................................................................................................24
Figura 7: Datagrama UDP..................................................................................................................25
Figura 8: Datagrama IP......................................................................................................................26
Figura 9: Representao grfica de um sinal sonoro..........................................................................30
Figura 10: Jitter...................................................................................................................................33
Figura 11: Skew..................................................................................................................................33
Figura 12: Modelo ISO OSI...............................................................................................................34
Figura 13: Pilha de Protocolos RTP...................................................................................................35
Figura 14: Cabealho RTP.................................................................................................................36
Figura 15: Cabealho Fixo RTP.........................................................................................................36
Figura 16: Cabealho RTCP...............................................................................................................41
Figura 17: Pacote RTCP Composto...................................................................................................42
Figura 18: Pacote Receiver Report.....................................................................................................43
Figura 19: Pacote Sender Report........................................................................................................45
Figura 20: Item SDES........................................................................................................................46
Figura 21: Pacote SDES.....................................................................................................................47
Figura 22: Pacote BYE.......................................................................................................................47
Figura 23: Pacote APP........................................................................................................................48
Figura 24: Funcionamento do Servidor de Streaming........................................................................53
Figura 25: Localizao do Socket......................................................................................................54
Figura 26: Fragmentao de Pacotes RTP..........................................................................................55
Figura 27: Funcionamento da Aplicao Cliente...............................................................................56
Figura 28: Arquitetura Proposta.........................................................................................................57
Figura 29: Aplicao de Configurao...............................................................................................60
Figura 30: Transmissor FURGTV......................................................................................................61
Figura 31: Selecionando o arquivo atravs do javax.swing.JfileChooser..........................................62

8
Figura 32: Janela de Temporizao....................................................................................................62
Figura 33: Classe Transmissor...........................................................................................................63
Figura 34: Conexo via socket...........................................................................................................64
Figura 35: Janela de Status de Transmisso.......................................................................................65
Figura 36: Aba Sobre..........................................................................................................................65
Figura 37: Abstrao da API JMF......................................................................................................71
Figura 38: Transmisso JMF..............................................................................................................73
Figura 39: Recepo JMF...................................................................................................................74
Figura 40: Arquitetura JMF................................................................................................................75
Figura 41: Modelo de Eventos JMF...................................................................................................68
Figura 42: Diagrama de Classes do Modelo de Eventos JMF............................................................68
Figura 43: Tipos de DataSource.........................................................................................................70
Figura 44: Player FURGTV...............................................................................................................76
Figura 45: Tamanho dos Pacotes........................................................................................................77
Figura 46: Pacotes Recebidos pelo Primeiro Receptor......................................................................78
Figura 47: Pacotes Recebidos pelo Terceiro Receptor.......................................................................78

9
LISTA DE TABELAS

Tabela 1: Caractersticas dos fluxos multimdia tpicos.....................................................................28


Tabela 2: Tipos de resoluo de vdeo...............................................................................................29
Tabela 3: Padres de Videoconferncia.............................................................................................29
Tabela 4: Padres do ITU...................................................................................................................30
Tabela 5: Valores de MOS.................................................................................................................31
Tabela 6: Codecs de udio e valores de MOS....................................................................................31
Tabela 7: RFCs do Perfil RTP............................................................................................................38
Tabela 8: Formatos de vdeo suportados pelo JMF............................................................................68
Tabela 9: Formatos de udio suportados pelo JMF............................................................................69

10
LISTA DE ABREVIATURAS

ASM Any Source Multicast


API Application Programming Interface
APP Application-defined packet name
CBR Constant Bit Rate
Codec enCOder DECoder
DHCP Dynamic Host configuration Protocol
DNS Domain Name System
DVMRP Distance Vector Multicast Routing Protocol
HTTP Hiper Text Transfer Protocol
IANA Internet Assigned Numbers Authority
IETF Internet Engenering Task Force
IGMP Internet Group Management Protocol
IP Internet Protocol
ISSO Hypertext Transfer Protocol
ITU Unio Internacional de Telecomunicaes
MBONE Multicast Backbone
MCU Unidades de Controle Multiponto
MC Controlador Multiponto
MOS Mean Opinion Score
MOSPF Multicast extensions to Open Shortest Path First
MP Processador de Multiponto
MTU Maximum Transmission Unit
MSDP Multicast Source Discovery Protocol
NAT Network Address Translation
NTP Network Time Protocol
OSI Open Systems Interconnection
PCM Pulse Code Modulation
PIM-SM Protocol Independent Multicast Sparse Mode
QoS Quality of Service
RAS Registration, Admission and Status
RP Rendevous Point
RTCP Real-Time Transport Control Protocol

11
RTP Real-Time Transport Protocol
RTT Round-Trip Time
SDES Source Description
SDP Session Description Protocol
SNMP Simple Network Management Protocol
SIP Session Initiation Protocol
SSM Source Specific Multicast
TCP Transmission Control Protocol
TTL Time To Live
UDP User Datagram Protocol
URL Universal Resource Locator
VOD Video-On-Demand
Wi-Fi Wireless Fidelity

12
RESUMO

Um canal de Televiso pode ser disponibilizado atravs da Internet com capacidades plenas.
Para isto, a capacidade de streaming via Multicast deve ser implementada. A comunicao feita de
um transmissor para mltiplos receptores. Como o endereamento Multicast permite enviar pacotes
IP para um determinado grupo de usurios, estes so cadastrados previamente no grupo. Para entrar,
sair e se manter em grupos Multicast, as estaes utilizam o protocolo IGMP. A diferena do
Multicast para unicast e broadcast est no roteamento dos pacotes que so enviados do transmissor
para os receptores. Ele utiliza o maior nmero possvel de rotas coincidentes, economizando assim a
capacidade dos canais de comunicao.
Foram implementados dois mdulos em Java: servidor e cliente. Primeiramente, o aplicativo
servidor abre o arquivo de vdeo e udio que comea a ser transmitido via multicast pela rede. Aps
cria-se um loop que espera conexes via socket. Quando alguma requisio recebida, dispara-se
uma thread para adicionar o cliente em questo no grupo e controlar a permanncia dele atravs de
sesses. O cliente um Applet que roda embutido no servidor Tomcat. Ele ser disponibilizado
atravs de um link na pgina da FURG TV (www.furgtv.furg.br). Desta maneira, ser
disponibilizado o canal de televiso da Fundao Universidade Federal do Rio grande, via
streaming, na Internet.

13
ABSTRACT

A television channel can be set over the Internet with full capacity. For this, the capacity for
streaming with Multicast must be implemented. The communication is done from a transmitter to
multiple receivers. As the Multicast Protocols allows sending IP packets to a specific group of
users, they are registered in advance in a group. To enter, leave and remain in Multicast groups,
stations use the protocol IGMP. The difference of Multicast for unicast and broadcast is in the
routing of packages that are sent to the receivers from the transmiter. Multicast Protocols use the
possible greater number of coincident parcial routes.
Two modules were implemented in java: server and client. Initially, the server application
open the file and begin to transmit video and audio multicast via the network. Then it creates a loop
waiting connections via socket. When a request is received, it fired a thread to add the customer in
question in the group and control its permanence in sessions. The client is an Applet that runs
embedded in a Tomcat server. It can be downloaded from a link on the page of FURG TV
(www.furgtv.furg.br). Thus, the channel of the Fundao Universidade Federal do Rio Grande has
been available with the capacities of streaming multimidia data over the Internet, through multicast.

14
1 INTRODUO

As comunicaes multimdia so definidas como todo tipo de comunicao na qual existe


transmisso de mltiplas mdias sobre uma rede de comunicao. Em geral, as mdias so de udio
(voz ou msica) e vdeo. E, normalmente, a rede de comunicao em questo a Internet. Neste
contexto podem ser implementados muitos servios como: ensino a distncia, telemedicina,
conversa remota, etc. Um dos servios mais populares atualmente o de Web TV, no qual os
telespectadores podem assistir ao seu canal favorito em tempo-real no momento que desejar atravs
da Internet via browser.
Os aplicativos multimdia enviam e recebem fluxos contnuos de dados em tempo real. Por
esta razo, o escalonamento e a alocao de recursos (Ex: largura de banda) devem ser precisas para
o atendimento das especificaes necessrias a um funcionamento razovel das aplicaes.
Tambm necessria a utilizao de buffers para o armazenamento dos elementos recebidos via
rede. Por isso, deve haver uma maior ateno em relao QoS oferecida s aplicaes. Caso
existam outros aplicativos executando e consumindo recursos, o que bastante provvel, a largura
de banda e a quantidade de memria disponvel no devem restringir a qualidade da transmisso de
vdeo. Esta outra razo para haver um cuidado maior com QoS. Mesmo assim, as aplicaes
atuais so baseadas na regra do melhor esforo e em poucas solues quanto qualidade de servio.

Tpicas aplicaes multimdia, segundo [21], so:

Multimdia baseada na web: Os dados de udio e vdeo so publicados na Internet.


Depende da largura de banda disponvel, da latncia varivel encontrada nas redes
atuais de comunicao e da falta de capacidade dos sistemas operacionais em
realizar o escalonamento em tempo real.
Vdeo sob demanda: Este tipo de aplicao tem resultados eficientes quando utiliza
um servidor de vdeo dedicado. Ele trata requisies para assistir determinado
arquivo multimdia em um determinado horrio e data.
Telefone de rede e conferncia por udio: Exige pouca largura de banda. Trata-se de
comunicao bastante interativa e com necessidade de baixos RTTs.

Afora essas, a transmisso de contedo multimdia ao vivo est crescendo cada vez mais
devido popularizao dos links de banda larga. Esse tipo de transmisso est se tornando comum
aos usurios na Internet [1]. Com a televiso na Internet, o usurio solicita apenas os programas de
seu interesse e no precisa ser escravo da programao pr-definida pelas estaes corporativas. A

15
maioria das televises disponibilizados na Internet, hoje em dia, consiste em um decodificador de
sinal capturando sinal de TV e retransmitindo-o para a web atravs de um servidor de streaming.
O modelo utilizado atualmente pelas TVs abertas sofrer uma mudana bastante relevante,
devido s prprias limitaes. A forma de transio provavelmente ser consolidada como digital,
substituindo a atual que analgica. Isto se deve a alguns fatores como melhor definio e maior
nmero de canais disponibilizados. Onde se captava um nico programa por canal, podero existir
vrios (sistema de mltiplos programas). Existem ainda outras vantagens que no sero abordadas
neste trabalho. Como exemplos podem-se citar o T-commerce, o comrcio eletrnico pela TV, e o
T-Banking, servios bancrios tambm pelo aparelho de TV. Isto sem falar na TV interativa que
uma das reas de maior atratividade e de progresso rpido neste contexto.
Uma forma de disponibilizar um canal de TV atravs da Internet com capacidades plenas
atravs da utilizao de dois mdulos, em Java por exemplo, atravs dos quais feito o envio de
dados de um transmissor para mltiplos receptores. Para economizar recursos de comunicao
pode-se utilizar endereamento Multicast, o qual permite o envio de pacotes IP para um
determinado grupo de usurios que previamente se cadastraram neste (identificado por um endereo
IP classe D, ou seja, entre 224.0.0.0 at 239.255.255.255). Para entrar, sair e se manter em grupos
Multicast, as estaes devem utilizar o protocolo IGMP [16]. A diferena entre o Multicast e o
unicast reside no modo como feito o roteamento dos pacotes. Enquanto no unicast a comunicao
feita ponto a ponto, no multicast alguns protocolos de roteamento so utilizados para fazer isso,
como, por exemplo, o DVMRP, o MOSPF e o PIM. Eles usados para troca de informaes entre os
roteadores e definio de quais rotas os pacotes devero seguir e a comunicao feita de um para
muitos.
necessria a manuteno dos grupos multicast. Para isso, utilizado o protocolo IGMP em
hosts IPv4. Esse tipo de gerenciamento feito atravs da notificao aos roteadores vizinhos
quando um host entra ou sai de algum grupo. J em hosts IPv6, o IGMP implementado atravs do
ICMPv6. Existem mensagens caractersticas deste protocolo como, por exemplo, a mensagem
IGMP Host Membership Query que enviada por roteadores, quando querem descobrir quais hosts
esto em seu grupo, para o endereo 224.0.0.1 com TTL igual a 1. Outra mensagem caracterstica
a Host Membership Report. Esta enviada pelos hosts, que participam de algum grupo multicast,
para os roteadores vizinhos. Mensagens peridicas IGMP devem ser enviadas para que seja mantida
a consistncia dos grupos multicast.

16
Figura 1: IGMP

O diagrama na Figura 1 representa os estados dos membros durante uma sesso multicast do
protocolo IGMP, assim como os eventos que causam as transies entre os estados. Os estados
possveis dos membros esto representados pelos crculos cinzas com bordas pretas. A comear
pelo estado No-membro, esse o estado inicial para todos os grupos em todas as interfaces de
rede. Um membro tambm pode pertencer a um grupo numa interface e ter um temporizador de
report executando (membro com temporizador). Alm destes, existe o estado sem temporizador. Os
eventos que causam transies de estado, e podem ocorrer em qualquer das interfaces de rede nele
existentes so:

Join Group: ocorre quando o host quer participar de um grupo.


Leave Group: ocorre quando um host quer abandonar um grupo.
Query Received: ocorre quando um host recebe uma mensagem Host Membership Query.
Report Receive: ocorre quando um host recebe uma mensagem Host Membership Report.
Timer Expired: ocorre quando o temporizador de atraso para o grupo na interface expira.

Para as redes que no podem usufruir o endereamento Multicast, existe o backbone


Multicast da Internet (MBONE) [2] que ser melhor explicado posteriormente. Os pacotes somente
so encaminhados para aqueles caminhos que possuem clientes cadastrados em algum grupo
Multicast, evitando trfego desnecessrio. Para limitar o alcance geogrfico do Multicast, o campo
TTL utilizado, atravs de uma configurao de threshold. Para roteadores que no suportam
Multicast, os pacotes so enviados pelos tneis Multicast que encapsulam os pacotes em tneis IP
unicast.

17
Um dos grandes desafios atuais da Internet o acesso s transmisses multimdia, mesmo na
presena de receptores localizados em redes heterogneas, com diferentes larguras de banda,
velocidade de enlace, condies de acesso e capacidade de processamento. Para resolver esse
problema deve ser implementado algum tipo de controle de banda para disponibilizar a transmisso
igualitria do vdeo entre os receptores. Existem dois tipos de abordagem de controle de
congestionamento: SSM [3] e ALM [4]. A abordagem SSM deve ser escolhida quando apenas uma
fonte pode enviar dados Multicast. J na abordagem ALM, o Multicast implementado na camada
de aplicao para que redes com diferentes topologias possam compartilhar da mesma transmisso
com a mesma qualidade de imagem, o que normalmente gera problemas na distribuio de pacotes.
Alm disso, os protocolos ALM implementam as facilidades de Multicast nos end-hosts ao
invs de nos roteadores da rede. Os dados so replicados nos end-hosts e no dentro da rede como
feito com IP Multicast. O grande problema desta abordagem a utilizao, normalmente,
inadequada da banda. Existem trs protocolos ALM bastante conhecidos: Narada [5], Yoid [6] e
NICE [7].
No trabalho aqui descrito, foram construdos dois mdulos: um cliente e um servidor de
streaming. O sinal multimdia codificado e transmitido pelo servidor para um grupo multicast de
clientes. O sinal multimdia tanto pode ser obtido por uma filmadora ou quanto pode ser lido em um
arquivo, sendo que o transmissor deve encapsular os pacotes utilizando protocolo RTP [8].
A transmisso via Multicast compe uma soluo alternativa ao excesso de trfego
redundante de pacotes que ocorre nas transmisses unicast e broadcast. Multicasting , pois, um
mtodo ou tcnica de transmisso de um pacote de dados para mltiplos destinos ao mesmo tempo,
com otimizao dos recursos de comunicao. Durante este tipo de transmisso, o servidor envia os
pacotes de uma vez, dependendo dos receptores a captura da transmisso e, a partir disto, sua
reproduo. Por exemplo, no caso de um filme a ser enviado por um servidor remoto para vrios
clientes, Multicast a soluo ideal pois diminui bastante o trfego j que no envia pacotes para
cada um dos participantes e sim para todo o grupo de uma s vez. Alm disso, importante
ressaltar que tambm existe o padro H.323 que prov uma base tecnolgica para transmisso de
dados, udio e vdeo [9].
O funcionamento de uma transmisso multimdia bastante simples de compreender: o sinal
gerado inicialmente digitalizado para ento passar por um processo de compresso, o que diminui
a quantidade de dados a ser transmitido, tornando vivel o envio dos dados pela rede. Esta insere
alguns atrasos no sistema, como pode ser visto na Figura 2. No receptor, os pacotes so
reordenados, descomprimidos e reconvertidos ao estado original, normalmente com perdas
inseridas no processo de compresso.

18
Figura 2: Transmisso Multimdia

As mdias, normalmente, so grandes demais para serem enviados diretamente sem nenhum
tipo de tratamento porque geram atrasos demasiados, congestionando a rede envolvida na
comunicao. A soluo para este problema a codificao e decodificao das mdias. Para isto
so utilizados algoritmos de codec que definem o formato no qual sero codificadas e comprimidas
as mdias. Alm de definir como sero decodificadas as informaes no receptor. Tendo isto em
considerao, a escolha do codec crucial para que a transmisso seja eficiente. Tanto a qualidade
de transmisso quanto a quantidade de banda consumida depende do tipo de codec escolhido. Alm
disso, importante ressaltar que tanto na transmisso quanto na recepo devem ser utilizados o
mesmo tipo de codec.
Para que uma comunicao seja considerada em tempo-real, os telespectadores devem ter a
percepo de que esto vendo as imagens no mesmo momento em que esto sendo filmadas ou
lidas de um arquivo. Mas sempre existir algum tipo de atraso ou perda em relao ao que est
sendo produzido. Para minimizar este problema, deve ser adotada alguma alternativa que impea o
usurio de perceber esses atrasos ou perdas. Grandes atrasos prejudicam a caracterstica de tempo
real da comunicao e atrasos variveis prejudicam a continuidade da reproduo da mdia. Muitas
vezes, as comunicaes multimdia em tempo real so consideradas CBR, o que indica que devem
manter uma taxa de bit constante durante a transmisso das mdias. Esta caracterstica deve ser
mantida, mas a manuteno no pode exigir recursos em demasia da rede, pois conseqentemente
ir prejudicar a transmisso.
O funcionamento da nossa arquitetura bastante simples: o aplicativo servidor abre o
arquivo de vdeo e comea a transmitir via multicast pela rede. Aps criado um loop que espera
conexes via socket. Quando alguma requisio recebida, dispara-se uma thread para adicionar o
cliente em questo no grupo e fazer o controle da permanncia nas sesses. O cliente um Applet
que roda embutido no servidor Tomcat. Ele ser disponibilizado atravs de um link na pgina da
FURG TV (www.furgtv.furg.br). Desta maneira, ser disponibilizado o canal de televiso da
Universidade Fundao Universidade Federal do Rio grande via streaming na Internet.

19
2 INFRAESTRUTURA DE COMUNICAO

Existem trs tipos de endereamento que podem ser adotados no protocolo IPv4 para
encaminhar pacotes: unicast, multicast e broadcast. No tipo unicast, a comunicao d-se de um
para um, ou seja, de uma entidade origem para outra destino. No multicast, um para vrios. J no
broadcast um para todos. O endereamento multicast permite enviar pacotes IP para um
determinado grupo de interfaces de rede que estejam previamente cadastradas no grupo. Para entrar,
sair e se manter em grupos multicast, as estaes devem utilizar o protocolo IGMP, que ser
mostrado em maiores detalhes adiante.
Em termos de qualidade de servio, uma transmisso multicast tratada da mesma forma
que unicast, ou seja, possui as mesmas caractersticas de melhor esforo do IP unicast, sofrendo
as mesmas polticas de controle de acesso e confirmao de trfego. Como uma transmisso
multicast possui o mesmo cabealho IP do unicast, os mtodos de garantia de qualidade de servio
so os mesmos e ambos podem usar diffserv, RSVP [17], MPLS, e assim por diante.
No roteamento de pacotes multicast, o roteador deve saber em quais portas existem usurios
cadastrados em grupos. Com isso ele replica os pacotes por todos os caminhos por onde existirem
receptores. Os protocolos de roteamento multicast so os seguintes: DVMRP, o MOSPF e o PIM.
Atravs destes protocolos, os roteadores conversam entre si e descobrem quais rotas devem ser
usadas para encaminhar os pacotes.
O grande ponto a favor do multicast que ele permite uma distribuio simultnea para um
grande nmero de clientes, sem exigir muito dos recursos do servidor e sem gerar muito trfego na
rede. Assim, esta tecnologia facilita a existncia de uma nova gerao de aplicaes um para
muitos em rede, como trfego de vdeo, udio, trabalho colaborativo, transmisso de arquivos
simultaneamente para muitos usurios, e assim por diante. As novas aplicaes podem ou no
exigir confiabilidade, entretanto, para transmisses confiveis existe uma complexidade maior para
controlar fluxo e o feedback dos receptores.
Em resumo:

Trfego multicast: o transmissor gera um fluxo de pacotes IP multicast, que distribui


para todas suas portas. Os clientes cadastrados no grupo multicast pegam a informao e
a processam. O roteador, por sua vez, verifica se tem alguma de suas portas com clientes
cadastrados no grupo multicast. Caso tenha, envia um fluxo multicast para essa porta.

Trfego unicast: para cada cliente, o transmissor deve gerar um fluxo de pacotes IP
unicast.

20
Trfego broadcast: a rede sobrecarregada pois a mesma mensagem enviada pelo
transmissor para todos os receptores ao mesmo tempo, inundando assim a rede com
pacotes replicados.

Figura 3: Multicast e Unicast

A transmisso de pacotes por multicast compe uma soluo alternativa ao excesso de


trfego redundante de pacotes. Multicasting um mtodo ou tcnica de transmisso de um pacote
de dados para mltiplos destinos simultaneamente. Durante transmisso desse tipo, o servidor envia
os pacotes e depende dos receptores a captura da transmisso e, conseqente, reproduo.
O endereamento multicast caracterizado por IPs classe D. Ou seja, so reservados para
comunicao multicast os IPs de 224.0.2.0 at 238.255.255.255. Os endereos reservados para
protocolo de roteamento, descobrimento de topologia, etc. esto na faixa de 224.0.0.0 at
224.0.0.255. J em aplicaes desenvolvidas para criar um novo tipo de protocolo deve-se utilizar a
faixa 224.0.1.0 at 224.0.1.255. Os endereos IPs restantes da classe D so reservados para fins
administrativos (239.0.0.0 at 239.255.255.255), segundo [22].
No caso de uma aplicao multimdia, o transmissor gera um fluxo de pacotes IP multicast,
que distribui para todas suas portas. Os clientes cadastrados no grupo multicast recebem a
informao e esta apresentada na tela. O roteador verifica se tem alguma de suas portas com
clientes cadastrados no grupo multicast. Em caso afirmativo, ele envia um fluxo multicast para essa
porta.
No nosso caso: um canal de televiso sendo transmitido para vrios clientes por um servidor
de vdeo, multicast torna-se a soluo ideal porque diminui significantemente o trfego na rede.

21
2.1 Endereamento Multicast

Cada grupo multicast reconhecido como um endereo multicast que tem caractersticas
singulares que o diferenciam de um endereo IP comum. Isto se torna necessrio porque pacotes
enviados a eles no sero enviados a apenas um host, e sim, a vrios destinos ao mesmo tempo.
Desta forma, uma faixa de endereos so reservados para endereamento multicast, como acima
detalhado.

Multicast no Nvel de Rede (Nvel 3)

O multicast utiliza a classe D de endereamento da Internet, ou seja, de 224.0.0.0 a


239.255.255.255. A diferena no cabealho IP de um pacote unicast e um multicast apenas o
endereo. A classe D permite at 28 bits, ou seja, 268 milhes de endereos diferentes.
Existem alguns endereos multicast reservados pelo IANA [16], como o 224.0.0.0, que a base
e no deve ser usado. J os endereos de 224.0.0.1 a 224.0.0.255 so reservados para protocolos de
roteamento, como, por exemplo, todos sistemas na subrede (224.0.0.1), todos roteadores nesta
subrede (224.0.0.2), todos roteadores DVMRP (224.0.0.4), todos roteadores MOSPF
(224.0.0.6). Outros so reservados para determinadas aplicaes, como o IETF1-udio
(224.0.1.11) e o IETF1-vdeo (224.0.1.12). O conjunto de endereos de 239.0.0.0 a
239.255.255.255 reservado para uso local, podendo ser usado em intranets. Maiores detalhes
podem ser encontrados na RFC 1700 [23].

Multicast no Nvel de Enlace (Nvel 2)

Numa rede local, existe um conjunto de endereos MAC (Mdium Access Control) especial
destinado a multicast. Assim, no protocolo de nvel 2, o host do cliente sabe se a mensagem
destinada a ele ou no. Esse conjunto de nmeros foi reservado pelo IANA e compreende todos os
endereos de 01-00-5E-00-00-00 a 01-00-5E-7F-FF-FF, conforme a Figura 5 (somente 23 bits,
comparado aos 28 do endereo multicast).

Figura 4: Endereo Multicast

22
Existe um processo de mapeamento entre o IP multicast e o Ethernet multicast, que
simplesmente a substituio dos 23 bits menos significativos do Ethernet pelos 23 bits menos
significativos do IP. Assim, quando uma estao cliente se cadastra em determinado grupo
multicast, como, por exemplo, o 238.173.117.105 (EE.AD.75.69), automaticamente o driver da
placa de rede passa a receber mensagens MAC que cheguem no endereo 01-00-5E-2D-75-69,
como mostra a Figura 7. J o transmissor, que criou o grupo 238.173.117.105, quando enviar a
mensagem para a rede, vai encaminh-la ao endereo 01-00-5E-2D-75-69 do nvel 2, como
explicado anteriormente.

Figura 5: Multicast Nvel 3 e Nvel 2

Observa-se que o mapeamento mostrado na figura provoca a existncia de 32 nmeros


multicast iguais para o mesmo nmero Ethernet. Isso acontece, pois os cinco bits mais
significativos do endereo multicast so ignorados no mapeamento. Quando se faz o mapeamento
para o nvel 2, utiliza-se somente os 23 bits menos significativos. Ou seja, de (224 a 239).0.0.0 at
(224 a 239).127.255.255. Isso faz com que, para 32 endereos, a placa de rede receba os grupos
como se fossem o mesmo. A filtragem para verificar se a mquina que est cadastrada se d no
nvel 3.
A maioria dos switches Ethernet atuais quando recebem um nmero MAC multicast tratam
como se fosse endereo broadcast. Ou seja, enviam para todas suas portas. Sendo assim, qualquer
cliente cadastrado no grupo ir receber o pacote e o colocar no nvel a cima, e qualquer cliente no
cadastrado vai receber o mesmo pacote e ignor-lo. Existem alguns tipos de switch que executam
IGMP, e so teis para minimizar o trfego desnecessrio em redes nvel 2, especialmente em
configuraes compostas de muitos switches e poucos roteadores.

2.2 MBONE

23
O MBONE ou backbone multicast da Internet nada mais do que um conjunto de roteadores
interligados a fim de distribuir trfego multicast. Ou seja, uma rede virtual de hosts conectados pela
Internet para comunicao estritamente multicast. Seu tempo de vida tem seus dias contados, pois
quando todos os roteadores da Internet suportarem protocolos de roteamento multicast, no ser
mais necessrio o uso do MBONE.
Desde de 1992, o MBONE encontra-se em funcionamento. Ele foi originado de um esforo
realizado pela IETF para dar suporte de udio e vdeo atravs de multicast para reunies distncia.
A ttulo de curiosidade, certa vez, um show dos Rolling Stones foi transmitido pelo MBONE, como
tambm partes do Festival de Cinema de Cannes [10]. Isto revela sua capacidade de utilizao real.
Atualmente, vrios protocolos esto sendo desenvolvidos sobre o MBONE. Atravs dele, pacotes
so enviados via unicast pela Internet.
Caso os roteadores suportassem roteamento multicast, os tneis (linhas de comunicao
bidirecionais entre hosts) seriam inteis, pois o roteador faria o papel do mrouter. Alm disso, a
manuteno dos tneis um processo bem trabalhoso, ficando bem mais fcil o uso no roteador.
Entretanto, o roteador vai ser afetado no desempenho da entrega de pacotes porque vai ter mais uma
tarefa por fazer.
Os roteadores do MBONE so chamados de mrouters e suportam endereamento multicast.
Todo o funcionamento baseado em tunneling, no qual os pacotes so enviados para as subredes
MBONE por mrouters que no suportam IP Multicast. A estrutura do MBONE est representada na
Figura 6.

Figura 6: Multicast MBONE

Os pacotes so encaminhados apenas para os caminhos que possuem clientes cadastrados


em algum grupo multicast, evitando trfego desnecessrio. Para limitar o alcance geogrfico do
multicast, o campo TTL utilizado com uma configurao de threshold.
Os tneis multicast encapsulam os pacotes em tneis IP unicast atravs do protocolo IP-IP.
A configurao dos tneis feita atravs de um arquivo chamado /etc/mrouted.conf.

24
Um tnel necessita ser configurado em ambos mrouters a fim de que possa ser usado. O
arquivo /etc/mrouted.conf deve ser configurado com os seguintes parmetros: IPs dos tneis,
Threshold (define o valor mnimo de TTL que um pacote multicast deve ter para que seja
encaminhado por determinada interface ou tnel), Metric (define o custo associado a esse tnel) e
Rate_limit (largura de banda, em Kbit/s, do fluxo multicast que passa pelo mrouter).
Em geral, todos os roteadores multicast conectados a um determinado tnel devem usar a
mesma mtrica e threshold para este tnel.

2.3 UDP

Uma aplicao que necessita da comunicao via Internet deve utilizar os protocolos de
transporte como pontos de acesso. Para que esta comunicao seja implementvel, cada ponto de
acesso representado por um endereo de transporte denominada porta. O conceito de porta
tambm utilizado para tornar possvel a multiplexao de vrias comunicaes do nvel de
aplicao de forma independente e simultnea. Os protocolos de transporte denominam-se UDP e
TCP. Na prxima seo ser explicado como funciona o protocolo UDP e porque ele foi o
escolhido para implementar a comunicao proposta neste trabalho.
UDP um protocolo de transporte no qual no existe a verificao do recebimento dos
dados pelo destino, no possui servio de reenvio e nenhum tipo de ordenamento de mensagens.
Sendo assim, as mensagens recebidas so agrupadas da maneira como chegam, sem nenhuma
verificao da ordem de chegada. Alm disso, no existe nenhuma verificao de integridade das
mesmas. Essas caractersticas podem parecer prejudiciais, mas so elas que fazem com que o
protocolo UDP seja muito rpido. Por conseqncia, tornou-se um protocolo extremamente simples
que oferece um servio de pacotes sem conexo.
O funcionamento baseado em portas de comunicao. So definidas portas de origem e de
destino e a comunicao feita atravs do envio de datagramas UDP. O formato dos datagramas
encontra-se na Figura 7.

Figura 7: Datagrama UDP

25
No datagrama UDP, so definidas a porta de origem e a de destino (ambas com 15 bits).
Alm disso, existe um campo de tamanho (15 bits) que descreve quantos bytes o pacote ter, um
campo de checksum (15 bits) que opcional e faz uma soma verificadora para proporcionar a
verificao de erros. Para que seja enviado, o datagrama UDP encapsulado num pacote IP, como
ilustrado na Figura 8.

Figura 8: Datagrama IP

Existem alguns protocolos do nvel de aplicao que fazem uso do protocolo UDP para as
suas implementaes. Um exemplo o protocolo DHCP que, entre outras coisas, utilizado para
distribuio automtica de endereos IPs. Outro protocolo que tambm o utiliza o DNS, adotado
para traduzir nomes de hosts em endereos IPs. Alm desses, o SNMP tambm utiliza o UDP.
Atravs dele, por exemplo, possvel configurar dispositivos como switches ou roteadores.
Possibilitando que enviem informaes de status a outros elementos da rede.
Tendo em vista o que foi explicado sobre o protocolo UDP, fica claro que ele usado
quando se quer implementar uma comunicao em tempo real porque no existe muita sobrecarga
na rede e por causa da caracterstica de poder mandar um pacote para vrios destinos, o que o torna
diferente do outro protocolo de transporte mais popular, o TCP (orientado a conexes). Sendo no
orientado a conexo, pacotes de confirmao de recebimento, por exemplo, no precisam ser
enviados. Ou seja, existem vrios pacotes apenas de verificao que no so enviados quando se
utiliza UDP, pois esta no orientada a conexes. Portanto UDP muito mais rpida que TCP.
Mesmo sendo menos segura, UDP muito mais indicada para transmisses multimdia porque o
que se quer neste tipo de transmisso velocidade.

26
3 STREAMING

H algum tempo atrs, executar um arquivo de vdeo, ou seja, assistir um pequeno clip na
Internet significava um longo perodo de download. Ento, levantou-se a possibilidade de
reproduzir o vdeo desejado antes mesmo que todo o arquivo fosse gravado localmente. Assim,
nasceu a tecnologia de Streaming, que um misto de tcnicas de compresso e armazenamento em
memria temporria (buffering). Ela permite a transmisso de vdeo em tempo real atravs da
Internet.
Na tecnologia streaming, a imagem e som comeam a ser reproduzidos antes mesmo que o
arquivo que os contm seja copiado totalmente para o computador local. Isto reduz a espera inicial a
poucos segundos, um tempo relativamente razovel para o contexto atual da Internet.
Nas transmisses de streaming, a ordem de chegada dos pacotes contendo unidades de um
arquivo fundamental, pois a visualizao ou execuo do contedo do arquivo se inicia antes do
trmino da transmisso, como foi mencionado. Por outro lado, alguns pacotes podem ser
descartados, sendo que em algum nvel razovel de descartes isso se torna praticamente
imperceptvel ao olho humano.
Alm disso, esta tecnologia permite ainda enviar o vdeo de uma forma que ele no pode ser
copiado. Para rodar um vdeo clip em streaming, normalmente necessria a presena de um plug-
in (software especial que trabalha em conjunto com o navegador da Web), o qual manipula o
download e a descompresso do arquivo.
Na compresso do vdeo, a imagem particionada em uma seqncia de quadros
denominados frames. Cada frame quebrado em partes estticas ou dinmicas. Essas partes,
tambm chamadas de objetos, possuem contedo parado ou mvel, respectivamente. Um software
de compresso age sobre estes objetos, atualizando aqueles com contedo mvel e reciclando
aqueles com contedo esttico. Desta forma, se reduz o tamanho e o tempo de transmisso de um
arquivo.
O armazenamento em memria temporria ou bufferizao trata da utilizao de um espao
alocado em memria que visa manter um ritmo constante na reproduo das imagens. Caso a
conexo fique demasiadamente lenta, o buffer fica encarregado de suprir os atrasos e lacunas na
transmisso, esvaziando seu reservatrio de frames.
Um outro aspecto a ser destacado diz respeito aos diferentes tipos de fluxos multimdia. A
Tabela 1 [21], exemplifica alguns desses tipos e as taxas de dados e de quadro por amostragem, por
eles tipicamente utilizadas.

27
Tipo de Fluxo Taxa de Dados Tamanho Freqncia
Vdeo de TV 120 Mbps At 640x480 com 16 bits por pixel 24 frames/s
Vdeo de TV MPEG-1 1,5 Mbps Varivel 24 frames/s
Vdeo HDTV 1000-3000 Mbps At 1920x1080 com 24 bpp 24-60 frames/s
Vdeo HDTV MPEG-2 10-30 Mbps Varivel 24-60 frames/s
Tabela 1: Caractersticas dos fluxos multimdia tpicos

3.1 Codecs de Vdeo

Para que um sinal de vdeo possa ser transmitido atravs de uma rede de comunicao
digital torna-se necessria a sua adequada codificao/decodificao, o que realizada atravs de
codecs. Os codecs de vdeo so utilizados para codificar sinais de vdeo que tanto pode vir de uma
cmera conectada ao computador como de um arquivo de vdeo pr-armazenado. Pela mesma
lgica, o receptor decodifica o vdeo com o mesmo codec para ento apresent-lo. A apresentao
do vdeo recebido pode ser feita tanto em um display apropriado quanto pode ser armazenado em
um arquivo. Como um arquivo de vdeo normalmente bastante grande, ele deve ser divido em
pacotes para que possa ser transmitido sem demora.
Um vdeo nada mais do que uma seqncia de imagens que so exibidas rapidamente,
causando a impresso de movimento. Tendo isto em mente, uma das medidas que devem ser
escolhidas pelo codec o nmero de imagens (quadros) por unidade de tempo que sero enviados
pelo transmissor aos receptores. Esta medida normalmente dada em Frames Per Second (fps). Na
televiso convencional utilizado 30fps. Numa comunicao em tempo real via Internet, esta
medida para ser aceitvel deve estar entre 15 e 30fps. Um codec pode ser considerado melhor que
outro caso consiga enviar mais quadros por segundo, proporcionando assim uma melhor qualidade
na apresentao.
Afora, a resoluo do vdeo adotada pelo codec tambm influi na banda de transmisso.
Algumas resolues especiais foram especificadas para multimdia em tempo real com vistas
manuteno da qualidade e da temporalidade natural do vdeo. Estes padres esto descritos na
Tabela 2.

28
Formato Significado Resoluo
SQCIF Sub-quarter Common Intermediate Format 128 x 96 pixels
QCIF Quarter Common Intermediate Format 176 x 144 pixels
CIF Common Intermediate Format 352 x 288 pixels
4CIF 4 x Common Intermediate Format 704 x 576 pixels
16CIF 16 x Common Intermediate Format 1048 x 1152 pixels
Tabela 2: Tipos de resoluo de vdeo

O vdeo, depois de carregado pelo servidor, deve ser divido em pacotes que iro passar por
um processo de compresso, o que diminui seu tamanho, tornando assim vivel a transmisso pela
rede. No receptor, os pacotes so reordenados, descomprimidos e reconvertidos ao estado original,
normalmente com algumas perdas decorrentes do processo de compresso.
Alguns padres de vdeo possibilitam a interao entre solues de diferentes fabricantes de
forma transparente. As especificaes de maior importncia so apresentadas na Tabela 3, para
diferentes tipos de redes de comunicao.

Padro Tecnologia Qualidade Oferecida


H.320 Videoconferncia sobre ISDN Comunicao coorporativa
H.321 Videoconferncia sobre ATM Alta qualidade
H.323 Videoconferncia sobre IP/Ethernet Qualidade best effort
H.324 Videoconferncia sobre POTS Baixa qualidade
H.310 Videoconferncia MPEG-2 sobre ATM Qualidade para broadcast
Tabela 3: Padres de Videoconferncia

O padro H.323 a especificao indicada pelo IEEE para transmisses de udio e vdeo
sobre a Internet. Permite tambm que produtos de multimdia e aplicaes de fabricantes diferentes
possam interoperar de forma eficiente e usurios possam se comunicar de forma adaptada
velocidade da rede. Ele um padro para controle de conferncias de vdeo e voz sobre redes
TCP/IP da srie H do ITU-T, um subgrupo do ITU [12] que responsvel por padronizaes. A
ttulo de curiosidade, alguns padres do ITU, associados aos assuntos aqui tratados, so
apresentados na Tabela 4.

29
Padres Descrio
H.100 a H.199 Sistemas de telefonia visual
H.220 a H.229 Transmisso, multiplexao e sincronizao
H.230 a H.239 Caractersticas bsicas dos sistemas multimdia
H.240 a H.259 Controle de procedimentos de comunicao
H.260 a H.279 Codecs de vdeo
H.280 a H.299 Servios de suporte as comunicaes multimdia
H.300 a H.399 Servios audiovisuais
H.450 a H.499 Servios de suporte as comunicaes multimdia
Tabela 4: Padres do ITU

3.2 Codecs de udio

O som, para que possa ser transmitido, deve ser transformado em sinais eltricos que por sua
vez devem ser digitalizados. O microfone transforma as ondas sonoras em tenses eltricas com
amplitudes altas e baixas, correspondendo a sons de maior e menor intensidade. Da mesma maneira,
e com variaes de freqncia mais rpidas ou mais lentas, correspondendo a sons mais agudos e
mais graves. A Figura 9 apresenta a representao grfica de um sinal sonoro, depois de convertido
em tenses eltricas atravs do microfone.

Figura 9: Representao grfica de um sinal sonoro

Vrias caractersticas podem ser implementadas atravs dos codecs de udio. Um exemplo
a supresso de silncio que faz com que no seja consumido quase nenhum recurso durante a
ausncia de som em uma comunicao. Apenas transmitido o rudo no momento de silncio. E
isto acontece para que a outra pessoa na linha de comunicao no pense que foi abandonada pelo
outro falante.

30
Outro fator crucial na escolha do codec o valor do MOS, uma medida de qualidade que se
quer implementar para a aplicao. Tal valor pode ser escolhido de modo subjetivo pelo usurio,
dependendo da qualidade percebida pelo mesmo durante a comunicao. Para isto so associados
valores entre zero e um percepo subjetiva da qualidade do som, segundo a Tabela 5.
Normalmente so utilizados codecs com MOS acima de 3,5.

Valor MOS Qualidade Exemplo


0a1 Pssima Conversa impraticvel
1a2 Ruim Conversa com fala quebrada e atraso
2a3 Regular Conversa razovel
3a4 Boa Conversa telefnica de longa distncia
4a5 tima Conversa telefnica local
Tabela 5: Valores de MOS

Valores de MOS associados a alguns tipos de codec de udio so mostrados Tabela 6 [21].

Codec Valor MOS Taxa de transmisso


G.729 3,7 8Kbps
G.728 3,6 16Kbps
G.711 4,1 64Kbps
G.726 3,8 32Kbps
G.723.1 3,9 6,3Kbps
Tabela 6: Codecs de udio e valores de MOS

Por tratar-se de um codec de domnio pblico e larga utilizao, destaca-se aqui o codec
G.711. Ele foi o precursor nas comunicaes de tempo real na Internet. Baseado no sistema
telefnico convencional, ele obrigatrio na arquitetura H.323. de fcil implementao e oferece
uma boa qualidade de mdia.

O codec G. 711 utiliza o algoritmo PCM para codificar udio e representa cada sinal
amostrado atravs de oito bits, gerando uma stream de udio de 8Kbps. Por se tratar de um
algoritmo leve, sua execuo bastante rpida. Sendo assim, possui uma tima qualidade de
transmisso em redes com pouca perda de pacotes, boa largura de banda e atrasos constantes e
reduzidos. Apesar de estar implementado em quase todas as aplicaes atuais de multimdia, ele
pouco utilizado devido ao atual cenrio da Internet.

31
3.3 Mtricas de QoS

O crescimento das aplicaes multimdia em rede tornou necessrio controlar a qualidade de


servio ou QoS a que uma seqncia de pacotes de uma origem a um destino deve ser submetida.

Redes que seguem as diretrizes de transmisso pela regra do melhor esforo, caso das redes IP,
fazem com que os pacotes que as percorrem sejam transmitidos hop a hop na maior velocidade
possvel, independente das aplicaes a que pertenam. Nelas, os pacotes devem chegar aos seus
destinos o mais rpido possvel, mesmo que para isso necessitem utilizar rotas alternativas devido
ao congestionamento da rede. Devem-se, pois, em alguma camada superior dessas redes, introduzir
mecanismos de controle capazes de atribuir prioridades aos fluxos gerados pelas diferentes
aplicaes que se encontrem em execuo corrente.

Considerando a caracterstica iscrona dos pacotes tratados pela aplicao multimdia, foco
desta monografia, e conseqentemente as severas restries a que as entidades que transportam
esses pacotes devem ser submetidas, destacam-se a seguir, para que se possa melhor entender o
funcionamento da proposta, os principais parmetros para controle de qualidade dos fluxos de
dados na Internet.

Latncia
Latncia o tempo que um pacote leva da origem ao destino. Caso esse atraso seja muito
grande, prejudica a troca de dados atravs da rede. Os principais responsveis pela latncia so o
atraso de transmisso, de codificao e de empacotamento, que podem ser definidos da seguinte
forma:
Atraso de transmisso: tempo que leva para o pacote sair da placa de rede do computador
origem e chegar na placa de rede do computador destino (atraso no meio fsico, atrasos de
processamento em roteadores e atraso devido ao tempo de espera nas filas de transmisso
dos equipamentos intermedirios).
Atraso de codificao e decodificao: tempo de processamento na mquina origem e na
mquina destino para codificao e decodificao de sinais. O atraso depende do padro
escolhido.
Atraso de empacotamento e desempacotamento: depois de codificado, o dado deve ser
empacotado atravs dos nveis na pilha de protocolos a fim de ser transmitido na rede.

32
Jitter

Jitter a variao estatstica do retardo entre as chegadas dos pacotes. Deve ser inferior a
50ms para que as comunicaes multimdia no fiquem comprometidam. Para o clculo do jitter
devem-se considerar o atraso do processamento dos codecs e o atraso na transmisso dos pacotes. O
conceito de jitter e latncia so ilustrados na Figura 10.

Figura 10: Jitter

A soluo para o jitter criar um buffer no destino com tamanho dependente do valor do
mesmo, o que conseqentemente reduz o atraso na transmisso. O buffer serve como uma reserva
para manter a taxa de entrega constante no receptor.

Skew

Skew um parmetro utilizado para medir a diferena entre os tempos de chegada de


diferentes mdias que deveriam estar sincronizadas. Em diversas aplicaes existe dependncia
entre mdias, como no caso de uma TV disponibilizada em um browser via Internet, que se
compem de udio e vdeo. Assim, numa transmisso de TV, o udio deve estar sincronizado com o
movimento dos lbios (ou levemente atrasado, visto que a luz viaja mais rpido que o som, e o ser
humano percebe naturalmente o som levemente atrasado em relao viso).

Figura 11: Skew

33
4 TRANSMISSO EM TEMPO REAL

Para transportar dados em tempo real, como o caso da aplicao multimdia tratada no
presente trabalho, so necessrios protocolos que tratem aspectos de sincronismo e de
temporizao. A seguir abordam-se os protocolos RTP e RTCP, que so capazes de dar suporte a
esses tipos de necessidades.

4.1 RTP

O protocolo RTP (Real-time Transport Protocol) especifica um formato para transmisses


em tempo real, caracterstica necessria a aplicaes de transminsso de TV sobre a Internet.
Atravs desse protocolo podem ser detectadas perdas de pacotes UDP, por exemplo. E isso
realizado utilizando nmeros de seqncia nos pacotes. O RTP considerado um protocolo de
middleware, pois se localiza entre a camada de aplicao e a camada de transporte, conforme
ilustrado na Figura 12, onde foi utilizada a representao adotada pela arquitetura ISO OSI.

Figura 12: Modelo ISO OSI

Esse protocolo tambm d suporte a sincronizao intermdia e intramdia. O campo de


timestamp do cabealho informa ao receptor o momento exato em que esse deve passar os dados ao
usurio. Essa informao usada pelo receptor para absorver o jitter da rede atravs de um buffer
auxiliar. Esse campo tambm usado em conjunto com o protocolo NTP a fim de sincronizar as
diferentes mdias, permitindo ao receptor a adaptao ao skew.

34
O RTP utiliza o RTCP, adiante descrito, para monitorar a qualidade de servio e repassar
informaes sobre os participantes de uma sesso em andamento.

Em termos do modelo OSI [10], como foi dito anteriormente, o RTP se situa entre a camada
de aplicao e a de transporte, coforme melhor mostrado na Figura 13. O IP pode ser tanto unicast
como multicast, e o protocolo Ethernet utilizado na figura apenas um exemplo. No caso aqui
tratado, utiliza-se multicast como modo de endereamento e os pacotes RTP so encapsulados em
pacotes UDP, para transmisso via rede.

Figura 13: Pilha de Protocolos RTP

Uma sesso RTP caracterizada por uma mdia por sesso apenas, podendo ser de udio ou
de vdeo. Tambm so utilizados um conjunto nico de IP, porta e SSRC para cada participante.
Mesmo havendo as sesses distintas, a sincronizao entre udio e vdeo pode ser atingida atravs
do feedback de tempo proporcionado pelos pacotes RTCP, que sero explanados posteriormente.

O pacote RTP composto por um cabealho fixo, uma lista de fontes de contribuio
opcional, um cabealho de extenso opcional e um campo de payload. Esta estrutura pode ser vista
na Figura 14 e o cabealho fixo ser detalhado na prxima subseo. A lista de contribuio ou
CSRC (utilizado para mixers) contm 32 bits, assim tambm como o campo de payload (representa
o contedo do pacote) que tanto pode ser de udio quanto de vdeo e codificado por um codec
(Ex: G.711 ou H.263).

35
Figura 14: Cabealho RTP

O cabealho fixo e a lista opcional de fontes de contribuio so mostrados na Figura 15.

Figura 15: Cabealho Fixo RTP

Os primeiros doze bytes esto presentes em todos os pacotes RTP, enquanto que a lista dos
identificadores CSRC est presente somente quando inserido por um multiplexador. Os campos tm
o seguinte significado:

Version (V): Identifica a verso do protocolo RTP. A verso 2 a utilizada atualmente (2


bits);

Padding (P): Indica a opo de preenchimento do pacote RTP. Se este bit for 1, o pacote
contm um ou mais bytes (octetos) de preenchimento no final do pacote e utilizado para
criptografia. J quando ele setado para 0, no existe nenhum dado til e os dados
complementares devem ser ignorados (1 bit);

Extension (X): Se este bit estiver setado para 1, indica que o cabealho ter uma extenso
com o mesmo nmero de bytes (1 bit). Caso contrrio, o campo de extenso deve ser
desconsiderado;

CSRC Counter(CC): Indica o nmero de identificadores CSRC que seguem o campo fixo do
cabealho (4 bits). E til na unio de vrias fontes de udio em um nico fluxo de dados;

Marker (M): Permite que eventos significativos, tal como limites de quadro, sejam marcados
no fluxo de pacotes (1 bit);

36
Payload Type(PT): Identifica o formato da carga til do pacote, de forma que possa ser
interpretado pela aplicao, ou seja, o tipo de codec utilizado (7 bits);

Nmero de seqncia: um valor que incrementado de 1 a cada pacote RTP transmitido e


pode ser usado pelo receptor para detectar perda de pacotes, bem como para restaurar a
seqncia correta do fluxo (16 bits). O primeiro valor de uma seqncia criado
aleatoriamente;

Timestamp: Identifica o instante de amostragem do primeiro byte no payload, permitindo


assim a sincronizao e o clculo do jitter. Por isso, fundamental na remontagem de mdias
recebidas. Se pacotes consecutivos possurem o mesmo timestamp, isto significa que
pertencem ao mesmo instante de vdeo (32 bits);

SSRC: Identifica a origem de transmisso. Esse nmero escolhido aleatoriamente,


procurando fazer com que todas as fontes de sincronizao tenham identificadores
diferentes. Cada sesso deve ter um SSRC nico. Sendo assim, existir um SSRC para uma
sesso de transmisso de vdeo e outro para uma sesso de transmisso de udio (32 bits);

CSRC: identifica as fontes que contriburam para a carga de dados existente no pacote RTP
e opcional (32 bits). Identifica cada transmissor, durante uma mltipla transmisso. Vrios
participantes de uma sesso RTP podem contribuir para criar pacotes. Quando setado, este
campo adicionado lista de participantes conhecidos.

O cabealho de extenso opcional e contm 32 bits. composto pelo ID do perfil (16 bits),
comprimento (16 bits) e informaes extras de extenso. O perfil RTP estabelece mapeamentos
entre os codecs e os valores do campo PT (Payload Type). Este mapeamento feito com base em
valores constantes de PT que indicam os codecs correspondentes. A Tabela 7 apresenta os codecs
mais conhecidos e utilizados atualmente.

37
PT Formato Especificao
0 PCMU (udio) RFC 1890
3 GSM (udio) RFC 1890
8 PCMA (udio) RFC 1890
14 MPA (udio) RFC 2250
26 JPEG (vdeo) RFC 2435
31 H.261 (vdeo) RFC 2032
32 MPEG I e II (vdeo) RFC 2250
34 H.263 (vdeo) RFC 2190
Tabela 7: RFCs do Perfil RTP

Mesmo sendo a divulgao do tipo de payload esttica (tambm pode ser dinmica),
necessrio que seja feita a descrio da sesso para a aplicao, para que esta possa saber qual o
tipo de payload utilizado. Um dos protocolos mais utilizados para descrio de sesso o SDP ou
Session Description Protocol. Atravs desse protocolo os participantes de uma sesso multimdia
podem padronizar o codec utilizado na comunicao. Alm disso, podem trocar informaes entre
si sobre suas capacidades de processamento de mdia. O SDP faz uso de uma codificao textual
que composta por campos de controle nos quais podem ser descritos o nmero da verso do
protocolo, o identificador de incio de comunicao, nome da sesso, descries da mdia, tempo de
ncio e fim de sesso e informaes de controle. Para isso, seus dados so encapsulados em
mensagens SIP. Mesmo que seja comum o uso de SDP em sesses RTP, seu uso no especificado
como padro.

O protocolo SIP uma especificao do grupo de trabalho MMUSIC do IETF publicada em


1999. Mas a verso atual do protocolo, contida na RFC 3261, foi publicada em 2002. Esse
protocolo tambm baseado em troca de mensagens. Quando utilizado para sinalizao sobre UDP,
torna-se mais rpido e eficiente do que utilizando verses iniciais do H.323. As mensagens podem
indicar um pedido de abertura de comunicao, uma confirmao de recebimento de mensagem, o
cancelamento de pedidos, o registro de usurios e a ocorrncia de eventos em geral. J em
aplicaes que utilizam o padro H.323, utilizado o H.245 para descrio de sesses. Neste caso,
o protocolo H.245 utilizado para negociar e estabelecer os canais de comunicao do RTP.

A escolha do formato do payload tem vrias implicaes intrnsecas. Definindo tambm a


taxa do clock de mdia RTP e o formato de qualquer cabealho de payload. A maioria dos formatos
de payload tem uma variao limitada de taxas de clock. E atravs da especificao do formato de
payload so definidos quais as taxas vlidas. Mltiplos formatos de payload podem ser usados por

38
sesso para que possam ser adotados vrios formatos por sesso RTP. Dessa forma, o formato pode
mudar no decorrer do tempo durante uma sesso. Mesmo tendo essa propriedade, o protocolo RTP
especifica que se udio e vdeo sero transmitidos por uma aplicao, devem ser criados duas
sesses. Uma para transmisso de vdeo e outra para a transmisso de udio, em diferentes portas e
endereos. Esta separao necessria para que a aplicao em questo possa requisitar diferentes
QoS para os tipos de mdia. Alm de permitir que o protocolo de controle RTCP possa funcionar
corretamente.

O campo Timestamp utilizado para o escalonamento da visualizao do vdeo. Ele um


campo de 32 bits contendo um inteiro sem sinal que, inicialmente escolhido aleatoriamente,
incrementado em funo de uma taxa que depende da mdia. Isso feito para que ataques ao stream
RTP criptografados sejam dificultados. Tambm possvel utilizar um timestamp estendido de 64
bits. importante ressaltar que os timestamps criados devem manter uma seqncia contnua de
valores crescentes e no devem acontecer variaes entre eles. Essa exigncia necessria para que
servidores de streaming de mdia trabalhem corretamente. Algo que pode ocorrer que podem
existir timestamps repetidos quando so enviados mltiplos pacotes RTP. Mas nesse caso, cada
pacote ter um nmero de seqncia diferente.

Os formatos de payload de vdeo, normalmente, usam clock de 90kHz. Isto feito para ter
compatibilidade com vdeos MPEG e para incrementar timestamps para quadros de taxa de 24Hz,
25Hz, 29.97Hz e 30Hz. A qualidade de resoluo no implementada pelo protocolo RTP, e deve
ser garantida pela aplicao.

O nmero de seqncia o que identifica cada pacote como nico. atravs dele que o
receptor descobre se pacotes esto sendo perdidos ou entregues fora de ordem. Em uma
comunicao tpica de voz sobre IP, enviando udio em pacotes a perodos de 20 milisegundos, o
nmero de seqncia se sobrepe a cada 20 minutos, aproximadamente. Isso significa que no deve
ser apenas considerado como identificador o nmero de seqncia padro de 16 bits. O
recomendado o uso de nmeros de seqncia estendidos a um inteiro sem sinal de 32 bits ou
maior. Sendo primeiros os 16 bits o nmero de seqncia do RTP, e os 16 bits restantes um
contador do nmero de vezes que o nmero de seqncia foi sobreposto, o que pode ser
representado pela seguinte expresso:

Num_seq_estendido = num_seq + (65536 * contador_empacotamento)

O contador de sobbreposio ou empacotamento deve ter um controle maior do que o


incremento do nmero de seqncia. Este contador s incrementado no momento que o nmero

39
atual de seqncia for menor que o nmero mximo de seqncia. O nmero de seqncia pode ser
invlido e isto deve ser tratado tambm na implementao. Caso se decida no levar em conta o
contador de sobreposio, o nmero de pacotes perdidos e dados estatsticos de perda no so
verificados. Mas importante o seu uso estendido, pois bastante comum a ocorrncia de perda de
pacotes ou erros na reordenao dos pacotes durante o momento da sobreposio do nmero de
seqncia.

O nmero de seqncia sempre inicia com um valor randmico. E isto ocorre pela mesma
razo que acontece com o timestamp. Os nmeros de seqncia so reportados nos pacotes de
relatrio de recepo RTCP. Isso feito para controle de erros de transmisso e criao de dados
estatsticos de perda. Alm disso, o nmero de seqncia deve sempre seguir uma ordem crescente,
somando-se um, na medida que os pacotes so transmitidos. Jamais podero existir saltos de valores
tanto para um nmero maior quanto menor. Mesmo quando um vdeo subdividido, o nmero de
seqncia mantido contnuo. Quando detectado um intervalo entre os nmeros de pacotes, o
receptor percebe que houve perdas no envio dos pacotes por parte do transmissor. A partir disso,
pode ser alterada a ordem dos pacotes atravs de uma atualizao.

Eventos relevantes de um fluxo de mdia so reportados pelo bit Marker ou M. No perfil


RTP definido o significado do evento e o tipo de cada mdia. Ele indica aplicao que algo
importante aconteceu naquele momento da transmisso. Durante uma transmisso de udio, o bit M
setado para 1 quando um pacote enviado aps um perodo em silncio. Isto serve como uma dica
para a aplicao atualizar o ponto de reproduo j que um pequeno lapso no silncio no
percebido pelo usurio. Entretanto, em um fluxo de vdeo, o bit M setado para 1 quando o ltimo
pacote for transmitido.

Para identificar os participantes de uma sesso, o campo SSRC ou fonte de sincronizao


utilizado. Ele nada mais do que um inteiro de 32 bits que aleatoriamente escolhido localmente
pelos participantes da sesso em questo no momento de associao a sesso. Como cada
participante escolhe, dois de uma mesma sesso podem ter o mesmo valor. Este tipo de coliso
percebido no momento em que existe a troca de pacotes entre estes participantes. Quando isto
ocorre, um dos participantes deve enviar uma mensagem BYE e selecionar um novo valor de
SSRC. Sendo assim, o nmero de fonte de sincronizao dos participantes nico em uma sesso
RTP. Desta forma, quando necessrio algum tipo de playback, feita a sincronizao para agrupar
pacotes pelo SSRC do participante. Caso um participante da sesso (por exemplo, o servidor de
streaming) envia mltiplos fluxos aos participantes, cada fluxo deve ter um SSRC nico. Isso
necessrio para que seja feita a distino entre cada fluxo na recepo dos pacotes.

40
Outra caracterstica do protocolo RTP a possibilidade do uso de cabealhos de extenso.
Para isto deve ser setado para 1 o bit X do cabealho padro. Os tamanhos dos cabealhos de
extenso so variveis. Mas o mnimo de 32 bits, sendo os primeiros 16 bits contendo o tipo e os
16 bits restantes contendo o tamanho do mesmo. Normalmente, no so utilizados, mas foram
criados para uso experimental para novos tipos de formato de payload e para otimizao de alguns
tipos de payload. O contedo do cabealho RTP pode ser tanto esttico como dinmico. No caso
esttico, ele duplicado para toda a sesso que usa um determinado tipo de payload. Normalmente,
tudo o que considerado dinmico em um cabealho RTP configurado pelo SDP.

O campo de payload ou de dados pode suportar vrios frames por pacote. Por isso, o
receptor pode checar o tamanho do pacote caso seja um nmero constante de frames por pacotes.
Alm disso, existem alguns formatos de payload que referem a quantidade de frames. Isso muito
importante para aplicao receptora distinguir qual o ponto de reproduo. Esse caso ocorre quando
o nmero de frames pode ser varivel durante a transmisso.

4.2 RTCP

O protocolo RTCP (RTP Control Protocol) tem como objetivo fornecer feedback sobre a
qualidade de servio oferecida distribuio de dados RTP. Isto obtido atravs de transmisses
peridicas de pacotes de controle a todos participantes da sesso RTP, utilizando o mesmo
mecanismo de distribuio do RTP (no caso deste trabalho, multicast) e possuindo uma porta
especfica de controle na sesso. O pacote RTCP padro pode ser visto na Figura 16.

Figura 16: Cabealho RTCP

O tamanho total padro de 32 bits. Os cinco principais campos so:


Version (V): Identifica a verso do protocolo RTP. A verso 2 a utilizada atualmente
(2 bits). No prevista a criao de novas verses e as verses anteriores no so
utilizadas.

41
Padding (P): Indica se o tamanho do pacote extrapolou ou no. Caso o bit esteja setado
para 1, isto significa que um ou mais octetos foram adicionados no final do mesmo. J
quando ele setado para 0, no existe nenhum dado til e os dados complementares
devem ser ignorados (1 bit).
Item Count (IC): utilizado para indicar a quantidade da lista de itens que alguns
pacotes tm. Podem ser adicionados at 31 itens em pacotes RTCP. Quando o IC contem
o valor zero, significa que a lista de itens est vazia. Aplicaes que no necessitam
deste campo podem utiliz-lo com outra funo.
Packet Type (PT): Identifica o tipo de informao que est sendo enviada pela rede.
Existem cinco tipos padres que so descritos na especificao RTP. Outras mais
especficas podem ser definidas no futuro.
Length: Este campo contm o comprimento do pacote que vem abaixo do cabealho
padro. So medidos em unidades, pois todos pacotes RTCP so mltiplos de 32. Caso o
campo de Length esteja com o valor zero, o pacote RTCP apenas ter o cabealho
padro.

O encapsulamento do pacote RTCP similar ao RTP. Ele embarcado em pacotes UDP que
por sua vez so empacotados em pacotes IP. Podem ser enviados mais de um pacote RTCP por
pacote IP. Isto chamado de pacote RTCP composto e encontra-se ilustrado na Figura 17. O
primeiro pacote RTCP o que segue o cabealho do UDP, enquanto o segundo pacote RCTP est
imediatamente aps ao primeiro. Um conjunto como esse, com dois pacotes, chama-se pacote
RTCP composto.

Figura 17: Pacote RTCP Composto

42
Existem alguns tipos de aes que podem ser reportados atravs dos pacotes RTCP. Uma
das mais primitivas utilizaes do RTCP para reporte de relatrios sobre qualidade de recepo.
Isso realizado atravs de pacotes RTCP Receiver Report (RR). Qualquer participante de uma
sesso que esteja recebendo dados pode enviar esse tipo de pacote. O valor PT para esse tipo de
relatrio 201 e seu formato pode ser visto em maiores detalhes na Figura 18.

Figura 18: Pacote Receiver Report

Como pode ser visto na figura, o pacote RR composto por uma srie de itens que
descrevem os dados relacionados qualidade transmisso. O campo RC apresenta o nmero de
blocos reportados. Caso ele seja zero, nenhum item est anexado ao cabealho padro. Mas quando
o campo Length for igual a 1, alm do cabealho padro, o pacote RTCP em questo ter o item
Reporter SSRC de 32 bits. Um pacote RTCP RR pode conter 31 blocos descrevendo a qualidade de
recepo de uma nica fonte de sincronizao. Caso existam mais de trinta e um transmissores, os
receptores devem enviar pacotes RR em um pacote RTCP composto. Cada bloco de relatrio
composto por sete campos num total de vinte e quatro octetos.

O campo Reportee SSRC indica quem o participante do grupo que o dono do bloco de
relatrio que est sendo enviado. Ou seja, quem gerou o pacote RTCP RR e est reportando
informaes para controle de qualidade e criao de estatsticas de transmisso e recepo. Algumas
estatsticas so vlidas apenas durante a existncia da sesso.

O Cumulative number of packets lost um campo inteiro de 24 bits que representa o


nmero de pacotes que deveriam ser entregues menos o nmero de pacotes perdidos. O nmero de
pacotes esperados para recepo calculado a partir do ltimo nmero de seqncia inicial menos o
nmero de seqncia inicial. O nmero de pacotes recebidos leva em conta os pacotes duplicados e
atrasados. Por essa razo, o nmero cumulativo de pacotes perdidos pode ser negativo. E ele
calculado por sesso e no por intervalos. Outro campo calculado por sesso o nmero estendido

43
de nmero de seqncia. J o campo Loss Fraction representa o nmero de pacotes perdidos por
intervalo de relatrio, dividido pelo nmero de pacotes esperado. O valor da frao sempre
multiplicado por 256. Se o nmero de pacotes recebidos for maior que o nmero de pacotes
esperados, o Loss Fraction zerado. E atravs desse valor que o transmissor pode ter uma noo
se a quantidade de pacotes perdidos constante ou varivel. E se a perda transiente ou em longo
prazo. Com isso, possvel fazer a escolha certa sobre o tipo de formato que ser usado para
transmitir a mdia.

O Interarrival jitter uma estimativa estatstica da varincia do tempo de transio na rede,


para pacotes de dados enviados pelo Reportee SSRC. Ele medido em unidades de timestamp e
expresso por um inteiro sem sinal de 32 bits. Mesmo sendo impossvel calcular o exato tempo de
transio, porque o receptor e transmissor no esto com seus relgios sincronizados, calculado o
tempo de transio estimado, atravs da diferena entre o timestamp do pacote RTP e o clock do
receptor, no momento em que o pacote chegou. Para isto, necessrio manter um clock para cada
fonte de transmisso.

O campo LSR representa o timestamp do ltimo relatrio recebido pelo transmissor. Ele
contm trinta e dois dos 64 bits de timestamp do protocolo NTP, includo nos pacotes SR que sero
explicados em maiores detalhes a seguir. Caso no tenha sido recebido nenhum pacote SR do
transmissor, o LSR ter o valor zero. J o campo DLSR indica o tempo de atraso entre o ltimo
pacote RS e tempo de envio do pacote de relatrio de recepo. Ele expresso em unidades de
1/65.536 segundos. Assim como o LSR, o DLSR composto pelo valor zero se nenhum pacote RS
tenha sido recebido. A qualidade de recepo no importante apenas para o transmissor. Porque
atravs do receptor que o transmissor pode ter algum tipo de feedback sobre a qualidade de
transmisso. Dessa forma, o transmissor pode adaptar os seus prprios parmetros s atuais
caractersticas da transmisso. E em geral elas so altamente dinmicas, pois podem se modificar de
vrias formas. Apenas a entrada de um novo participante no grupo multicast pode modificar a
velocidade de transmisso de todos, j que fazem parte do mesmo grupo. Alm disso, atravs desse
tipo de feedback, o transmissor pode verificar se o problema reportado por um receptor tambm
um problema que assola os outros participantes ou se um problema isolado.

O RTT calculado pelo transmissor atravs dos campos LSR e DLSR computados e
enviados em pacotes RR pelo receptor. Podem ser calculados RTTs entre o transmissor e cada um
dos participantes. Alm dos pacotes RR enviados pelos receptores atravs do protocolo RTCP, os
transmissores tambm tm um equivalente. Eles enviam pacotes RS atravs do protocolo de
controle RTP. O formato e campos deste tipo de pacote podem ser vistos na Figura 19.

44
Figura 19: Pacote Sender Report

Os pacotes RS so relatrios enviados aos receptores em um esforo conjunto para melhorar


a qualidade de transmisso e recepo. Um dos objetivos mais usuais deste tipo de mensagem
para sincronizao dos lbios entre udio e vdeo na reproduo multimdia. Como pode ser
observado na Figura 19, o cdigo de tipo de payload 200 para este tipo de pacote.

O campo NTP timestamp composto por um inteiro sem sinal de 64 bits e para que medidas
de tempo possam ser transformadas no tempo NTP, preciso adicionar 2.208.988.800 segundos. J
o RTP timestamp expresso em unidades de clock de mdia RTP, mas representa o mesmo instante
que o NTP timestamp expressa no pacote.

O contador de pacote tem o valor da quantidade de pacotes gerados pela fonte de


transmisso desde o incio da sesso. Enquanto isso, o contador de octetos, como o prprio nome
diz, tem o valor total de octetos contidos no payload destes pacotes, sem incluir os cabealhos
padro. Caso ocorra uma coliso e um novo valor SSRC tenha que ser escolhido, os contadores,
como explicado anteriormente, so zerados.

Atravs dos valores fornecidos pelo transmissor pelos pacotes RR, possvel calcular uma
mdia das taxas de pacotes e de payload enviadas em um intervalo de tempo. A razo para o clculo
dessa mdia o tamanho do payload. Assim, o throughput disponvel para o receptor pode ser
calculado pela multiplicao da mdia do tamanho de payload pelo nmero de pacotes recebidos
pelo receptor em questo.

Alm disso, o protocolo RTCP tambm usado na identificao dos usurios que participam
do grupo multicast. O pacote SDES pode conter informaes que vo desde o nmero do telefone
at o e-mail do participante do grupo. Normalmente, contm dados que so informados pelo usurio
e mostrados na aplicao cliente. Como o pacote SDES composto por vrios itens, torna-se
primordial o detalhamento dos itens SDES para que os pacotes SDES possam ser compreendidos

45
em sua plenitude. Na Figura 20 podem ser observados o formato do item e do tamanho e a ordem
de seus componentes internos.

Figura 20: Item SDES

Os itens SDES que compe os pacotes SDES so formados por trs itens. So eles:
Type: Indica o tipo de item que ser descrito ao longo do item SDES.
Length: Contm o tamanho do item de descrio, ou seja, a quantidade de octetos de
texto do campo Value.
Value: o texto que descreve o item e est na codificao UTF-8 [19].

No existe nenhum tipo de separao ou bit de indicao entre os itens contidos nos pacotes
SDES. O que acontece que so colocados um ou mais octetos nulos entre os itens SDES dentro do
pacote SDES. Quando o campo Type for zero, a lista de itens acabou. Os tipos padres atuais de
itens SDES so:
CNAME: um campo que prov um nome cannico para cada participante. Isto faz
com que exista um modo estvel e seguro de identificar, independente do SSRC, os
participantes do grupo multicast. Isto se torna necessrio pois podem existir nomes
iguais e necessrio ser independente do SSRC pois podem haver colises ou a
aplicao pode reiniciar. Nestes casos, o SSRC ser modificado e a identificao ser
perdida. Mas com este campo isto no acontece. Ele composto pelo nome e IP do
usurio e intermediado pelo smbolo @. Quando se faz uso das caixas NAT de traduo,
necessrio que haja tambm a traduo do RTCP CNAME para criar uma nica forma
de identificao. o nico campo exigido pela especificao RTP que deve constar nos
itens SDES (TYPE = 1).
NAME: Contm o nome do participante para ser disposto na lista de participantes como
parte da interface grfica da aplicao cliente (TYPE = 2).
EMAIL: Contm o endereo eletrnico no formato da RFC 822 [20]. Este dado deve ser
validado como e-mail vlido para se certificar de que um usurio idneo (TYPE = 3).
PHONE: Contm o nmero telefnico do participante. A especificao RTP recomenda
que seja um nmero internacional de telefone (TYPE = 4).
LOC: Identifica o local de cada participante. Pode ou no incluir coordenadas GPS para
localizao (TYPE = 5).
TOOL: Inclui o nome e a verso da implementao RTP (TYPE = 6).

46
NOTE: um recado que pode ser escrito pelo usurio para os outros usurios, mas no
prprio para mensagens instantneas (TYPE = 7).
PRIV: um mecanismo de extenso privada, utilizado para extenses especficas de
descrio. So raramente usados, pois podem ser definidos novos itens para extenso ao
invs de utilizar este campo (TYPE = 8).

O exemplo de um pacote SDES RTCP pode ser visto na Figura 21. Neste exemplo,
representado um pacote SDES com os itens CNAME e NAME.

Figura 21: Pacote SDES

Outro pacote especificado pelo protocolo RTCP o pacote BYE. Este utilizado para
controle de associao de membros. Caso um membro queira sair do grupo, ele deve mandar um
pacote BYE para o grupo. Este tipo de pacote diferenciado dos demais pelo tipo 203 e tem o
formato igual ao da Figura 22. A partir do momento que a aplicao recebe um pacote BYE, ela
obtm o campo RC que contm o nmero SSRC para ignorar qualquer pacote RTP ou RTCP da
fonte especificada. importante manter algum tipo de histrico mesmo algum tempo aps o
recebimento dos pacotes BYE, para permitir a prorrogao dos pacotes de dados.

Figura 22: Pacote BYE

47
Alm disso, nos pacotes BYE podem existir campos de texto explicando a razo da sada do
grupo. Isto til para mostrar na interface da aplicao para os demais usurios. Porm, trata-se de
campos opcionais. Podendo ser ignorados no recebimento.

medida que as aplicaes so desenvolvidas e problemas novos vo sendo descobertos,


torna-se adequado criar algumas extenses padronizadas para melhorar o funcionamento da
aplicao especfica e utilizar as facilidades do protocolo RTP de uma maneira melhor para a
prpria aplicao. O pacote RTCP utilizado para isto o APP e nada mais que uma maneira de
aprimorar o uso do protocolo RTCP. medida que desenvolvedores criam novas facilidades, eles
podem adicion-las lista de tipos de pacotes padres, caso sejam aceitas como adequadas para uso
geral. O formato dos pacotes APP mostrado na Figura 23. O campo PT deve ser preenchido pelo
valor numrico 204 e deve ser criado um nome de pacote que se relacione ao nome da aplicao que
est sendo desenvolvida e que seja nico em relao aos demais pacotes e aplicaes. Alm disso,
existem os dados dispostos em octetos no decorrer do pacote APP.

Figura 23: Pacote APP

Tendo em vista os pacotes RTCP descritos anteriormente neste captulo, torna-se bastante
trivial o entendimento geral do funcionamento do protocolo e de todos as precaues que o
circundam. Caso um participante servidor gere um pacote RTCP composto, este deve comear com
um pacote RTCP SR. Caso seja um cliente, deve iniciar com um pacote RTCP RR. Aps o pacote
RR ou RS, necessrio colocar em seguida um pacote SDES que deve incluir obrigatoriamente um
item CNAME no mnimo. A incluso dos outros itens conduzida em relao ao perfil RTP
escolhido. Por fim, devem ser includos sempre como ltimo pacote o BYE. Os outros pacotes
descritos no necessitam seguir uma ordem de preferncia. Estas regras servem para que exista um
modo de validao de pacotes seguros.

48
Um banco de dados de informaes sobre a sesso e sobre os participantes da mesma
guardado por cada aplicao que est na sesso RTP. Existem algumas variveis que so guardados
para controle de tempo atravs do protocolo RTCP. E so elas:

A largura de banda RTP: configurada a partir do incio de vida da aplicao e trata-se


da largura de banda disponvel para a sesso;
A frao da largura de banda RTCP: a frao da largura de banda RTP reservada para
pacotes de relatrio RTCP. Normalmente, separa-se 5% para isto. Mas pode ser diferente
a porcentagem, dependendo do perfil RTP escolhido pela aplicao. Caso seja escolhido
0%, nenhum pacote RTCP ser enviado;
A mdia de tamanho dos pacotes RTCP enviados e recebidos pelos participantes;
O nmero de membros na sesso;
A frao dos participantes que enviaram pacotes RTP durante o intervalo de tempo de
processamento de relatrios;
O tempo no qual a ultima aplicao enviou o ultimo pacote RTCP;
O tempo marcado para enviar a prxima transmisso;
Um flag indicando qual aplicao enviou o ltimo pacote RTP desde os ltimos dois
pacotes RTCP;
Um flag indicando se a aplicao enviou algum pacote RTCP desde que foi inicializada.

Alm das variveis descritas anteriormente, outras devem ser mantidas para que possam ser
includas em pacotes RTCP SR. Ou seja, pacotes de controle dos transmissores. E so elas:

O nmero de pacotes de dados RTP que foram enviados ao longo da sesso;


O nmero de octetos contidos nos pacotes de dados RTP que foram enviados ao longo
da sesso;
O ltimo nmero de seqncia utilizado;
A correspondncia entre o timestamp NTP e do clock RTP que est sendo usado.

Uma aplicao de streaming em tempo real, que utiliza o protocolo RTP e RTCP, segura e
consistente se cada participante mantm o estado dos outros membros da sesso durante o tempo de
vida da mesma. As informaes que os participantes devem manter tambm podem ser guardadas
em variveis e devem conter os seguintes dados:

O identificador SSRC;

49
As informaes de descrio para pacote RTCP SDES: CNAME e outros especficos
dependendo da aplicao necessitada;
Dados que permitem o clculo de estatsticas sobre qualidade de recepo para que seja
possvel a criao e envio de pacotes RTCP RR pelos receptores: jitter e nmero de
pacotes perdidos;
Dados recebidos pelos pacotes RTCP RS que permitem a sincronizao labial entre som
e imagem;
O ltimo momento no qual o participante enviou algum tipo de pacote na rede para o
grupo multicast da sesso para que no hajam participantes inativos. Caso existam
participantes inexistentes (cadastrados no grupo), a largura de banda utilizada ser mal
usada porque pacotes dos demais participantes sero encaminhados pela rede para este
participante inexistente;
Um flag que indica se este participante enviou algum tipo de dado durante o intervalo de
tempo para relatrios RTCP;
O buffers de reproduo de mdia;
O estado do codec utilizado;
Informaes para controle de erros em geral, para que possam ser corrigidos.

Qualquer tipo de estrutura criada a partir dos dados descritos anteriormente, devem ser
indexadas pelo SSRC que o que identifica unicamente cada participante da sesso RTP. Mas para
ser feita a sincronizao labial entre som e imagem, os participantes devem ser encontrados tambm
pelos CNAMEs.
Uma das etapas que devem ser desenvolvidas a etapa de validao dos participantes recm
cadastrados para que apenas participantes vlidos sejam cadastrados. Por isto, antes que um
participante seja aceito pelo grupo multicast que representa a sesso RTP, um pacote de validao
deve ser enviado aos demais. Para isto, no devem ser utilizados apenas pacotes RTP. Portanto,
devem ser usados pacotes RTCP para esta funo para que no seja um mtodo vulnervel de
validao.
Uma das maneiras mais simples manter uma tabela de participantes da sesso que tenham
recebido apenas um pacote RTP com um tamanho fixo. Esta deve ser leve e mantida com um time
out constantemente verificado. Desta forma, usurios inativos podem ser descartados. Cada pacote
RTP que contenha um CSRC vlido, este deve ser adicionado no banco de dados.

Outra forma de descartarem participantes atravs dos pacotes BYE. Quando um destes
recebido, o participante que o enviou decidiu sair da sesso RTP. Como no existe nenhuma
segurana quanto ordem de chegada dos pacotes, j que os pacotes so empacotados em

50
datagramas UDP, um pacote RTCP BYE pode ser recebido como no sendo o ltimo pacote do
participante em questo. Para prevenir este tipo de problema, pode ser usado algum tipo de delay
para o envio da mensagem BYE. Permitindo assim uma sincronizao probabilstica das
mensagens. Tambm deve ser definido algum tipo de tempo limite para inatividade. Caso o
participante fique um tempo maior que o esperado sem mandar pacotes, ele tambm ser
descartado. Outra questo que deve ser tratada quando mais de um membro decide sair da sesso
ao mesmo tempo. Isto pode causar congestionamento na rede com pacotes RTCP BYE. A verso 2
do protocolo RTP permite que pacotes BYE sejam mandados imediatamente apenas se menos que
50 membros decidem sair da sesso. Caso o nmero seja maior, precisar ser utilizado algum tipo
de delay. Este tempo de espera deve ser proporcional ao nmero de membros que est tentando sair
ao mesmo tempo.

51
5 ARQUITETURA

Para disponibilizar a programao da FURG TV canal de TV administrado pela FURG e


distribudo via cabo pelas operadoras desse tipo de mdia na cidade do Rio Grande - na Internet, foi
implementado um sistema cuja arquitetura e funcionamento so apresentados a seguir.

O sistema para disponibilizao do vdeo e audio de um canal de TV sobre a Internet se


constitui de dois mdulos em Java [5]: servidor e cliente. Considerando que a gerao dos sinais de
udio e vdeo so realizados a partir de arquivos contendo a programao a ser distribuda (assim
funciona a FURG TV) o aplicativo servidor abre os arquivos de vdeo e udio e comea a transmiti-
los via multicast pela rede. Para isto, os arquivos so dividos em vetores de bytes que so
encapsulados na medida que so enviados. Esses bytes so agrupados em pacotes RTP, que so
transmitidos via UDP. O servidor passa ento a executar um lao de espera por conexes via socket
[6].

Tambm foi implementado um mdulo de configurao atravs do qual, so ajustados os


parmetros da conexo entre o transmissor e o receptor. Toda a vez em que for necessrio mudar os
parmetros, ele tambm deve ser executado. Atravs da sua execuo criado um arquivo texto de
configurao, contendo os seguintes dados: Protocolo de Transporte, Porta, IP Multicast e TTL.

No momento que o mdulos transmissor e receptor iniciam a sua execuo eles acessam o
arquivo texto contendo os parmetros da conexo. Dessa forma possvel ajustar o mesmo
endereo multicast e por isso importante que o mdulo de configurao seja executado antes da
execuo dos demais mdulos. O usurio que transmitir o arquivo multimdia tambm deve
informar o tempo de durao do arquivo que ser transmitido. Esse valor armazenado em um
arquivo texto com o nome de tempo.txt que ser lido pelo mdulo receptor para que seja definido o
tempo de durao do loop de espera por dados.

O servidor comprime os arquivos antes de envi-los aos clientes. Os dados comprimidos so


encapsulados em pacotes RTP. medida que o transmissor l o arquivo multimdia ele coloca os
bytes lidos em um buffer do qual so produzidos frames codificados. So assinalados um nmero
de seqncia e um timestamp para cada frame e colocados em pacotes RTP, prontos para o envio.
Caso um frame seja maior do que o tamanho padro de pacote, ele fragmentado em vrios pacotes
para poder ser transmitido. Da mesma forma, se um frame for bem menor que o tamanho padro de
um pacote, ele pode ser agrupado a outros frames pequenos e, estes, colocados em um pacote RTP.

O mdulo servidor tambm responsvel por enviar pacotes RTCP, periodicamente,


contendo relatrios do status da transmisso atual das mdias. Como se trata de uma comunicao
full-duplex, ele tambm recebe feedback dos clientes sobre a qualidade de transmisso em pacotes
52
RTCP, dessa forma podendo otimizar a transmisso. O funcionamento do servidor de streaming
est esquematicamente ilustrado na Figura 24.

Figura 24: Funcionamento do Servidor de Streaming

Os recursos fundamentais de redes em Java so proporcionados pelo pacote java.net, pelo


qual disponibilizada a comunicao baseada em fluxos. Isso significa que os aplicativos podem
visualizar as redes como fluxos de dados. Alm disso, esse esquema tambm proporciona a viso de
comunicao baseada em pacotes, o que possibilita s aplicaes a condio de transmitirem
pacotes individuais, normalmente utilizados para a transmisso de vdeo e udio pela Internet.
Atravs dos sockets (tambm disponibilizado pelo Java.net), um processo pode estabelecer
uma conexo com outro. E proporciona uma abstrao capaz de fazer com que as operaes sobre a
rede sejam vistas como operaes de E/S sobre um arquivo. Um programa pode ler ou escrever em
um socket, como se faz com um arquivo, mas ao invs de salvar localmente o arquivo, um fluxo
enviado at outro processo. No caso de streaming, so utilizados sockets de datagrama do protocolo
de transporte UDP que oferece servios sem conexo. Ou seja, no existem garantias de que os
pacotes enviados chegaro e que chegaro na ordem certa. Com primitivas no bloqueantes, esse
tipo de conexo pode ser comparado com o servio postal. Ou seja, a maneira como o correio envia
suas cartas se assemelha bastante ao modo de comunicao UDP. Como pode ser visto na figura 25,
necessrio fazer um bind para associar um socket a uma porta.

53
Figura 25: Localizao do Socket

Durante a captura e transmisso de multimdia, o codificador invocado internamente para


produzir os frames comprimidos, que so entregues a rotina de criao de pacotes RTP. At que
seja montado um frame completo de udio, so coletadas seqncias de bytes representando o sinal
a ser transmitido. Os dados do buffer de entrada so colocados em frames de tamanho fixo.
Aparelhos de captura de udio comuns podem produzir sinais digitais com uma resoluo que varia
de 8 a 24 bits. Usando quantizao -law or A-law com taxas entre 8000 e 96000 quadros por
segundo, mono ou estereo. A escolha a ser adotada altamente dependente do tipo de codec
escolhido. Os quadros de udio so passados pelo encoder para compresso, mas podem ser
passados para o buffer de sada com frames de tamanho fixo ou varivel, dependendo do codec. A
taxa continua fixa, mesmo sendo frames tamanho fixos ou variveis. Tratando-se de vdeo,
aconselhvel converter o arquivo para um formato mais compatvel com o tipo de codec escolhido.

Quando uma requisio de transmisso recebida pelo servidor, disparada uma thread
para adicionar o cliente que a realizou no grupo multicast e fazer todo o controle necessrio para a
permanncia dele atravs da sesso. Tambm implementado um controle da largura de banda para
que no momento da distribuio do vdeo para os clientes no ocorra sobrecarga nem lentido em
demasia. O cliente executado sob a forma um Applet embutido no servidor Tomcat [7].

O Tomcat um servidor de aplicaes Java para web, distribudo como software livre e com
cdigo aberto, dentro do conceituado projeto Apache Jakarta e oficialmente endossado pela Sun
como a Implementao de Referncia para as tecnologias Servlet e JSP. robusto e eficiente,
podendo ser utilizado mesmo em um ambiente de produo. O Tomcat tem a capacidade de atuar

54
tambm como servidor web/HTTP, ou pode funcionar integrado a um servidor web dedicado como
o Apache httpd ou o Microsoft IIS.

Cada pacote a ser transmitido tem um campo de timestamp que representa o instante do
primeiro octeto de dados no frame. Como foi dito anteriormente, ele iniciado a partir de um valor
randmico inicial que incrementado atravs de uma taxa dependente da mdia. Como no nosso
caso, trata-se de um arquivo multimdia pr-gravado em disco, os timestamps criados apenas
representaro a seqncia de tempo de reproduo de cada quadro. Caso um quadro seja
fragmentado em mltiplos arquivos RTP, cada pacote conter o mesmo timestamp. O que de
grande valia no reordenamento de pacotes e seqncia de reproduo. Um exemplo de um pacote
fragmentado pode ser visto na Figura 26.

Figura 26: Fragmentao de Pacotes RTP

Na figura, o quadro comprimido divido em dois e o timestamp duplicado. Aps,


colocado o cabealho RTP em cada um e eles so encapsulados em dois pacotes RTP. Um dos
problemas dessa tcnica a perda de fragmentos, que no possibilita a reconstruo no mdulo
cliente por falta de informaes para tal. O servidor escolhe se ir mandar os fragmentos de uma
vez ou em linhas de tempo separadas. Os pacotes so espalhados entre o intervalo de quadros, e
como o protocolo RTP no faz nenhuma garantia sobre resoluo, estabilidade e preciso do clock
de mdia, o servidor ser o responsvel pela escolha do clock apropriado.

Como j foi dito anteriormente, o mdulo cliente responsvel por receber os pacotes RTP
provenientes da rede e fazer as correes necessrias para reparar o caso de pacotes perdidos,
recuperao de tempo, descumprimento da mdia e apresentao do arquivo multimdia para o
usurio. Alm disso, deve enviar relatrios sobre a qualidade de recepo para o servidor de
streaming atravs de pacotes RTCP. Desta forma, o mdulo servidor pode adaptar a transmisso
para as caractersticas necessrias da rede em uso. O mdulo cliente tambm mantm um banco de

55
dados sobre os demais participantes da sesso em questo para prover informaes aos usurios,
como pode ser visto na Figura 27, que ilustra o funcionamento do cliente.

Figura 27: Funcionamento da Aplicao Cliente

As operaes necessrias em um cliente RTP so muito mais complexas do que as de um


servidor RTP de streaming. Uma das grandes razes para esse aumento de complexidade a
caracterstica de variabilidade inerente ao IP, pois o cliente deve estar preparado para compensar
pacotes perdidos e recuperar a linha temporal de reproduo. O primeiro passo no processo de
recepo, no lado cliente, a coleta de pacotes da rede, validao e insero dos mesmos nas filas
de espera. Essa fase de processamento do mdulo cliente independe do formato de mdia. Aps a
sada das filas de espera, os pacotes so verificados e checados antes de serem enviados ao buffer de
reproduo. A partir desse buffer que feita a suavizao da reproduo. Muitas vezes, quadros so
formados por vrios pacotes. Quadros danificados ou perdidos so reparados e quadros so
decodificados. Finalmente, o arquivo multimdia pode ser visto pelo usurio requisitante. Caso
existam mltiplas entradas de udio, o que no o nosso caso, torna-se necessrio o uso de um
mixer de udio para uniir os mltiplos fluxos em uma s sada de udio.

56
Figura 28: Arquitetura Proposta

A arquitetura descrita pode ser mais bem observada no exemplo da Figura 28. Parte-se do
pressuposto de que o Cliente A no fez solicitao alguma e que o Cliente B j faz parte do grupo
multicast em questo. O que de grande valia a seqncia de acontecimentos decorrentes do
acesso do Cliente C ao link com o Applet. A partir deste momento, o Applet cria uma conexo via
socket com o Servidor de Streaming que, por sua vez, dispara uma thread e adiciona o Cliente C ao
grupo atual de transmisso.
Outra caracterstica do mdulo cliente que ele deve manter um bom valor dos gargalos
criados entre os pacotes recebidos pela rede. E deve estar preparado para receber pacotes em
rajadas. Alm disso, o cliente guarda o valor exato do tempo de chegada dos pacotes RTP para que
o jitter possa ser calculado. Caso seja mal calculado, existir uma demora demasiada entre cada
jorrada de pacotes, causando um delay de reproduo. Para isto, a taxa de clock de mdia deve ser
somada com o offset para correo de skew entre o clock de referncia e o clock de mdia. O
processamento dos pacotes processado em uma thread separada. Dentro do loop, pacotes so lidos
atravs do socket multicast e inseridos nas filas de espera. A partir da, os pacotes so passados
quando necessrio para reproduo. Caso pacotes cheguem em rajadas, alguns podem continuar nas
filas de espera, dependendo da taxa de reproduo e capacidade de processamento. Sendo assim,
uma thread espera dados do socket e os coloca nas filas de espera. Outra thread remove os dados
das filas para a reproduo da mdia, atravs dos campos timestamps de cada pacote RTP.
Quadros so guardados no buffer de reproduo por um tempo para suavizar as variaes de
tempo causadas pela rede. Alm disso, permite que quadros fragmentados possam ser reagrupados.
Os quadros so descomprimidos, erros so escondidos e a mdia pode ser interpretada pelo usurio.

57
O buffer de reproduo contm uma lista de nodos ordenados pelo tempo. Cada n representa um
quadro de dados de mdia, associado com informaes temporais. Cada n contm uma estrutura de
dados com um ponteiro para o prximo n, o tempo de chegada, o timestamp RTP e o tempo de
reproduo para o quadro.
Quando um pacote RTP chega, o ltimo da fila de espera removido e inserido um novo
nodo no buffer de reproduo e posicionado em relao ao timestamp. Aps todos os fragmentos de
um quadro serem recebidos, o decodificador invocado. Codecs de udio no fragmentam quadros
e cada pacote contm um quadro. J codecs de vdeo, muitas vezes, geram mltiplos pacotes por
quadro de vdeo com o campo Marker (M) do pacote RTP marcando o ltimo fragmento. Mas nem
sempre quando um pacote com o bit M com o valor 1 quer dizer que o quadro completo chegou
completamente, pois pacotes podem chegar em ordens diferentes devido aos pacotes empacotados
em datagramas. Neste caso, so utilizados o mesmo timestamp e o menor nmero de seqncia
utilizado para o ltimo pacote de um quadro completo. Quando o quadro for reproduzido, o n ser
removido. Uma das principais caractersticas que devem ser definidas o delay de reproduo
escolhido. O tempo de espera antes de algum erro de correo nos pacotes recebidos, o tempo de
espera entre o recebimento do primeiro e o ltimo pacote de um frame e a variao de tempo entre
os pacotes, causada pelo jitter, so alguns dos fatores que influem na escolha do delay correto.
O espaamento entre pacotes de um quadro e o tempo de espera entre pacotes de dados e
pacotes de correes de erros controlado pelo servidor de streaming. Quando o cliente for escolher
o tempo de reproduo para cada frame, ele ir seguir alguns passos. Primeiramente, a linha
temporal do servidor ser mapeada na linha temporal local, compensando o offset entre os clocks do
servidor e do cliente. Ento, o cliente ir compensar clock skew do servidor. O tempo de espera de
reproduo da linha temporal local calculado tendo como base um componente do servidor
contendo seu prprio delay de reproduo e o jitter criado pela rede. Aps isto, o tempo de espera
de reproduo ser ajustado caso a rota dos pacotes tenha mudado. Finalmente, o tempo de espera
de reproduo adicionado base temporal para o clculo do tempo de reproduo do quadro atual.
inevitvel que haja variaes na entrega de pacotes pela rede. Com isto, ser escolhido um
valor maior que o jitter da rede para que possa ser esperado antes de ser processado. Alguns
segundos bastam para uma compensao apropriada. Como no possvel descobrir de antemo o
jitter induzido pela rede. Ser escolhido um valor randmico que poder ser ajustado no decorrer da
transmisso atravs de pacotes RTCP. O estimado jitter multiplicado por 3 deve ser somado ao
tempo atual. Isto infere um novo tempo de reproduo. A variao do jitter ir depender tanto do
caminho percorrido pelo trfico da rede quanto o restante de dados trafegando na rede. A adaptao
apenas tentar adaptar o delay do buffer de reproduo caso acontea uma mudana significativa

58
em uma poro de pacotes descartados pela demora na chegada. Tambm ir adapt-lo quando
vrios pacotes forem recebidos do servidor, caso ele esteja inativo por um perodo de tempo.
Alguns eventos de mdia tambm podero aumentar o tempo de espera entre pacotes
consecutivos. Por exemplo, o silncio suprimido no udio pode causar um gargalo entre o ltimo
pacote e o primeiro pacote do prximo frame. Outro exemplo uma variao da taxa do quadro de
vdeo pode causar variaes nos tempos de chegada entre os pacotes.
O processo de reproduo de udio assncrono. Por isso, enquanto um quadro est sendo
reproduzido, outro estar sendo processado em outra thread. Esta caracterstica essencial para
reproduo em sistemas operacionais com suporte limitados para aplicaes multimdia. Isto de
extrema importncia para este trabalho devido ao fato de que o cliente ser acessado via Internet e
ser feito em Java. Ou seja, no existe um conhecimento prvio sobre qual sistema operacional os
clientes estaro executando o mdulo cliente. J o processo de reproduo de vdeo dedicado
atualizao da taxa de exibio, o que determina o tempo mximo entre o cliente escrever no buffer
de sada e a imagem ser exibida ao usurio. Frames (quadros) no so representados
instantaneamente.
O Applet ser disponibilizado atravs de um link na pgina da FURG TV
(www.furgtv.furg.br). Aps fazer a solicitao de conexo por uma porta em um socket, utilizado
uma primitiva receive(), esperando assim a transmisso dos dados. Aps o final da transmisso, o
servidor fechar a conexo atravs da primitiva stop(), terminando assim a sesso. Desta maneira,
ser disponibilizado o canal de televiso da Universidade Fundao Universidade Federal do Rio
Grande via streaming na Internet.

5.1 Mdulo de configurao

O mdulo Configura TV um arquivo chamado Configura_TV.jar composto de duas


classes, cujo contedo encontra-se listado no ANEXO 1. A classe Main.java corresponde ao
programa principal e responsvel por invocar a classe Parametros.java. Esta, por sua vez, cria o
arquivo de configurao (parametros.txt) no diretrio raiz, contendo as seguintes informaes:

Protocolo de Transporte: A aplicao necessita do envio de streams via Internet. Para


isto, deve ser utilizado um protocolo de transporte como ponto de acesso. Tanto pode
ser UDP quanto TCP, dependendo da necessidade. No nosso caso, ser UDP.
Porta: um valor inteiro que representa a ligao entre a camada de aplicao
(interface com o usurio) e a camada de transporte (comunicao).
IP Multicast: O endereamento Multicast permite enviar pacotes IP para um

59
determinado grupo de usurios. Pode ir de 224.0.2.0 at 238.255.255.255.
Time To Live (TTL): Parmetro responsvel pelo controle do tempo de vida de um
datagrama, evitando assim a existncia de um loop eterno devido a algum erro de
roteamento.

O arquivo parametros.txt, aps ser criado pela execuo do Mdulo de Configurao,


aberto pelos mdulos Transmissor e Receptor, no momento em que realizada a conexo via socket
entre eles. Os dados contidos no arquivo so utilizados para possibilitar a realizao de uma
conexo consistente. Dessa forma, o nmero de IP, a porta, e o TTL podem ser modificados para
um maior dinamismo na aplicao devido a restries dos endereos multicast. O protocolo de
transporte no editvel, devido a natureza da comunicao ser sem confirmao (Datagramas).

Figura 29: Aplicao de configurao

A Figura 29 apresenta a interface do Mdulo de Configurao oferecida aos usurios. Como


pode ser visto, existem quatro campos de texto (JTextField), nos quais os trs ltimos so editveis.
Para que possam ser feitas modificaes nos parmetros, o campo de texto em questo deve ser
ativado atravs de um clique no JTextField correspondente. Para que as modificaes sejam
aplicadas pelos outros mdulos, necessrio que elas sejam salvas. Para isso, deve-se clicar no
boto Salvar ou atravs do sub-menu Salvar Configuraes. Alm disso, o Mdulo Servidor deve
ser reiniciado.

Existe um sub-menu chamado Sobre contendo informaes para que o usurio do Servidor
de Streaming possa configurar a conexo entre o servidor e os clientes, atravs da modificao dos
parmetros contidos no arquivo texto. Tambm existem outro sub-menu que fecha a aplicao e o
boto Fechar que tem o mesmo objetivo. Todos os componentes so colocados dentro de um
JFrame (container). Para cada campo, existe um texto pop-up de ajuda, descrevendo-o para que
possa haver um entendimento sobre quais valores podem preencher os campos.
60
Para o desenvolvimento da aplicao foram utilizados os seguintes pacotes: javax.swing,
java.awt e java.io. Os dois primeiros pacotes permitem a criao da interface grfica. J o pacote
java.io permite operaes de entrada e sada (por exemplo: criar, editar e destruir arquivos de texto).

5.2 Mdulo Transmissor

Trata-se de um arquivo chamado compactado e executvel chamado


Transmissor_FURGTV.jar que composto pelas bibliotecas JMF (jmf.jar, customizer.jar,
sound.jar, mediaplayer.jar e multiplayer.jar) e pelos arquivos listados no ANEXO 2. O arquivo
principal do mdulo o Main.java que instancia um objeto Janela. Este ser o responsvel por criar
a janela principal do servidor de streaming. A interface criada pela classe Janela.java pode ser visto
na Figura 30.

Figura 30: Transmissor FURGTV

Para iniciar o processo de streaming, deve-se clicar no boto Adicionar Vdeo para abrir o
arquivo multimdia em questo para ser enviado pela Internet para os clientes que acessarem o link
na pgina www.furgtv.furg.br para assistir a FURG TV via rede. Aps o clique, aberta uma janela
do tipo javax.swing.JFileChooser, como pode ser observado na Figura 31. A janela principal no
pode ser acessada enquanto no for escolhido um arquivo ou for cancelada a operao.

61
Figura 31: Selecionando o arquivo atravs do javax.swing.JFileChooser

Aps a escolha do arquivo em questo, ele selecionado passado para uma varivel URL
chamada de mediaURL que utilizada para criar o MediaLocator que ser passado como
parmetro, junto aos dados contidos no arquivo parmetros.txt (TTL, IP e Porta), para o objeto
tempo durante sua criao.
A instanciao do objeto tempo se faz necessrio para definir o tempo de durao do arquivo
de vdeo que ser transmitido. Isto til para a definio, tanto no transmissor quanto no receptor,
da temporizao de streaming. A partir deste momento, uma nova janela criada para a
especificao do tempo de durao atravs de trs campos: horas, minutos e segundos. Aps o
preenchimento destes, deve-se clicar no boto OK como mostrado na Figura 32. Isto far com que
seja criado um arquivo chamado tempo.txt com a durao do vdeo. Este arquivo ser acessado
mais tarde pelo mdulo Receptor, durante sua execuo. Com isto, finalizada a janela de
temporizao contida na figura e criada a janela contido na Figura 35.

Figura 32: Janela de Temporizao

Aps a confirmao sobre a durao do vdeo, atravs do clique no boto OK, criado um
novo objeto Transmissor (proveniente da classe Transmissor.java). Esta classe a que faz todo o

62
processamento de dados e transmisso via rede. Primeiramente, configurada a interface visual e os
atributos (MediaLocator, IP, TTL e Porta) so preenchidos pelos parmetros passados pelo objeto
tempo. Aps executado o procedimento start(), o que inicia a transmisso de verdade. Caso
acontea um erro durante a transmisso, este mtodo retornar uma String com o erro especificado.
Do caso contrrio, retornar nulo. O procedimento bastante simples: cria-se o processor atravs do
procedimento createProcessor() para o arquivo especificado pelo MediaLocator. Aps, utilizado
o mtodo createTransmiter() para criar as sesses RTP atravs dos RTPManagers. Finalmente,
utilizado a primitiva start() contida na Classe Processor. Os atributos e mtodos da classe
Transmissor.java podem ser vistos em maiores detalhes na Figura 33.

Figura 33: Classe Transmissor

O procesimento createProcessor() cria um DataSource atravs do MediaLocator que contm


o arquivo que ser transmitido. Ento criado um Processor para tratar a entrada de dados do
DataSource. Em seguida, o Processor configurado e as trilhas so extradas do mesmo e guardadas
em um vetor chamado tracks[] do tipo TrackControl. Caso exista pelo menos uma trilha vlida
(vdeo ou udio), criado um ContentDescriptor que ser setado para raw.rtp para restringir as
trilhas para apenas formatos vlidos RTP. Para cada trilha extrada, verificada sua correspondente
nos formatos disponibilizados pela API JMF. Caso a trilha seja de vdeo, o tamanho da tela de
reproduo testado porque os formatos JPEG e H263 funcionam apenas com determinados
tamanhos de vdeo. Aps a configurao das trilhas, criado um fluxo grfico com um DataSource
de sada.
63
O procedimento createTransmiter() inicializa o vetor de RTPManagers com a instanciao
de um objeto da classe Conexao.java que recebe como parmetros o IP, a porta e o TTL. Atravs
desta classe so criados duas sesses RTP atravs de duas conexes socket como pode ser visto na
Figura 34. Nela esto representados a classe Conexo.java e a classe SockInputStream.java.
Existem duas conexes socket entre elas (dataOutStrm e ctrlOutStrm), uma para cada trilha. Aps a
criao das sesses, inicia-se o envio de dados para o grupo multicast.

Figura 34: Conexo via socket

A janela de transmisso o que representa o ltimo estgio da execuo do mdulo


Transmissor. Esta janela tem o ttulo Servidor de Streaming FURGTV e apresenta ao usurio qual
o IP Multicast no qual foi criada a sesso RTP para transmitir os dados. Para o mesmo endereo,
so usadas a porta especificada para transmitir um tipo de trilha (por exemplo: vdeo) e o mesmo
nmero de porta mais dois para transmitir o outro tipo de trilha (por exemplo: udio). Para cada
trilha criada uma sesso. Alm disso, o status da transmisso demonstrado. Isto pode ser visto
pela Figura 35, na qual o status transmitindo e as sesses foram criadas com o endereo IP
Multicast 232.0.0.1.

64
Figura 35: Janela de Status de Transmisso

Na janela principal sempre existir uma aba ativa. Na Figura 30, a aba Servidor de Vdeos
a que exibida por padro no momento em que executado o mdulo Transmissor. A segunda aba,
chamada de Sobre, demonstrada na Figura 36. Para que uma aba fique ativa, deve-se apenas clicar
sobre a mesma, em seu ttulo. J a ltima aba apenas um informativo sobre os meus dados
pessoais para futuro contato.

Figura 36: Aba Sobre

5.3 Mdulo Receptor

O Mdulo Receptor um arquivo compactado e executvel chamado


Receptor_FURGTV.jar que composto pelas bibliotecas JMF (jmf.jar, customizer.jar, sound.jar,
mediaplayer.jar e multiplayer.jar) e pelos arquivos Main.java, PlayerApplet(contidos no ANEXO
3) e Conexao.java (contido no ANEXO 2). A classe Main a que envoca a classe PlayerApplet,
criando assim um objeto PlayerApplet. O funcionamento do applet bastantes simples, para ser
executado deve-se executar o procedimento init() contido na classe. Sua primeira tarefa ler o
arquivo parametros.txt para obter os dados configurados pelo mdulo transmissor (TTL, Porta e IP
Multicast). A partir disto, inicializado o vetor de String, chamado sesso[], com os parmetros
obtidos. Com isto, executada a funo booleana initialize() que retorna true se os parmetros
forem corretos e as sesses tenham sido inicializadas. Caso contrrio, retorna false. A primeira
tarefa da funo criar um RTPManager para cada sesso especificada. Ento os RTPManagers so
configurados para adicionar o receptor ao grupo multicast (sesso). Para isto, eles so inicializados
com objetos da Classe Conexo.java. O prximo passo a criao de um buffer com o tamanho de
350. Daqui em diante, deve-se esperar receber algum dado do transmissor. Isto verificado por 30

65
segundos no mximo. Enquanto isto est acontecendo, o label status contm o valor sintonizando
para um melhor entendimento do usurio sobre o que est acontecendo durante a transmisso. Caso
nenhum dado tenha sido recebido durante os 30 segundos, o label recebe o valor de canal fora do ar
e os players so fechados, assim tambm como os RTPManagers. Para isto, existe o mtodo close().
Outro mtodo importante da classe PlayerApplet o update() que, dependendo do parmetro
passado, ou adiciona participante ao grupo (SessionEvent) ou recebe streams
(ReceiveStreamEvent). Caso tenha recebido um stream, o evento mapeado para cada um dos
seguintes eventos:

RemotePayloadChangeEvent: Quando necessrio algum tipo de mudana de payload,


o que no possvel e faz com que o Mdulo Receptor seja fechado.

NewReceiveStreamEvent: Evento que representa a chegada de um novo stream de


dados. criado um DataSource para o stream e atravs dele, descobre-se o formato da
mdia. Aps criado um Player com um DataSource para o MediaManager. Cria-se
uma janela para o player e o stream recebido sincronizado.

StreamMappedEvent: Caso o stream no seja nulo, criado um novo DataSource e os


formatos das trilhas so descobertas atravs de uma varivel RTPControl.

ByeEvent: Representa a chegada de uma mensagem Bye, indicando a sada de um


participante da sesso. ento executada a funo find() que procura por players no
vetor playerWindows[] e, caso o stream passado como parmetro seja condizendo com
o do player, o objeto Player retornado pela funo. Caso contrrio, retorna null e os
players so fechados atravs do mtodo close().

Existem duas subclasses que so utilizadas para a interface visual do Player:


PlayerWindow (mtodos inicialize(), close() e addNotify()) e PlayerPanel (mtodo
getPreferredSize()).

O Mdulo Receptor de utilizao muito simples para o usurio. Basta clicar no link
respectivo ao Applet que ser instantaneamente apresentado, no Player FURGTV, o programa que
est sendo transmitido no exato momento da execuo.

66
6 JAVA MEDIA FRAMEWORK

O JMF tem como funo principal incorporao de mdias iscronas em aplicaes Java
ou em Applets. Alm de servir como um apoio para aplicaes desenvolvidas para streaming de
vdeo e udio, ele prov facilidade para a criao de plug-ins para suportar tipos de mdia que,
atualmente, no so suportados pela API [18].

6.1 Estrutura de Classes

A API JMF constituda por interfaces que definem o comportamento dos objetos e o modo
como eles interagem para a captura, processamento e apresentao de multimdia. Implementaes
dessas interfaces operam dentro do prprio JMF atravs do uso de objetos chamados Managers.
Dessa forma, torna-se fcil integrar novas implementaes de interfaces para us-las em conjunto
com as atualmente implementadas. Quatro tipos de Managers podem ser usados:

Manager: permite a construo de objetos JMF (Players, Processors, DataSources e


DataSinks);
PackageManager: mantm um registro de quais pacotes contm classes JMF;
CaptureDeviceManager: mantm um registro dos dispositivos habilitados para captura;
PlugInManager: mantm um registro dos possveis plug-ins JMF (Multiplexers,
Demultiplexers, Codecs, Effects e Renderers).

A preciso da API JMF mantida na ordem de nanosegundos. Um intervalo de tempo


representado em sua hierarquia de classes como um objeto: Time. Durante a implementao do
trabalho aqui descrito foi desenvolvido o modelo Clock para manter a noo temporal de um stream
de mdia. Atravs dele foram implementadas operaes de sincronizao e controle temporal,
necessrias para a apresentao da mdia. A classe Clock usa um objeto TimeBase para realizar a
cronometragem durante a apresentao da mdia. Um objeto TimeBase prov o tempo corrente.
Essa marcao no pode ser resetada ou zerada, e baseada no relgio do sistema.
A varivel MediaTime representa a posio corrente, no tempo, de uma mdia de streaming.
Inicialmente, a varivel zerada. J a durao de um stream de mdia representado pela classe
Duration. Ela contm o tempo necessrio para que a mdia seja totalmente transmitida. No incio da
transmisso, o MediaTime mapeado no TempoBase e este usado para medir a passagem do
tempo da transmisso. Durante a transmisso, o tempo corrente de mdia ou MediaTime calculado
pela frmula a seguir:

67
MediaTime = TempoInicial + TAXA(TempoBaseAtual TempoBaseInicial)

No final da transmisso, o MediaTime zerado e o TempoBase continua sua contagem.


Caso a transmisso seja reiniciada, o MediaTime remapeado para o TempoBase corrente. Por isso
ele denominado tempo base. Sendo sempre a base para a tomada de tempo. A inter-relao entre
as classes do modelo temporal JMF pode ser visto em maiores detalhes na Figura 41.

Figura 41: Modelo de Eventos JMF

Foi imprescindvel utilizar o modelo de eventos da API JMF. O modelo baseia-se na


manuteno do estado atual do sistema multimdia e permite que programas respondam a condies
de erros como, por exemplo, falta de dados. Quando um objeto JMF precisa atualizar as condies,
ela envia um MediaEvent que nada mais do que uma subclasse de Event utilizada apenas para
eventos de mdia. Para cada objeto que pode enviar eventos de mdia, existe um listener
correspondente. Foi necessrio implementar uma interface listener para cada tipo de evento possvel
e adicionar a mesma a classe do objeto atravs do mtodo addListener. Os objetos que podem
enviar eventos so os objetos Controller (Players ou Processors) e alguns objetos Control. Alm do
objeto RTPSessionManager, que tambm pode enviar eventos deste tipo. O diagrama de classes
para o modelo de eventos especificado pela API JMF est ilustrado na Figura 42.

Figura 42: Diagrama de Classes do Modelo de Eventos JMF

68
Outro modelo definido pela API JMF o de controle. Quase todos os objetos, e alguns plug-
ins, precisam de algum tipo de controle. Dessa forma, devem ser criados objetos Control que
implementam a interface Controls. Para isto, usada a classe Control. Sua estrutura de classes
composta pelas seguintes subclasses:

StreamWriterControl: interface que deve ser implementada para que objetos, como o
DataSink, possam ler dados de um objeto DataSource e escrever em um destino. Atravs
dela, torna-se possvel limitar o tamanho de cada stream criado para transmisso;
SilenceSuppressionControl: prov a retirada de silncios que causam uma sobrecarga
desnecessria no trfego da rede;
PacketSizeControl: proporciona controle sobre o tamanho dos pacotes enviados pela
rede;
FrameGrabbingControl: prov a facilidade para se obter um quadro isolado do stream de
vdeo;
FramePositionControl: usado para o posicionamento preciso dentro de objetos
transmissores;
QualityControl: possibilita o controle sobre a qualidade de transmisso e recepo
multimdia. Muitas vezes, deve-se ajustar a qualidade ao consumo da CPU e a
performance do codec escolhido;
FormatControl: utiliza uma subclasse chamada TrackControl para controle de trilhas.
Existir normalmente uma trilha de udio e outra de vdeo.
BitRateControl: fornece controle sobre a taxa de bits transmitidos. Tambm utilizado
para controlar a taxa de compresso. Sua especificao informa as taxas em bits por
segundo;
BufferControl: fornece controle sobre o buffer utilizado para suavizao da reproduo;
FrameRateControl: ;az com que seja possvel o controle sobre a taxa de transmisso de
quadros.
CachingControl: controle de cach;
FrameProcessingControl: faz o controle de processamento dos quadros atravs de
parmetros que permitem a otimizao do codec;
H261Control: permite controle sobre o codec de vdeo H.261;
H263Control: permite controle sobre o codec de vdeo H.263;
MpegAudioControl: atravs deste podem ser feitas modificaes nos parmetros do
codec de udio MPEG;

69
KeyFrameControl: modificaes podem ser feitas entre os intervalos dos quadros chave;
MonitorControl: possibilita a pr-visualizao do vdeo que est sendo capturado ou
codificado;
PortControl: utiliza mtodos para o controle de sada do dispositivo de captura.

O Java Media Framework utiliza um modelo de dados intrnseco que permite o uso de
objetos chamados DataSource para transmitir contedos de mdia. Esses objetos tem a localizao e
o protocolo utilizado para transmitir o vdeo. Um DataSource definido por um MediaLocator ou
por uma URL. Caso for um MediaLocator, ele pode ser construdo mesmo se o protocolo
especificado pelo DataSource no for suportado. Alm disso, ele utiliza um vetor de bytes para
transmisso. Podem existir diferentes tipos de DataSources como pode ser visto na estrutura de
classes representada na Figura 37. Elas so classificadas em relao ao modo como a transferncia
de dados iniciada.

Figura 43: Tipos de DataSource

O funcionamento JMF atravs de DataSources bastante simples. O cliente inicia a


recepo de dados e controle do fluxo de dados atravs de PullDataSources. A entrada de dados
para o mesmo pode ser feita via web (HTTP) ou via arquivo (FILE). J objetos
PullBufferDataSource fazem o mesmo, mas incluem um buffer para suavizar a transmisso. Da
mesma forma, o servidor inicia a transferncia e o controle do fluxo de dados atravs de um
PushDataSource que pode fazer ou broadcast ou multicast ou VOD dos dados. No caso deste
trabalho, foi usado o modo de comunicao multicast. Caso o servidor queira utilizar um buffer,
deve ser criado o objeto PushBufferDataSource ao invs do objeto PushDataSource.

70
6.2 Funcionamento da API JMF

A API JMF verso 1.0 (Java Media Player API) possibilita desenvolver programas, na
linguagem Java, capazes de reproduzir mdias. A verso 2.0 do JMF estende esse framework para
prover suporte capturao e o armazenamento de dados de mdia, controlar o tipo de
processamento realizado durante o playback, padronizar o processamento de streams de dados de
mdia. A partir dessa verso foi disponibilizada a extenso de plug-ins JMF para otimizar e
possibilitar o uso de tipos de mdia no suportados pelo JMF.
A Figura 37 ilustra o funcionamento abstrato da API JMF. Entre parnteses so descritos os
nomes das classes, correspondentes aos dos dispositivos por elas abstrados. Ali se pode deparar
que a cmera de vdeo capta imagens para transmisso ao vivo.

Figura 37: Abstrao da API JMF

O vdeo fonte pode ser um arquivo salvo previamente em disco ou captado ao vivo. Mas o
seu formato deve ter a possibilidade de ser transformado em JPEG/RTP. Alguns exemplos de
formatos que apresentam essa propriedade so Cinepak, RGB, YUV e JPEG. Outros formatos
podem no funcionar corretamente devido a restries da classe Processor, explicada em maiores
detalhes anteriormente. Outra caracterstica importante a ser considerada a dimenso do vdeo que
deve ser mltipla de 8x8. Um exemplo de dimenso admitida seria 320x240.
Cada formato de vdeo tem caractersticas distintas, sendo que os principais formatos
suportados pela API JMF so os apresentados na Tabela 8, onde tambm esto descritas as suas
respectivas caractersticas.

71
Formato Tipo Qualidade Requisitos do CPU Requisitos de
Largura de Banda
Cinepack AVI, Quicktime Mdia Baixo Alto
MPEG-1 MPEG Alta Alto Alto
H.261 AVI, RTP Baixa Mdio Mdio
H.263 AVI, RTP, Quicktime Mdia Mdio Baixo
JPEG RTP, AVI, Quicktime Alta Alto Alto
Tabela 8: Formatos de vdeo suportados pelo JMF

Normalmente em aplicaes de conferncia de vdeo, os formatos H.261 e H.263 so


utilizados.
Outro formato que deve tambm ser definido o tipo de udio que ser utilizado.
Aplicaes de telefonia, por exemplo, devem utilizar taxas baixas de bits por segundo na
reproduo da fala, e, por isso, normalmente utilizado o formato G.723. Os padres de udio mais
conhecidos e suportados pelo JMF esto descritos na Tabela 9.

Requisitos de
Formato Tipo Qualidade Requisitos do CPU Largura de
Banda
AVI, WAV,
PCM Quicktime Alta Baixo Alto
AVI,
Mu-Law Quicktime, Baixa Baixo Alto
WAV, RTP
AVI,
ADPCM Quicktime, Mdia Mdio Mdio
WAV, RTP
MPEG1 MPEG Alta Alto Alto
GSM WAV, RTP Baixa Baixo Baixo
G.723 WAV, RTP Mdia Mdio Baixo
Tabela 9: Formatos de udio suportados pelo JMF

O servidor de streaming aceita como entrada o local de onde sero fornecidos os dados a
transmitir, indicado atravs de uma URL. Os seguintes passos so necessrios para que a
transmisso acontea sem problemas:

criar um Processor para a URL de entrada;


configurar o Processor;
configurar o stream de sada do Media Locator, baseado na extenso do arquivo de
entrada, determinar o Content Descriptor usando o MimeManager;

72
configurar o Content Descriptor de sada contido no Processor;
Verificar se cada formato de trilha de dados est em um formato suportado;
Obter o DataSource de sada e us-lo em conjunto com o Media Locator de sada para
criar o DataSink;
Iniciar o Processor e o DataSink;
Esperar que o evento EndOfStreamEvent provido pelo DataSink ocorra, indicando o
final do arquivo;
Fechar o Processor e o DataSink.

Para transmitir um stream RTP, conforme ilustrado na Figura 38, deve-se usar um Processor
para produzir um DataSource de dados RTP codificados e construir ou um SessionManager ou
outro DataSink (para controlar a transmisso). Existem duas maneiras de enviar dados RTP:
Usar um Media Locator que tm os parmetros da sesso RTP para construir um
DataSink chamando a funo Manager.createDataSink;
Usar um Session Manager para criar e enviar streams de dados e controle.

Os formatos das trilhas so configurados atravs da obteno de cada trilha atravs de


TrackControl. Chama-se ento a funo setFormat para especificar o formato em questo. Esta
especificao feita atravs da atualizao de uma string.

Figura 38: Transmisso JMF

O Processor tenta carregar o plug-in que suporta o formato escolhido. Caso o formato seja
desconhecido pela API JMF a exceo UnSupportedFormatException ser disparada. O formato de
sada especificado atravs do mtodo setOutputContentDescriptor. Como neste trabalho no foi
necessrio nenhum tipo de multiplexao, j que a aplicao em foco trata apenas uma fonte de
dados (servidor de streaming), o content descriptor de sada ser ContentDescriptor.RAW. Cada

73
trilha (vdeo e udio) transmitida em sesses RTP distintas. Ou seja, criada uma sesso para
transmitir os dados de vdeo e outra para transmitir os dados de udio.
O tempo de espera de um pacote ou intervalo de empatamento o tempo necessrio ao
pacote percorrer a rede e chegar ao destino. Ele determina o mnimo intervalo de tempo fim-a-fim.
Este valor deve estar no intervalo de 0 a 200 ms para dados de udio que sero transmitidos. Essa
restrio permite que o buffer do cliente possa ser redimensionado. Cada codec tem um valor
especfico para o delay respectivo. J para streams de vdeo, um frame de vdeo transmitido em
mltiplos pacotes RTP. O tamanho de cada pacote enviado limitado pelo MTU.
A mdia que ser enviada pela rede via socket para um grupo multicast pode ser manipulada
antes do envio, ou antes de ser apresentada ao usurio. Caso seja um fluxo multiplexado, as trilhas
sero extradas individualmente por um demultiplexador. Se elas estiverem comprimidas sero
decodificadas por um codec e transformadas no formato RAW (prprio para apresentao). Filtros
tambm podem ser aplicados s trilhas decodificadas e transform-las em tipos diferentes,
dependendo das necessidades da aplicao, ou devido a restries da rede. O prximo passo a
entrega das trilhas para o dispositivo de sada.
Durante a recepo de streams de mdia, conforme ilustrado na Figura 39, o Session
Manager poder criar um DataSource para os pacotes que so providos pela rede, que por sua vez
podero criar ou um Processor ou um Player ou um DataSink. Caso o objetivo seja armazenar os
dados de mdia recebidos em um arquivo, deve-se usar ou um Processor ou um DataSink. Se a
escolha for um Processor, dever ser criado outro DataSource que criar o DataSink. Este salvar os
dados em um arquivo.Por outro lado, se o objetivo for reproduzir os dados recebidos pela rede,
deve-se criar um Player.

Figura 39: Recepo JMF

74
Os filtros podem ser aplicados em um vdeo para produzir alguns efeitos especiais. Tanto
pode ser aplicado antes da mdia ser processada pelo codec ou depois. Normalmente so aplicadas a
dados RAW (descomprimidos).

A relao hierrquica entre os principais componentes JMF e como eles interagem na


arquitetura API encontra-se ilustrada na Figura 40.

Figura 40: Arquitetura JMF

As aplicaes Java e os Applets so desenvolvidas sobre a API JMF da mesma maneira


como se usa uma biblioteca em um programa. Mas, em se tratando de uma API, a JMF contm uma
srie de bibliotecas. Da mesma forma, a API JMF faz uso de Plug-ins JMF. Na ltima camada,
esto descritos os tipos de dispositivos que podem ser aplicados e que modificam e processam a
mdia.

75
7 TESTES E RESULTADOS

A Figura 44 mostra uma cena da sada de vdeo que foi assistida atravs da execuo do
Mdulo Receptor, durante testes realizados dia 21/12/07, s 15h, no Ncleo de Computao
Cientfica (NCC). Os testes levaram trinta minutos e vinte e dois segundos, durao do vdeo cedido
pela FURGTV. Tratava-se de um programa, chamado MUSIURG 19 dia do rock 1, que tinha
como foco principal a msica regional e da cidade.

Figura 44: Player FURGTV

Durante a realizao do experimento foi utilizado um Notebook Dell Latitude D520 (Intel
Core 2 Duo, 1.66GHz com 1014 MB de ram) executando o Mdulo Transmissor no Windows Vista
Home Basic. Ou seja, representando o Servidor de Streaming.
Alm disso, foram utilizados trs PCs executando o Mdulo Receptor, na condio de
telespectadores da FURGTV, utilizando o Ubuntu 7.10 como Sistema Operacional.
O tamanho padro do vdeo foi de 320 pixels de largura e 240 pixels de altura.
O valor de jitter (RTPtime) foi escolhido como 77.
Foi utilizado o software Wireshark 0.99.6a (www.wireshark.org) para avaliar os pacotes que
transitaram pela rede atravs do filtro UDP para pacotes enviados para o endereo multicast
230.0.0.1.
Atravs da anlise estatstica mostrada na Figura 45 pode-se perceber que a maior
porcentagem de pacotes enviados para o endereo em questo tinha o tamanho entre 640 e 1279
bytes, totalizando 93,33% do total de pacotes criados e enviados. Tambm foi observado que
existiram vrias faixas de tamanho de pacotes que no foram utilizados, ou seja, no foram criados
pacotes desses tamanhos durante a transmisso.

76
Figura 45: Tamanho dos pacotes

Outro dado importante a ser relatado que foi utilizado o tipo RAW para transmisso, ou
seja, o vdeo foi decodificado para esse padro. Alm disso, foi utilizado o tipo jpeg/rtp para
codificao. A taxa mdia de bits por segundo foi de 780.58 kbps, enquanto a taxa mdia de
quadros por segundo foi de 16.6 fps.
Foram capturados vrios grficos indicando quantos pacotes por segundo eram recebidos
pelos receptores. A Figura 46 mostra a variao dos pacotes para o primeiro receptor, decorridos
950 segundos aps a sua execuo.

Figura 46: Pacotes Recebidos pelo Primeiro Receptor

Como pode ser visto na figura, o Mdulo receptor estabilizou a transmisso aps o tempo de
950 segundos. Com isso, houve uma suavizao na tramitao dos pacotes e um melhor fluxo de
transmisso por parte do Servidor de Streaming. Para a leitura do grfico, cabe ressaltar que foi
utilizado 1 segundo por tick e foram utilizados 5 pixels por tick (eixo x do grfico). J o eixo y
indica a quantidade de pacotes por tick.

77
No teste, os dois primeiros receptores foram iniciados quase que simultaneamente com o
incio da transmisso. O terceiro receptor foi iniciado e o grfico mostrado na Figura 47 apresenta o
comportamento da recepo dos pacotes nele ocorrido.

Figura 47: Pacotes Recebidos pelo Terceiro Receptor

Em relao ao terceiro Receptor, houve momentos de extrema alternncia. Muitas vezes a


suavizao dos pacotes era regular e constante como do segundo 250 at o 300, devido a pouca
interao da prpria aplicao no envio e recebimento de pacotes de controle (protocolo RTCP). J
no perodo entre 300 e 350 segundos, houve vrias mudanas bruscas entre a quantidade de pacotes
recebidos pois haviam mais trocas de dados inerentes a transmisso multimdia. Outro fato
relevante foi no ter ocorrido taxas de recepo maiores do que 250 pacotes em nenhum dos
Receptores.

78
8 CONCLUSO

Esta monografia descreveu o trabalho de pesquisa realizado sobre o tpico TV na Internet.


Puderam ser verificadas as facilidades disponibilizadas pelo uso de transmisses multicast para na
comunicao entre grupos de hosts, especialmente para a troca de dados, de udio e vdeo.
Os trabalhos foram complementados com a construo de um framework para diponibilizar
a FURGTV na Internet. Foram implementados trs mdulos em Java: um Servidor de Streaming,
um Mdulo Receptor e um Mdulo de Configurao. O Mdulo Receptor reproduz um arquivo
multimdia em questo em tempo-real. Para que isso tenha sido possvel, foi utilizado o Protocolo
RTP por motivo de eficincia. Alm disso, foi utilizado a API JMF que apresenta muitas facilidades
para a criao de aplicaes multimdia.
As aplicaes multimdia disputam os recursos de rede com outras aplicaes que esto
sendo executadas simultaneamente. Quando se tratam de redes por datagramas, a partir de uma
certa carga, passam a ocorrer atrasos e perdas de pacotes. Uma soluo para essa situao o
gerenciamento da qualidade de servio. Ou seja, devem-se utilizar novos mecanismos de
gerenciamento que permitam a alocao adequada dos recursos. Muitas vezes, so adotados
algoritmos de escalonamento de processos em tempo real, como rate-monotonic (RM), para que
seja utilizado ao mximo a capacidade do processador, durante o processamento dos fluxos.
Segundo [21], a largura de banda necessria para transmitir um fluxo de vdeo em tempo real de
120 Mbps. Caso o vdeo seja compactado, a banda necessria passa a ser de 1,5 Mbps.
O trabalho focalizou uma aplicao real, envolvendo streaming de udio e vdeo:
disponibilizao da FURGTV na Internet. Por isso, alguns fatores ligados segurana precisaram
ser abordados como privacidade, autentificao, DOS, proteo quanto a replay, confiabilidade,
entre outros. As sesses devem ser robustas e consistentes, para que no sejam hackeada com
facilidade para atividades maliciosas. Para isso, provou-se importante o uso do protocolo RTP
devido a suas restries de segurana. Outra faceta importante nesse sentido o protocolo de
controle RTCP que fornece vrias informaes sobre a transmisso e sobre seus participantes.
Apesar de todos esses cuidados conseguiu-se estabilidade e taxas de transmisso razoveis. Atravs
dos testes realizados, pde-se verificar uma aplicabilidade bastante razovel, mantendo-se a taxa de
transmisso entre 20 e 30 fps.

79
9 REFERNCIAS BIBLIOGRFICAS

[1] FINZSCH, P., ROESLER, V. "Anlise do mecanismo de pares de pacotes para inferncia de
banda mxima em redes de computadores". UNISINOS - Universidade do Vale do Rio dos Sinos,
Centro de Cincias Exatas e Tecnolgicas, junho de 2003.

[2] KARSTEN, M., VENTER, R."MBone: The Multicasting Backbone". HSN-Team, Department
of Computer Science, University of Pretoria, Pretoria, 2002, South Africa.

[3] VENAAS S., CHOWN T. "Source Specific Multicast (SSM) with IPv6". School of Electronics
and Computer Science, University of Southampton, United Kingdom.

[4] ROESLER, V., GIULIANO G., VALDENI J. "ALM: Adaptive layering Multicast". UNISINOS
-Universidade do Vale do Rio dos Sinos, Centro de Cincias Exatas e Tecnolgicas.

[5] NOGUCHI T., YAMAMOTO M. "Construction of a Robust Multicast Tree for Application-
Level Multicast". EICE TRANS. COMMUN., VOL.E88B, NO.12 DECEMBER 2005.

[6] FRANCIS P. "Yoid: Extending the Internet Multicast Architecture". Em: www.aciri.org. 2 de
Abril, 2000.

[7] BANEJEE S., BHATTACHARJEE B., KOMMAREDDY C. "Scalable Application Layer


Multicast". Department of Computer Science,University of Maryland, USA.

[8] SHULZIRINNE, CASNER, FREDERICK, JACOBSON. "RTP: A Transport Protocol for Real-
Time Applications". Columbia U. Internet Engeneering Task Force, maio de 2002.

[9] http://www.protocols.com/pbook/h323.htm

[10] TANENBAUM A. (2003). Redes de Computadores. Campus, Edio 4.

[11] http://www.planet-lab.org

[12] http://www.itu.org

[13] Protocol Independent Multicast-Sparse Mode (RFC 2362).


Em: http://www.ietf.org/rfc/rfc2362.txt

[14] Internet Group Management Protocol (RFC 2236). Em: http://www.ietf.org/rfc/rfc2236.txt

[15] RTP: A Transport Protocol for Real-Time Applications (RFC 3550). Em:
http://www.ietf.org/rfc/rfc3550.txt

[16] IANA: rgo responsvel por estabelecer numeraes padro para a Internet. Em:
http://www.iana.org

[17] Resource ReSerVation Protocol (RFC 2205 - RSVP). Em: http://www.ietf.org/rfc/rfc2205.txt

[18] Java Media Framework (JMF). Em: http://java.sun.com/products/java-media/jmf/

80
[19] F. Yergeau. "UTF-8, a Transformation Format of ISO 10646," Internet Engineering Task
Force, RFC 2279, January 1998.

[20] D. Crocker. "Standard for the Format of ARPA Internet Text Messages," Network Working
Group, RFC 822, August 1982.

[21] Coulouris G., Dolimore J., Kindberg T. "SISTEMAS DISTRIBUDOS CONCEITOS E


PROJETOS". Quarta Edio. Bookman Editora, 2007.

[22] IP Multicast Technology Overview


http://www.cisco.com/uniivercd/cc/td/doc/cisint5wk/intsolns/mcst_sol/mcst_ovr.htm

[23] REYNOLDS, J. RFC 1700 Internet Multicast Addresses. 2002.

81
ANEXOS

ANEXO 1: MDULO DE CONFIGURAO


Main.java
/** Pacote Principal */
package configuratv;

/** Programa Principal */


public class Main
{
public Main() {}

/** Programa Principal */


public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Parametros().setVisible(true);
}
});
}
}

Parametros.java
/** Pacote Principal */
package configuratv;

/** Pacote Grfico awt */


import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Image;
import java.awt.Label;
import java.awt.Panel;
import java.awt.Toolkit;

/** Pacote de E/S */


import java.io.BufferedWriter;
import java.io.FileWriter;

/** Pacote Grfico swing */


import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JTextPane;

/** configura os parmetros da conexo via socket entre o transmissor e os receptores*/


public class Parametros extends javax.swing.JFrame
{
public Parametros() //configura Aplicao no Inicio
{
initComponents();

Toolkit tk = Toolkit.getDefaultToolkit();
img = tk.getImage("furg.gif");
this.setIconImage(img);

/** configura sub-menu */


jMenuItem1.setText("Salvar configuraes");
jMenuItem3.setText("Sobre");
jMenuItem2.setText("Sair");

82
/** Insere textos de ajuda */
jLabel1.setToolTipText("Uma aplicao que necessita da comunicao via Internet deve utilizar os protocolos de
transporte como pontos de acesso (udp ou tcp).");
jLabel2.setToolTipText("Uma porta um valor inteiro positivo que representa a ligao entre a camada de
aplicao (usurio) e a camada de transporte (comunicao)");
jLabel3.setToolTipText("O endereamento Multicast permite enviar pacotes IP para um determinado grupo de
usurios. De 224.0.2.0 at 238.255.255.255 (os valores entre pontos vo de 0 at 255).");
jLabel4.setToolTipText("Time To Live = controla o tempo de vida de um datagrama, evitando assim que este
fique \n" + "em um loop eterno devido a algum erro de roteamento.");

/** inicializa variaveis */


protocolo = jTextField1.getText();
porta = jTextField2.getText();
ip = jTextField3.getText();
ttl = jTextField4.getText();

try
{
/** abre arquivo parametros.txt */
arq = new BufferedWriter(new FileWriter("C:/parametros.txt"));
arq.write(protocolo+" ");
arq.write(porta+" ");
arq.write(ip+" ");
arq.write(ttl);
arq.close();
}
catch(Exception e){e.printStackTrace();}
}

private void initComponents()


{
jPanel1 = new javax.swing.JPanel();
jLabel4 = new javax.swing.JLabel();
jLabel1 = new javax.swing.JLabel();
jLabel2 = new javax.swing.JLabel();
jLabel3 = new javax.swing.JLabel();
jTextField3 = new javax.swing.JTextField();
jTextField2 = new javax.swing.JTextField();
jTextField1 = new javax.swing.JTextField();
jTextField4 = new javax.swing.JTextField();
jButton2 = new javax.swing.JButton();
jButton1 = new javax.swing.JButton();
jMenuBar1 = new javax.swing.JMenuBar();
jMenu1 = new javax.swing.JMenu();
jMenuItem1 = new javax.swing.JMenuItem();
jMenuItem3 = new javax.swing.JMenuItem();
jMenuItem2 = new javax.swing.JMenuItem();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Par\u00e2metros - FURGTV");
setBackground(new java.awt.Color(82, 109, 166));
setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
setForeground(java.awt.Color.lightGray);
setResizable(false);
addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosed(java.awt.event.WindowEvent evt) {
formWindowClosed(evt);
}
});

jPanel1.setBackground(new java.awt.Color(0, 51, 102));


jPanel1.setAutoscrolls(true);

83
jLabel4.setForeground(new java.awt.Color(255, 255, 255));
jLabel4.setText("TTL");

jLabel1.setForeground(new java.awt.Color(255, 255, 255));


jLabel1.setText("Protocolo");

jLabel2.setForeground(new java.awt.Color(255, 255, 255));


jLabel2.setText("Porta");

jLabel3.setForeground(new java.awt.Color(255, 255, 255));


jLabel3.setText("IP Multicast");

jTextField3.setText("232.0.0.1");
jTextField3.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jTextField3ActionPerformed(evt);
}
});

jTextField2.setText("5000");
jTextField2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jTextField2ActionPerformed(evt);
}
});

jTextField1.setEditable(false);
jTextField1.setText("udp");
jTextField1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jTextField1ActionPerformed(evt);
}
});

jTextField4.setText("1");
jTextField4.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jTextField4ActionPerformed(evt);
}
});

jButton2.setText("Fechar");
jButton2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton2ActionPerformed(evt);
}
});

jButton1.setText("Salvar");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});

org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1);


jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jPanel1Layout.createSequentialGroup()
.add(18, 18, 18)
.add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING)
.add(jLabel4)

84
.add(jLabel2)
.add(jLabel3)
.add(jLabel1)
.add(jButton2))
.add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jPanel1Layout.createSequentialGroup()
.add(17, 17, 17)
.add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jTextField2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 54, Short.MAX_VALUE)
.add(jTextField1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 54, Short.MAX_VALUE)
.add(jTextField4, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 54, Short.MAX_VALUE)
.add(jTextField3, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
.add(52, 52, 52))
.add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel1Layout.createSequentialGroup()
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(jButton1)
.add(29, 29, 29))))
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel1Layout.createSequentialGroup()
.addContainerGap()
.add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(jLabel1)
.add(jTextField1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
.add(16, 16, 16)
.add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(jLabel2)
.add(jTextField2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
.add(15, 15, 15)
.add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(jLabel3)
.add(jTextField3, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
.add(14, 14, 14)
.add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(jLabel4)
.add(jTextField4, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
.add(26, 26, 26)
.add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(jButton2)
.add(jButton1))
.addContainerGap())
);

jMenuBar1.setBackground(new java.awt.Color(51, 51, 51));


jMenu1.setBackground(new java.awt.Color(51, 51, 51));
jMenu1.setForeground(new java.awt.Color(204, 204, 204));
jMenu1.setIcon(new javax.swing.ImageIcon(""));
jMenu1.setText("Menu");
jMenu1.setDisabledIcon(new
javax.swing.ImageIcon("C:\\Users\\rafael\\Desktop\\ProjetoFURGTV\\FURGTV\\furg.gif"));
jMenu1.setDisabledSelectedIcon(new
javax.swing.ImageIcon("C:\\Users\\rafael\\Desktop\\ProjetoFURGTV\\FURGTV\\furg.gif"));
jMenuItem1.setText("Item");
jMenuItem1.setBorder(javax.swing.BorderFactory.createEtchedBorder());
jMenuItem1.setContentAreaFilled(false);
jMenuItem1.setRolloverEnabled(true);
jMenuItem1.addActionListener(new java.awt.event.ActionListener() {

85
public void actionPerformed(java.awt.event.ActionEvent evt) {
jMenuItem1ActionPerformed(evt);
}
});

jMenu1.add(jMenuItem1);
jMenuItem1.getAccessibleContext().setAccessibleParent(jMenu1);
jMenuItem3.setText("Item");
jMenuItem3.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jMenuItem3ActionPerformed(evt);
}
});

jMenu1.add(jMenuItem3);
jMenuItem2.setText("Item");
jMenuItem2.setBorder(javax.swing.BorderFactory.createEtchedBorder());
jMenuItem2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jMenuItem2ActionPerformed(evt);
}
});

jMenuItem2.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
jMenuItem2MouseClicked(evt);
}
});

jMenu1.add(jMenuItem2);
jMenuBar1.add(jMenu1);
setJMenuBar(jMenuBar1);
org.jdesktop.layout.GroupLayout layout = new
org.jdesktop.layout.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jPanel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
);
layout.setVerticalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel1,
org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 200, Short.MAX_VALUE)
);
pack();
}

private void jMenuItem3ActionPerformed(java.awt.event.ActionEvent evt)


{
/** Cria Frame Sobre */
status = new JTextPane();
status.setEditable(false);
status.setBackground(Color.BLACK);
status.setText("INSTRUO: Preencha os valores correspondentes aos parmetros de conexo. \n\n"+ "
DESENVOLVEDOR: Rafael Vieira Coelho (rafaelvc2@gmail.com). \n\n" + " OBSERVAO: Atravs
deste software feita a padronizao entre o Servidor \n" + " de Streaming e o Receptor da FURG TV via
Web.");

status.setForeground(Color.WHITE);
Font fo = new Font ("Arial", Font.BOLD, 12);
status.setFont(fo);

86
painel = new Panel();
f = new JFrame();
painel.add(status);
painel.setBackground(Color.BLACK);
f.setResizable(false);
f.setSize(480,140);
f.add(painel);
f.setTitle("Sobre");
f.setEnabled(true);
f.show(true);
f.setDefaultCloseOperation(f.HIDE_ON_CLOSE);
jPanel1.setEnabled(false);
f.setIconImage(img);
}

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)


{
/** salva novos valores nas variaveis */
protocolo = jTextField1.getText();
porta = jTextField2.getText();
ip = jTextField3.getText();
ttl = jTextField4.getText();

try
{
/** abre arquivo parametros.txt */
arq = new BufferedWriter(new FileWriter("parametros.txt"));

/** salva novos parametros */


arq.write(protocolo+" ");
arq.write(porta+" ");
arq.write(ip+" ");
arq.write(ttl);

/** fecha arquivo */


arq.close();
}
catch(Exception e){e.printStackTrace();}
}//GEN-LAST:event_jButton1ActionPerformed

private void jTextField4ActionPerformed(java.awt.event.ActionEvent evt) {}


private void jTextField3ActionPerformed(java.awt.event.ActionEvent evt) {}
private void jTextField2ActionPerformed(java.awt.event.ActionEvent evt) {}
private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) {}
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {System.exit(2);}
private void jMenuItem2ActionPerformed(java.awt.event.ActionEvent evt) {System.exit(1);}
private void jMenuItem2MouseClicked(java.awt.event.MouseEvent evt) {}
private void formWindowClosed(java.awt.event.WindowEvent evt) {System.exit(0);}

private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt)


{
/** salva novos valores nas variaveis */
protocolo = jTextField1.getText();
porta = jTextField2.getText();
ip = jTextField3.getText();
ttl = jTextField4.getText();

try
{
/** abre arquivo parametros.txt */
arq = new BufferedWriter(new FileWriter("C:/parametros.txt"));

/** salva novos parametros */

87
arq.write(protocolo+" ");
arq.write(porta+" ");
arq.write(ip+" ");
arq.write(ttl);

/** fecha arquivo */


arq.close();
}
catch(Exception e){e.printStackTrace();}
}//GEN-LAST:event_jMenuItem1ActionPerformed

// Declarao de variveis
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JLabel jLabel4;
private javax.swing.JMenu jMenu1;
private javax.swing.JMenuBar jMenuBar1;
private javax.swing.JMenuItem jMenuItem1;
private javax.swing.JMenuItem jMenuItem2;
private javax.swing.JMenuItem jMenuItem3;
private javax.swing.JPanel jPanel1;
private javax.swing.JTextField jTextField1;
private javax.swing.JTextField jTextField2;
private javax.swing.JTextField jTextField3;
private javax.swing.JTextField jTextField4;
private String protocolo;
private String porta;
private String ip;
private String ttl;
private BufferedWriter arq;
private javax.swing.JTextPane status;
private Panel painel;
private JFrame f;
private Image img;
}

ANEXO 2: MDULO TRANSMISSOR


Main.java
/** Pacote principal */
package transmissor_furgtv;

/** Bibliotecas auxiliares */


import javax.swing.JFrame;

/** Classe Principal */


public class Main
{
/** Construtor Abstrato */
public Main(){}

/** Cria Instancia do Programa Principal */


public static void main(String[] args)
{
Janela ProgramaPrincipal = new Janela();
ProgramaPrincipal.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

Janela.java

88
/** PACOTE PRINCIPAL*/
package transmissor_furgtv;

/** BIBLIOTECAS */

/** Bibliotecas auxiliares */


import javax.media.Format;

/** Pacote lang */


import java.lang.*;

/** Pacote IO */
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.File;
import java.io.FileReader;

/** Pacote awt */


import java.awt.*;
import java.awt.Dimension;
import java.awt.Event.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.FlowLayout;
import java.awt.BorderLayout;

/** Pacote net */


import java.net.URISyntaxException;
import java.net.URL;
import java.net.MalformedURLException;
import javax.media.MediaLocator;

/** Pacote swing */


import javax.swing.JFrame; /** fornece recursos bsicos de janela */
import javax.swing.JLabel; /** exibe texto e imagens */
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.SwingConstants; /** constantes comuns utilizadas com Swing */
import javax.swing.Icon; /** interface utilizada para manipular imagens */
import javax.swing.ImageIcon; /** carrega imagens */
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JFileChooser;

/** Interface Grfica */


public class Janela extends JFrame implements ActionListener
{

JFrame f = new JFrame();

/** cria um JTabbedPane = permite painis paralelos*/


JTabbedPane tabs = new JTabbedPane(JTabbedPane.TOP, JTabbedPane.SCROLL_TAB_LAYOUT);

/** cria Botes */


JButton botao2 = new JButton(" Sair ");
JButton botao1 = new JButton(" Adicionar Video ");

/** cria Painis */

89
JPanel panel_sobre = new JPanel();
JPanel panel = new JPanel();
JPanel panel_texto = new JPanel();
JPanel panel_menu = new JPanel();
JPanel panel_equipe = new JPanel();

/** cria atributo cor */


Color cor = Color.lightGray;

/** cria icone */


Toolkit tk = Toolkit.getDefaultToolkit();
Image icone = tk.getImage("furg.gif");

/** cria imagens */


Icon img = new ImageIcon("tv.jpg");
Icon img2 = new ImageIcon("furg.gif");

/** cria Label com as imagens */


JLabel label_imagem = new JLabel(img);
JLabel label_imagem_furg = new JLabel(img2);

/** Cria Texto */


JTextPane texto = new JTextPane();

/** Cria Texto_sobre */


JTextPane texto_sobre = new JTextPane();

/** Cria Texto_equipe */


JTextPane texto_equipe = new JTextPane();

/** Arquivo com parmetros da conexo */


private BufferedReader arq;

private String horas, min, sec;

/****************************** Trata Eventos ********************************/


/** Botao clicado! */
public void actionPerformed(ActionEvent event)
{
Object source = event.getSource();

if (source == botao2) /** Botao "Sair" pressionado */


{
System.exit(0);
}
else
{
//*************** Botao "Adicionar Video" pressionado *******************/

/** desabilita boto "Adicionar Video" */


botao1.setEnabled(false);

/** desabilita abas */


tabs.setEnabled(false);

/** desabilita imagem e texto */


label_imagem_furg.setEnabled(false);
texto.setEnabled(false);

/** cria um filechooser para procurar o arquivo que ser enviado */


JFileChooser fileChooser = new JFileChooser();
int result = fileChooser.showOpenDialog( null );

90
if ( result == JFileChooser.APPROVE_OPTION ) /** se usuario escolheu um arquivo */
{
URL mediaURL = null;
Format fmt = null;

try
{
/** obtm o arquivo como URL */
mediaURL = fileChooser.getSelectedFile().toURL();
final MediaLocator m = new MediaLocator(mediaURL);

/** abre o arquivo parametros.txt */


arq = new BufferedReader(new FileReader("C:/parametros.txt"));

char[] linha = new char[100];


char[] protocolo = new char[15];
char[] porta = new char[15];
char[] ip = new char[15];
char[] ttl = new char[15];

/** le parametros do arquivo parametros.txt */


arq.read(linha);

int x = 0, y = 0;

y = 0;
while ((linha[x] != ' ')&&(y!=15))
{
protocolo[y] = linha[x];
x++;
y++;
}
x++;
y = 0;
while ((linha[x] != ' ')&&(y!=15))
{
porta[y] = linha[x];
x++;
y++;
}
x++;
y = 0;
while ((linha[x] != ' ')&&(y!=15))
{
ip[y] = linha[x];
x++;
y++;
}
x++;
y = 0;
while ((linha[x] != ' ')&&(y!=15))
{
ttl[y] = linha[x];
x++;
y++;
}

/** fecha arquivo */


arq.close();

final String IP = String.valueOf(ip).trim();


final String TTL = String.valueOf(ttl).trim();

91
final String PORTA = String.valueOf(porta).trim();

f.setVisible(false);

/** cria objeto tempo com os parametros lidos */


java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new tempo(m, IP, PORTA, TTL).setVisible(true);
}
});

}
catch (IOException e) {System.err.println( "Erro: Arquivo no encontrado!" ); e.printStackTrace();}

if (mediaURL != null) /** exibe somente se houver um URL valido */


{
byte[] b = new byte[256];

/** Converte a URL em um objeto file */


File arquivo = new File(mediaURL.getFile());
if (arquivo.exists())
{
arquivo.deleteOnExit();
System.out.println("Tamanho do Arquivo: " + arquivo.getAbsoluteFile().length() + " bytes.");
}
else
{System.out.println("ERRO: Arquivo invlido!");}
}
}

/** habilita boto "Adicionar Video" */


botao1.setEnabled(true);
/** habilita abas */
tabs.setEnabled(true);
/** habilita imagem e texto */
label_imagem_furg.setEnabled(true);
texto.setEnabled(true);
}
}

/** Janela Principal */


public Janela()
{
/** Adiciona Icone */
f.setIconImage(icone);

/** Cria layouts */


BorderLayout layout = new BorderLayout(3,3);
BorderLayout layout2 = new BorderLayout(2,2);
BorderLayout layout3 = new BorderLayout(2,2);
BorderLayout layout1 = new BorderLayout(2,2);

/** Adiciona Layouts */


panel.setLayout(layout);
panel_sobre.setLayout(layout2);
panel_menu.setLayout(layout3);
panel_equipe.setLayout(layout1);

/** Formata Texto */


texto.setText("\n A Fundao Universidade Federal do Rio Grande, atravs " +
"\n da Pr-Reitoria de Assuntos Comunitrios e Estudantis " +
"\n apresenta a sua TV Universitria em nova fase."
);

92
texto.setFont(new Font("sansserif", Font.BOLD, 17));
texto.setEditable(false);
cor = Color.black;
texto.setBackground(cor);
cor = Color.white;
texto.setForeground(cor);

/** Formata Texto_sobre */


texto_sobre.setText(" \nA FURG TV oferece nove programas de TV distribudos em sua grade de programao
semanal, com "+
" \numa hora e meia indita por dia e mais trs horas e meia de horrios alternativos de seus
programas. "
+" \nTais programas tm por objetivo, alm da divulgao institucional, a disseminao dos
conhecimentos "
+" \nproduzidos na Instituio, a discusso democrtica de temas polmicos e a promoo da
educao e da cultura.");
texto_sobre.setEditable(false);
texto_sobre.setFont(new Font("sansserif", Font.BOLD, 12));

/** Formata Texto_sobre */


texto_equipe.setText("DADOS PESSOAIS"
+"\nNome: Rafael vieira Coelho "
+"\nEmail: rafaelvc2@gmail.com "
+"\nTelefone: (53)91158533 "
+"\n\nFORMAO ACADMICA "
+"\nEnsino Fundamental 1991 - 1998: Instituto de Educao Juvenal Miller. Rio Grande-RS. "
+"\nEnsino Mdio 1999 - 2001: CTI - Colgio Tcnico Industrial Prof. Mario Alquati, Rio Grande-
RS. "
+"\n Curso: Informtica "
+"\nGraduao 2003 - 2007: Fundao Universidade Federal do Rio Grande (FURG). Rio Grande -
RS. "
+"\n Curso: Engenharia de Computao. ");

texto_equipe.setFont(new Font("sansserif", Font.BOLD, 12));


texto_equipe.setEditable(false);
cor = Color.black;
texto_equipe.setBackground(cor);
cor = Color.white;
texto_equipe.setForeground(cor);
texto_equipe.setToolTipText("http://www.ncc.furg.br/~rcoelho/");

/** Adiciona Componentes aos Paineis */

/** painel menu */


label_imagem_furg.setToolTipText("www.furg.br");
cor = Color.white;
panel_menu.setBackground(cor);
panel_menu.add(label_imagem_furg, BorderLayout.CENTER);
panel_menu.add(botao1, BorderLayout.SOUTH);

/** painel principal */


panel.add(botao2, BorderLayout.SOUTH);
panel.add(panel_menu,BorderLayout.WEST);
panel.add(texto,BorderLayout.CENTER);

/** painel sobre */


label_imagem.setToolTipText("www.furgtv.furg.br");
panel_sobre.add(label_imagem,BorderLayout.NORTH);
panel_sobre.add(texto_sobre,BorderLayout.CENTER);

/** painel equipe */


panel_equipe.add(texto_equipe,BorderLayout.CENTER);

93
/** Textos de Ajuda dos Botes */
botao1.setToolTipText("Clique neste boto para inserir um novo vdeo de streaming");
botao2.setToolTipText("Clique neste boto para fechar o programa");

/** Adiciona Listeners nos Botes */


botao2.addActionListener(this);
botao1.addActionListener(this);

/** coloca cada container no painel com guias */


tabs.addTab( "Servidor de Videos", panel);
tabs.addTab( "Sobre", panel_sobre);
tabs.addTab( "Equipe", panel_equipe);

/** cores de background */


tabs.setBackground(cor);
panel.setBackground(cor);
cor = Color.white;
panel_sobre.setBackground(cor);

/** coloca o painel com guias no quadro */


f.add(tabs);

f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
f.setSize(700,250); /** configura o tamanho do frame */
f.setVisible( true ); /** exibe o frame */
f.setResizable(false);
f.setTitle("FURG TV na Internet");
}
}

Transmissor.java
/** PACOTE PRINCIPAL*/
package transmissor_furgtv;

/** BIBLIOTECAS */

/** Grafica awt */


import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.ImageObserver;
import java.awt.image.ImageProducer;
import javax.swing.JButton;
import javax.swing.JComponent;

/** Grafica swing */


import javax.swing.JFrame;
import javax.swing.JLabel;

/** E/S */
import java.io.*;

/** Midia (JMF) */


import javax.media.*;
import javax.media.protocol.*;
import javax.media.protocol.DataSource;
import javax.media.format.*;
import javax.media.control.TrackControl;
import javax.media.control.QualityControl;

/** Rede */
import java.net.InetAddress;

94
/** RTP */
import javax.media.rtp.*;
import javax.media.rtp.rtcp.*;

/** CLASSE TRANSMISSOR RTP */


public class Transmissor extends JFrame
{
private Panel painel;
private JFrame f;

/** MediaLocator => ENTRADA DE ARQUIVO */


private MediaLocator locator;

/** Endereo IP Multicast */


private String IP;

/** PORTA */
private int porta;

/** TTL */
private int t;

/** PROCESSOR */
private Processor processor = null;

/** VETOR DE MANAGERS RTP */


private RTPManager rtpMgrs[];

/** DATASOURCE = DADOS DE SAIDA */


private DataSource dataOutput = null;

private Label status;

private java.awt.Label status2;

/** CONSTRUTOR DO TRANSMISSOR (localizador de video, IP, porta, ttl,formato) */


public Transmissor(String horas, String minutos, String segundos, MediaLocator locator, String ip, String pb, String
TTL,Format format)
{
Toolkit tk = Toolkit.getDefaultToolkit();
Image icone = tk.getImage("furg.gif");

status = new Label();


status.setText("FURG TV - Servidor de Streaming");
status2 = new Label();
status2.setText("STATUS: sintonizando...");
status.setForeground(Color.WHITE);
status.setBackground(Color.DARK_GRAY);
status2.setForeground(Color.LIGHT_GRAY);

painel = new Panel();


painel.add(status);
painel.add(status2);
painel.setBackground(Color.DARK_GRAY);
painel.setForeground(Color.WHITE);

f = new JFrame();
f.setBackground(Color.DARK_GRAY);
f.setForeground(Color.WHITE);

//f.setIconImage(img);
f.setSize(300,100);

95
f.add(painel);
f.setTitle("Servidor de Streaming - FURG TV");
f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
f.setIconImage(icone);
f.show();

this.locator = locator;
this.IP = ip;
this.t = Integer.valueOf(TTL).intValue();

this.porta = Integer.valueOf(pb).intValue();

/** Inicia a transmisso*/


String result = start();

/** result ser no-nulo se aconteceu um erro.*/


/** result ser uma string caso tenha ocorrido um erro.*/
if (result != null)
{
System.err.println(result);
System.exit(0);
}
System.out.println("============ INCIO DE TRANSMISSO ==============");

try
{
Float h = new Float(String.valueOf(horas));
Float min = new Float(String.valueOf(minutos));
Float sec = new Float(String.valueOf(segundos));

min = min + h*60 + sec/60;

System.out.println("Durao do Vdeo: "+ min + " minutos (");

min = 60000*min; //transformando minutos em milisegundos

Integer t = new Integer(min.intValue()); //passando float para inteiro

int tempo = t.intValue();

System.out.print(tempo + "milisegundos)");
Thread.currentThread().sleep(tempo);
}
catch (InterruptedException ie) {ie.printStackTrace();}

//DADOS ESTATISTICOS
System.out.println("Bytes Recebidos - " + rtpMgrs[0].getGlobalReceptionStats().getBytesRecd());
System.out.println("Bytes Transmitidos - " + rtpMgrs[0].getGlobalTransmissionStats().getBytesSent());
System.out.println("Pacotes RTCP recebidos - " + rtpMgrs[0].getGlobalReceptionStats().getRTCPRecd());
System.out.println("Pacotes RTCP transmitidos - " + rtpMgrs[0].getGlobalTransmissionStats().getRTCPSent());
System.out.println("Pacotes SR recebidos - " + rtpMgrs[0].getGlobalReceptionStats().getSRRecd());
System.out.println("Pacotes RTP transmitidos - " + rtpMgrs[0].getGlobalTransmissionStats().getRTPSent());
System.out.println("Pacotes em loop - " + rtpMgrs[0].getGlobalReceptionStats().getPacketsLooped());
System.out.println("Falhas na Transmisso - " + rtpMgrs[0].getGlobalReceptionStats().getTransmitFailed());
System.out.println("Pacotes Bye mal formados - " + rtpMgrs[0].getGlobalReceptionStats().getMalformedBye());
System.out.println("Pacotes RR mal formados - " + rtpMgrs[0].getGlobalReceptionStats().getMalformedRR());
System.out.println("Pacotes SDES mal formados - " +
rtpMgrs[0].getGlobalReceptionStats().getMalformedSDES());
System.out.println("Pacotes SR mal formados - " + rtpMgrs[0].getGlobalReceptionStats().getMalformedSR());

/** Finaliza Transmisso */


stop();

96
System.out.println("============= FIM DE TRANSMISSO ===============");
System.exit(0);
}

/** INICIA A TRANSMISSAO */


/** RETORNA NULL SE NO HOUVERAM ERROS, SENO RETORNA UMA STRING COM ERRO.*/
public synchronized String start()
{
/** result => SAIDA DE ERRO */
String result;

/** CRIA UM processor PARA O ARQUIVO ESPECIFICADO NO media locator


* E SETA A SAIDA PARA JPEG/RTP */
result = createProcessor();
if (result != null) {return result;}

/** CRIA UMA SESSAO RTP PARA TRANSMITIR A SAIDA DO processor PARA O IP E PORTA */
result = createTransmitter();
if (result != null)
{
processor.close();
processor = null;
return result;
}
/** INICIA A TRANSMISSAO = start()*/
processor.start();

status2.setText("STATUS: Transmitindo....");

/** SE TRANSMISSAO BEM SUSCEDIDA, ENTAO RETORNA NULL */


return null;
}

/** FINALIZA A TRANSMISSAO */


public void stop()
{
status2.setText("STATUS: Fim de transmisso!");
status2.repaint();
repaint();
try {
Thread.sleep(10000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}

synchronized (this)
{
if (processor != null)
{
processor.stop();
processor.close();
processor = null;

for (int i = 0; i < rtpMgrs.length; i++)


{
rtpMgrs[i].removeTargets("STATUS: Sesso terminada.");
rtpMgrs[i].dispose();
}
}
}
}

/** CRIA PROCESSADOR */

97
private String createProcessor()
{
if (locator == null)
return "ERRO: locator null!";

DataSource ds;
DataSource clone;

try {ds = javax.media.Manager.createDataSource(locator);}


catch (Exception e) {return "ERRO: No foi possvel criar o DataSource";}

/** CRIA UM processor PARA TRATAR A ENTRADA DO media locator */


try {processor = javax.media.Manager.createProcessor(ds);}
catch (NoProcessorException npe) {return "ERRO: No foi possvel criar o processor";}
catch (IOException ioe) {return "ERRO: Ocorreu um IOException durante a criao do processor";}

/** ESPERA QUE TERMINE A CONFIGURAO */


boolean result = waitForState(processor, Processor.Configured);
if (result == false) return "ERRO: No foi possvel configurar o processor";

/** PEGA AS TRILHAS DO processor */


TrackControl [] tracks = processor.getTrackControls();

/** TEM PELO MENOS UMA TRILHA? */


if (tracks == null || tracks.length < 1)
return "ERRO: No foram encontradas trilhas no processor";

/** SETA A SAIDA DO descriptor PARA RAW_RTP


ISTO IR LIMITAR OS FORMATOS SUPORTADOS QUE SERO REPORTADOS PELO
Track.getSupportedFormats PARA APENAS FORMATOS VALIDOS RTP.*/
ContentDescriptor cd = new ContentDescriptor(ContentDescriptor.RAW_RTP);
processor.setContentDescriptor(cd);

Format supported[];
Format chosen;
boolean atLeastOneTrack = false;

/** PROGRAMA AS TRILHAS.*/


for (int i = 0; i < tracks.length; i++)
{
Format format = tracks[i].getFormat();

if (tracks[i].isEnabled())
{
supported = tracks[i].getSupportedFormats();

if (supported.length > 0)
{
if (supported[0] instanceof VideoFormat)
{
/** CHECA O TAMANHO PORQUE NEM TODOS OS FORMATOS FUNCIONAM
COM TODOS OS TAMANHOS*/
chosen = checkForVideoSizes(tracks[i].getFormat(), supported[0]);
}
else
chosen = supported[0];

tracks[i].setFormat(chosen);
System.out.println("Trilha " + i + " setado para transmitir: " + chosen);
atLeastOneTrack = true;
}
else
tracks[i].setEnabled(false);

98
}
else
tracks[i].setEnabled(false);
}
if (!atLeastOneTrack)
{
//status2.setText("ERRO: Nenhuma trilha pde ser setada para um formato RTP vlido");
return "ERRO: Nenhuma trilha pde ser setada para um formato RTP vlido";
}

/** CRIA UM FLUXO GRAFICO E TENTA CRIAR UM datasource DE SAIDA JPEG/RTP */


result = waitForState(processor, Controller.Realized);
if (result == false)
return "ERRO: No foi possivel criar saida no processor";

/** seta a qualidade JPEG Set the JPEG quality to 0.5. */


setJPEGQuality(processor, 0.5f);

/** pega a saida do datasource do processor */


dataOutput = processor.getDataOutput();

//System.out.println(dataOutput.getContentType());
return null;
}

/** USA O RTPManager PARA CRIAR UMA SESSAO PARA CADA MDIA (AUDIO E VIDEO) */
private String createTransmitter()
{
PushBufferDataSource pbds = (PushBufferDataSource)dataOutput;
PushBufferStream pbss[] = pbds.getStreams();

rtpMgrs = new RTPManager[pbss.length];


SendStream sendStream;
int port;
SourceDescription srcDesList[];

for (int i = 0; i < pbss.length; i++)


{
try
{
rtpMgrs[i] = RTPManager.newInstance();
port = porta + 2*i;

IP = IP.trim();

/** INICIALIZA O RTPManager COM O RTPSocketAdapter */


rtpMgrs[i].initialize(new Conexao(IP,port,t));

status.setText("Sesso RTP criada: IP - " + IP);

System.out.println("Sesso RTP criada: IP - " + IP + " , Porta - " + port);

sendStream = rtpMgrs[i].createSendStream(dataOutput, i);


sendStream.start();
}
catch (Exception e) {return e.getMessage();}
}
return null;
}

/** JPEG e H263, apenas funcionam para determinados tamanhos (verifica se tamanhos esto corretos novamente) */
Format checkForVideoSizes(Format original, Format supported)
{

99
int width, height;
Dimension size = ((VideoFormat)original).getSize();
Format jpegFmt = new Format(VideoFormat.JPEG_RTP);
Format h263Fmt = new Format(VideoFormat.H263_RTP);

if (supported.matches(jpegFmt))
{
/** Para JPEG, a largura e a altura devem ser divisiveis por 8 */
width = (size.width % 8 == 0 ? size.width : (int)(size.width / 8) * 8);
height = (size.height % 8 == 0 ? size.height : (int)(size.height / 8) * 8);
}
else /** Para H.263, apenas alguns tamanhos so suportados */
if (supported.matches(h263Fmt))
{
if (size.width < 128)
{
width = 128;
height = 96;
}
else
if (size.width < 176)
{
width = 176;
height = 144;
}
else
if (size.width > 400)
{
width = 800;
height = 600;
}
else
{
width = 352;
height = 288;
}
}
else
{
return supported;
}
return (new VideoFormat(null, new Dimension(width, height),
Format.NOT_SPECIFIED, null,
Format.NOT_SPECIFIED)).intersects(supported);
}

/** SETANDO A QUALIDADE DE CODIFICAO PARA 0.5 OU OUTRO VALOR (JPEG encoder) */
void setJPEGQuality(Player p, float val)
{
Control cs[] = p.getControls();
QualityControl qc = null;
VideoFormat jpegFmt = new VideoFormat(VideoFormat.JPEG);

/** PROCURA NOS CONTROLES A QUALIDADE PARA O JPEG encoder */


for (int i = 0; i < cs.length; i++)
{
if (cs[i] instanceof QualityControl && cs[i] instanceof Owned)
{
Object owner = ((Owned)cs[i]).getOwner();

/** CHECA O CODEC E O FORMATO DE SAIDA */


if (owner instanceof Codec)
{

100
Format fmts[] = ((Codec)owner).getSupportedOutputFormats(null);
for (int j = 0; j < fmts.length; j++)
{
if (fmts[j].matches(jpegFmt))
{
qc = (QualityControl)cs[i];
qc.setQuality(val);
System.out.println("Setando qualidade para " + val + " no " + qc);
break;
}
}
}
if (qc != null) break;
}
}
}

/** METODOS PARA TRATAR OS ESTADOS DO PROCESSADOR */

private Integer stateLock = new Integer(0);


private boolean failed = false;
Integer getStateLock() {return stateLock;}
void setFailed() {failed = true;}

private synchronized boolean waitForState(Processor p, int state)


{
p.addControllerListener(new StateListener());
failed = false;

/** CHAMA O METODO PEDIDO NO processor*/


if (state == Processor.Configured) {p.configure();}
else if (state == Processor.Realized) {p.realize();}

/** ESPERA ATE QUE CHEGUE UM EVENTO CONFIRMANDO O STATUS DO METODO (olhar classe
StateListener inner)*/
while (p.getState() < state && !failed)
{
synchronized (getStateLock())
{
try {getStateLock().wait();} catch (InterruptedException ie) {return false;}
}
}
if (failed) return false;
else return true;
}

class StateListener implements ControllerListener


{
public void controllerUpdate(ControllerEvent ce)
{
/** SE OCORREU UM ERRO DURANTE A CONFIGURAO OU REALIZAO, O processor
FECHADO.*/
if (ce instanceof ControllerClosedEvent) setFailed();

/** TODOS OS EVENTOS DO controller ENVIAM UMA NOTIFICAO PARA A


THREAD QUE ESPERA NO METODO waitForState*/
if (ce instanceof ControllerEvent)
{
synchronized (getStateLock())
{
getStateLock().notifyAll();
}

101
}
}
}
}

Conexao.java
/** PACOTE PRINCIPAL*/
package transmissor_furgtv;

//=================== BIBLIOTECAS =============================\\


/** E/S */
import java.io.IOException;

/** REDE */
import java.net.*;

/** RTP */
import javax.media.protocol.DataSource;
import javax.media.protocol.PushSourceStream;
import javax.media.protocol.ContentDescriptor;
import javax.media.protocol.SourceTransferHandler;
import javax.media.rtp.RTPConnector;
import javax.media.rtp.OutputDataStream;

/** IMPLEMENTAO DE UM RTPConnector BASEADO EM SOCKETS UDP */


public class Conexao implements RTPConnector
{
/** Socket Multicast de Dados (RTP) para trilha 0*/
MulticastSocket dataSock0;

/** Socket Multicast de Dados (RTP) para trilha 1*/


MulticastSocket dataSock1;

/** Endereo do Grupo Multicast */


InetAddress addr;

/** Porta */
int port;

/** Sockets de Entrada */


SockInputStream dataInStrm0 = null,
dataInStrm1 = null;

/** Sockets de Saida */


SockOutputStream dataOutStrm0 = null,
dataOutStrm1 = null;

/** Construtor da Classe Conexao */


public Conexao(String endereco, int porta, int TTL) throws IOException
{
try
{
/** cria socket multicast de dados*/
dataSock0 = new MulticastSocket(porta);

/** cria socket multicast de dados*/


dataSock1 = new MulticastSocket(porta+2);

/** cria grupo multicast atravs do endereo passado como parmetro*/


this.addr = InetAddress.getByName(endereco);

102
/** se inscreve no grupo multicast da trilha 0*/
dataSock0.joinGroup(this.addr);
dataSock0.setTimeToLive(TTL);

/** se inscreve no grupo multicast da trilha 1*/


dataSock1.joinGroup(this.addr);
dataSock1.setTimeToLive(TTL);
}
catch (SocketException e) {e.printStackTrace();System.exit(-1);}

this.port = porta;
}

/** RETORNA UM input stream PARA RECEBER DADOS RTP da trilha 0*/
public PushSourceStream getDataInputStream() throws IOException
{
if (dataInStrm0 == null)
{
dataInStrm0 = new SockInputStream(dataSock0, addr, port);
dataInStrm0.start();
}
return dataInStrm0;
}

/** RETORNA UM output stream PARA ENVIAR DADOS RTP da trilha 0*/
public OutputDataStream getDataOutputStream() throws IOException
{
if (dataOutStrm0 == null) dataOutStrm0 = new SockOutputStream(dataSock0, addr, port);
return dataOutStrm0;
}

/** RETORNA UM input stream PARA RECEBER DADOS RTP da trilha 1*/
public PushSourceStream getControlInputStream() throws IOException
{
if (dataInStrm1 == null)
{
dataInStrm1 = new SockInputStream(dataSock1, addr, port+2);
dataInStrm1.start();
}
return dataInStrm1;
}

/** RETORNA UM output stream PARA ENVIAR DADOS RTP da trilha 1 */


public OutputDataStream getControlOutputStream() throws IOException
{
if (dataOutStrm1 == null)
dataOutStrm1 = new SockOutputStream(dataSock1, addr, port+2);
return dataOutStrm1;
}

/** FECHA TODOS OS STREAMS RTP da trilha 0 e da trilha 1 */


public void close()
{
if (dataInStrm0 != null)
dataInStrm0.kill();

if (dataInStrm1 != null)
dataInStrm1.kill();

dataSock0.close();
dataSock1.close();
}

103
/** SETA O TAMANHO DO BUFFER DE RECEPO DO CANAL DE DADOS RTP. */
public void setReceiveBufferSize( int size) throws IOException
{dataSock0.setReceiveBufferSize(size); }

/** RETORNA O TAMANHO DO BUFFER DE RECEPO DO CANAL DE DADOS */


public int getReceiveBufferSize()
{
try {return dataSock0.getReceiveBufferSize();}
catch (Exception e) {return -1;}
}

/** SETA O TAMANHO DO BUFFER DE TRANSMISSO DO CANAL DE DADOS RTP. */


public void setSendBufferSize( int size) throws IOException {dataSock0.setSendBufferSize(size);}

/** RETORNA O TAMANHO DO BUFFER DE TRANSMISSO DO CANAL DE DADOS */


public int getSendBufferSize()
{
try {return dataSock0.getSendBufferSize();}
catch (Exception e) {return -1;}
}

/** RETORNA A LARGURA DE BANDA DESTINADA AO RTCP. UTILIZADO PARA INICIALIZAR O


RTPManager. */
public double getRTCPBandwidthFraction() {return -1;}

/** RETORNA A LARGURA DE BANDA DESTINADA AO TRANSMISSOR RTCP. UTILIZADO PARA


INICIALIZAR O RTPManager. */
public double getRTCPSenderBandwidthFraction() {return -1;}

/** Uma classe inner para implementar um OutputDataStream baseado em Sockets UDP */
class SockOutputStream implements OutputDataStream
{
DatagramSocket sock;
InetAddress addr;
int port;

/** cria socket de sada */


public SockOutputStream(DatagramSocket sock, InetAddress addr, int port)
{
this.sock = sock;
this.addr = addr;
this.port = port;
}

/**envia pacote*/
public int write(byte data[], int offset, int len)
{
try {sock.send(new DatagramPacket(data, offset, len, addr, port));}
catch (Exception e) {return -1;}
return len;
}
}

/** uma classe inner para implementar um PushSourceStream baseado em Sockets UDP.*/
class SockInputStream extends Thread implements PushSourceStream
{
DatagramSocket sock;
InetAddress addr;
int port;
boolean done = false;
boolean dataRead = false;
SourceTransferHandler sth = null;

104
/** cria socket de entrada */
public SockInputStream(DatagramSocket sock, InetAddress addr, int port)
{
this.sock = sock;
this.addr = addr;
this.port = port;
}
/** L pacote */
public int read(byte buffer[], int offset, int length)
{
DatagramPacket p = new DatagramPacket(buffer, offset, length, addr, port);

try {sock.receive(p);}
catch (IOException e) {return -1;}

synchronized (this)
{
dataRead = true;
notify();
}
return p.getLength();
}
public synchronized void start()
{
super.start();

if (sth != null)
{
dataRead = true;
notify();
}
}
public synchronized void kill()
{
done = true;
notify();
}
public int getMinimumTransferSize()
{
return 2 * 1024;
}
public synchronized void setTransferHandler(SourceTransferHandler sth)
{
this.sth = sth;
dataRead = true;
notify();
}

public ContentDescriptor getContentDescriptor() {return null;}


public long getContentLength() {return LENGTH_UNKNOWN;}
public boolean endOfStream() {return false;}
public Object[] getControls() {return new Object[0];}
public Object getControl(String type) {return null;}

/** Procura e notifica o tratador de transferncia de novos dados*/


public void run()
{
while (!done)
{
synchronized (this)
{
while (!dataRead && !done) {try {wait();} catch (InterruptedException e) {e.printStackTrace();}}
dataRead = false;

105
}
if (sth != null && !done) {sth.transferData(this);}
}
}
}
}

tempo.java
/** PACOTE PRINCIPAL*/
package transmissor_furgtv;

import java.awt.Image;
import java.awt.Toolkit;
import javax.media.MediaLocator;

public class tempo extends javax.swing.JFrame


{
private MediaLocator video;
private String IP;
private String Porta;
private String TTL;

public tempo(MediaLocator v, String i, String p, String t)


{
//Inicia componentes grficos (janela, boto, etc..)
initComponents();

//Seta o icone da furg na aplicao


Toolkit tk = Toolkit.getDefaultToolkit();
img = tk.getImage("furg.gif");
this.setIconImage(img);

//Inicializa atributos
video = v;
IP = i;
Porta = p;
TTL = t;
}

private void initComponents() //Inicia componentes grficos


{
jPanel1 = new javax.swing.JPanel();
jTextField1 = new javax.swing.JTextField();
jTextField2 = new javax.swing.JTextField();
jTextField3 = new javax.swing.JTextField();
jLabel1 = new javax.swing.JLabel();
jLabel2 = new javax.swing.JLabel();
jLabel3 = new javax.swing.JLabel();
jButton1 = new javax.swing.JButton();
jButton2 = new javax.swing.JButton();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Temporiza\u00e7\u00e3o");
jPanel1.setBackground(new java.awt.Color(0, 51, 102));
jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
jPanel1.setToolTipText("Insira a dura\u00e7\u00e3o do v\u00eddeo em quest\u00e3o");

jLabel1.setFont(new java.awt.Font("Tahoma", 1, 11));


jLabel1.setForeground(new java.awt.Color(255, 255, 255));
jLabel1.setText("Horas");

jLabel2.setFont(new java.awt.Font("Tahoma", 1, 11));


jLabel2.setForeground(new java.awt.Color(255, 255, 255));

106
jLabel2.setText("Minutos");

jLabel3.setFont(new java.awt.Font("Tahoma", 1, 11));


jLabel3.setForeground(new java.awt.Color(255, 255, 255));
jLabel3.setText("Segundos");

jButton1.setText("OK");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});

jButton2.setText("Cancelar");
jButton2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton2ActionPerformed(evt);
}
});

javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);


jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addContainerGap(28, Short.MAX_VALUE)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jLabel1)
.addComponent(jLabel2)
.addComponent(jLabel3))
.addGap(29, 29, 29)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(jTextField2)
.addComponent(jTextField1)
.addComponent(jTextField3, javax.swing.GroupLayout.PREFERRED_SIZE, 62,
javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(48, 48, 48))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
.addComponent(jButton2)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED,
javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(jButton1)
.addGap(31, 31, 31))))
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(26, 26, 26)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel1))
.addGap(18, 18, 18)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jTextField2, javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel2))
.addGap(18, 18, 18)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jTextField3, javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)

107
.addComponent(jLabel3))
.addGap(49, 49, 49)
.addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jButton1)
.addComponent(jButton2))
.addContainerGap(21, Short.MAX_VALUE))
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
);
pack();
}

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {System.exit(0);}

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)


{
String horas, minutos, segundos;
horas = jTextField1.getText();
minutos = jTextField2.getText();
segundos = jTextField3.getText();

this.setVisible(false);

// Cria objeto Transmissor para comear a transmisso


Transmissor at = new Transmissor(horas, minutos, segundos, video, IP, Porta, TTL,null);
}
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JPanel jPanel1;
private javax.swing.JTextField jTextField1;
private javax.swing.JTextField jTextField2;
private javax.swing.JTextField jTextField3;
private Image img;
}

ANEXO 3: MDULO RECEPTOR


Main.java
/** PACOTE PRINCIPAL*/
package receptor_furgtv;

/** Pacote Applet */


import java.applet.Applet;

/** PROGRAMA PRINCIPAL */


public class Main
{
public Main() {}

/** APPLET FURGTV */

108
public static void main(String argv[])
{
/** cria o applet */
Applet principal = new PlayerApplet();

/** inicializa o applet atravs de init() e start(): nessa ordem. */


principal.init();
}
}

Receptor.java
/** PACOTE PRINCIPAL */
package receptor_furgtv;

/** BIBLIOTECAS */

/** E/S */
import java.io.*;
import java.io.FileReader;

/** GRAFICO */
import java.awt.*;
import java.awt.event.*;

/** REDE */
import java.net.*;

/** UTILIDADES */
import java.util.Vector;
import java.util.Properties;

/** MIDIA E RTP */


import javax.media.*;
import javax.media.rtp.*;
import javax.media.rtp.event.*;
import javax.media.rtp.rtcp.*;
import javax.media.protocol.*;
import javax.media.protocol.DataSource;
import javax.media.format.AudioFormat;
import javax.media.format.VideoFormat;
import javax.media.Format;
import javax.media.format.FormatChangeEvent;
import javax.media.control.BufferControl;

/** Applet */
import java.applet.Applet;

/** Lang */
import java.lang.String;

/** Swing */
import javax.swing.*;

/** Applet Player Multimidia */


public class PlayerApplet extends Applet implements ReceiveStreamListener, SessionListener, ControllerListener
{
Player p = null;
PlayerWindow pw = null;
String sessions[] = null;
RTPManager mgrs[] = null;
Vector playerWindows = null;
boolean dataReceived = false;
Object dataSync = new Object();

109
Label status;

protected boolean initialize()


{
try
{
mgrs = new RTPManager[sessions.length];
playerWindows = new Vector();

SessionLabel session;

/** cria sesses RTP*/


for (int i = 0; i < sessions.length; i++)
{
/** trata os endereos da sesso*/
try {session = new SessionLabel(sessions[i]);}
catch (IllegalArgumentException e)
{
System.out.println("ERRO: Endereo de sesso " + sessions[i] + " invlido!");
return false;
}
System.out.println(" Adicionado a Sesso RTP: " + session.addr + ", que escuta na porta: " +
session.port + ", com TTL: " + session.ttl);

mgrs[i] = (RTPManager) RTPManager.newInstance();


mgrs[i].addSessionListener(this);
mgrs[i].addReceiveStreamListener(this);

/** Inicializa o RTPManager com o RTPSocketAdapter*/


mgrs[i].initialize(new Conexao(session.addr, session.port, session.ttl));

BufferControl bc = (BufferControl)mgrs[i].getControl("javax.media.control.BufferControl");
if (bc != null)bc.setBufferLength(350);
}
}
catch (Exception e)
{
status.setText("ERRO: Sintonizao mal sucedida!!");
System.err.println("ERRO: No foi possvel criar a sesso RTP: ");e.printStackTrace();
return false;
}

/** Espera receber dados antes de continuar */


long then = System.currentTimeMillis();
long waitingPeriod = 30000; /** espera no mximo por 30 segundos */

try
{
synchronized (dataSync)
{
while (!dataReceived && System.currentTimeMillis() - then < waitingPeriod)
{
if (!dataReceived)
{
System.out.println(" Esperando dados RTP...");
status.setText("Sintonizando canal FURG TV....");
}
dataSync.wait(1000);
}
}
}
catch (Exception e) {}

110
if (!dataReceived)
{
status.setText("ERRO: Canal fora do ar!");
System.err.println("Nenhum dado RTP foi recebido.");
close();
return false;
}
return true;
}

public boolean isDone() {return playerWindows.size() == 0;}

/** FECHA OS PLAYES E OS GERENTES DE SESSO*/


protected void close()
{
for (int i = 0; i < playerWindows.size(); i++) {
try {
((PlayerWindow)playerWindows.elementAt(i)).close();
} catch (Exception e) {}
}

playerWindows.removeAllElements();

/** Fecha sesso RTP*/


for (int i = 0; i < mgrs.length; i++)
{
if (mgrs[i] != null)
{
mgrs[i].removeTargets( "Fechando sesso");
mgrs[i].dispose();
mgrs[i] = null;
}
}
}

PlayerWindow find(Player p)
{
for (int i = 0; i < playerWindows.size(); i++)
{
pw = (PlayerWindow)playerWindows.elementAt(i);
pw.setTitle("FURG TV");
pw.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
status.setText("FURG TV");
Toolkit tk = Toolkit.getDefaultToolkit();
Image icone = tk.getImage("furg.gif");
pw.setIconImage(icone);
if (pw.p == p) return pw;
}
return null;
}

PlayerWindow find(ReceiveStream strm)


{
for (int i = 0; i < playerWindows.size(); i++)
{
pw = (PlayerWindow)playerWindows.elementAt(i);
if (pw.stream == strm)
return pw;
}
return null;
}

/** SessionListener*/

111
public synchronized void update(SessionEvent evt)
{
if (evt instanceof NewParticipantEvent)
{
Participant pa = ((NewParticipantEvent)evt).getParticipant();
System.err.println(" Um novo participante foi adicionado ao grupo: " + pa.getCNAME());
}
}

/** ReceiveStreamListener*/
public synchronized void update( ReceiveStreamEvent evt)
{
RTPManager mgr = (RTPManager)evt.getSource();
Participant participant = evt.getParticipant();
ReceiveStream stream = evt.getReceiveStream();

if (evt instanceof RemotePayloadChangeEvent)


{
System.err.println("Recebido um RTP PayloadChangeEvent.");
System.err.println("Desculpe, no possvel tratar mudana de payload.");
System.exit(0);
}
else
if (evt instanceof NewReceiveStreamEvent)
{
try
{
stream = ((NewReceiveStreamEvent)evt).getReceiveStream();
DataSource ds = stream.getDataSource();

/** Descobre os formatos.*/


RTPControl ctl = (RTPControl)ds.getControl("javax.media.rtp.RTPControl");
if (ctl != null)
{
System.out.println(" Foi recebido um RTP stream: " + ctl.getFormat());
}
else
System.out.println(" Foi recebido um RTP stream.");

if (participant == null)
System.out.println(" O transmissor do stream deve ser identificado.");
else
{
System.out.println(" O stream vem de: " + participant.getCNAME());
}

/** cria um player passando um datasource para o Media Manager*/


p = javax.media.Manager.createPlayer(ds);
if (p == null)
return;

p.addControllerListener(this);
p.realize();
pw = new PlayerWindow(p, stream);
playerWindows.addElement(pw);

/** Notifica o intialize() que um novo stream chegou*/


synchronized (dataSync)
{
dataReceived = true;
dataSync.notifyAll();
}
}

112
catch (Exception e)
{
System.err.println("ERRO: NewReceiveStreamEvent exception " + e.getMessage());
return;
}
}
else
if (evt instanceof StreamMappedEvent)
{

if (stream != null && stream.getDataSource() != null)


{
DataSource ds = stream.getDataSource();
/** Descobre os formatos*/
RTPControl ctl = (RTPControl)ds.getControl("javax.media.rtp.RTPControl");

if (ctl != null)
System.err.println(" " + ctl.getFormat());
System.out.println(" foi enviado por: " + participant.getCNAME());
}
}
else
if (evt instanceof ByeEvent)
{

System.out.println(" Mensagem \"bye\" recebida de: " + participant.getCNAME());


pw = find(stream);

if (pw != null)
{
pw.close();
playerWindows.removeElement(pw);
}
}
}

/** ControllerListener PARA OS PLAYERS*/


public synchronized void controllerUpdate(ControllerEvent ce)
{
p = (Player)ce.getSourceController();

if (p == null)
return;

if (ce instanceof RealizeCompleteEvent)


{
pw = find(p);

if (pw == null)
{
System.err.println("ERRO: problema interno!");
System.exit(-1);
}

status.setText("www.furgtv.furg.br");
pw.add("South",status);

pw.initialize();
pw.setVisible(true);
p.start();
}

if (ce instanceof ControllerErrorEvent)

113
{
p.removeControllerListener(this);
pw = find(p);

if (pw != null)
{
pw.close();
playerWindows.removeElement(pw);
}
System.err.println("ERRO: " + ce);
}
}

/** CLASSE QUE TRATA A STRING DA SESSAO */


class SessionLabel
{

public String addr = null;


public int port;
public int ttl = 1;

SessionLabel(String session) throws IllegalArgumentException


{
int off;
String portStr = null, ttlStr = null;

if (session != null && session.length() > 0)


{
while (session.length() > 1 && session.charAt(0) == '/')
session = session.substring(1);

// se tem um endereo
off = session.indexOf('/');
if (off == -1)
{
if (!session.equals(""))
addr = session;
}
else
{
addr = session.substring(0, off);
session = session.substring(off + 1);

// se tem uma porta


off = session.indexOf('/');

if (off == -1)
{
if (!session.equals(""))
portStr = session;
}
else
{
portStr = session.substring(0, off);
session = session.substring(off + 1);

// se tem um TTL
off = session.indexOf('/');

if (off == -1)
{
if (!session.equals(""))
ttlStr = session;

114
}
else
{
ttlStr = session.substring(0, off);
}
}
}
}

if (addr == null)
throw new IllegalArgumentException();

if (portStr != null)
{
try
{
Integer integer = Integer.valueOf(portStr);
if (integer != null)
port = integer.intValue();
}
catch (Throwable t)
{
throw new IllegalArgumentException();
}
}
else
throw new IllegalArgumentException();

if (ttlStr != null)
{
try
{
Integer integer = Integer.valueOf(ttlStr);

if (integer != null)
ttl = integer.intValue();
}
catch (Throwable t)
{
throw new IllegalArgumentException();
}
}
}
}

/** CLASSES VISUAIS GUI PARA O PLAYER*/


class PlayerWindow extends JFrame
{
ReceiveStream stream;
private Player p;

PlayerWindow(Player player, ReceiveStream strm)


{
p = player;
stream = strm;
}

public void initialize() {add(new PlayerPanel(p));}

public void close()


{
p.close();
setVisible(false);

115
dispose();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

public void addNotify()


{
super.addNotify();
pack();
}
}

/** CLASSES VISUAIS PARA O PLAYER*/


class PlayerPanel extends JPanel
{
Component vc, cc;

PlayerPanel(Player p) {
setLayout(new BorderLayout());
if ((vc = p.getVisualComponent()) != null) add("Center", vc);
if ((cc = p.getControlPanelComponent()) != null) add("South", cc);
}

public Dimension getPreferredSize() {


int w = 0, h = 0;
if (vc != null) {
Dimension size = vc.getPreferredSize();
w = size.width;
h = size.height;
}
if (cc != null) {
Dimension size = cc.getPreferredSize();
if (w == 0) w = size.width;
h += size.height;
}
if (w < 160) w = 160;
return new Dimension(w, h);
}
}

/** Inicia o Applet */


public void init()
{
status = new Label("Inicializao de Cliente FURG TV", Label.CENTER);
status.setForeground(Color.DARK_GRAY); add(status); setSize(300,300); show();
String sessao[] = new String[2];
BufferedReader arq;
char[] linha = new char[100], protocolo = new char[15], porta = new char[15], ip = new char[15], ttl = new
char[15];
try {
arq = new BufferedReader(new FileReader("C:/parametros.txt"));
arq.read(linha); /** le parametros do arquivo parametros.txt */
int x = 0, y ;
y = 0; while ((linha[x] != ' ')&&(y!=15)) {protocolo[y] = linha[x]; x++; y++;}
x++; y = 0; while ((linha[x] != ' ')&&(y!=15)) {porta[y] = linha[x]; x++; y++;}
x++; y = 0; while ((linha[x] != ' ')&&(y!=15)) {ip[y] = linha[x]; x++; y++;}
x++; y = 0; while ((linha[x] != ' ')&&(y!=15)) {ttl[y] = linha[x];x++; y++; }
arq.close(); /** fecha arquivo */
}
catch (Exception ex) {ex.printStackTrace();}
String IP = String.valueOf(ip).trim();
String TTL = String.valueOf(ttl).trim();
String PORTA = String.valueOf(porta).trim();
sessao[0] = new String(IP+"/"+PORTA+"/"+TTL);

116
Integer p = Integer.valueOf(PORTA).intValue();p = p + 2;PORTA = String.valueOf(p);
sessao[1] = new String(IP+"/"+PORTA+"/"+TTL);
this.sessions = sessao;
if (!initialize()) {
System.err.println("ERRO: Sesses no inicializadas!");
System.exit(-1);
}
System.out.println("====== Cliente Sintonizado na FURGTV =====");
// Checa se acabou a recepo
try {while (!isDone()) Thread.sleep(2000000000);} catch (Exception e) {e.printStackTrace();}
System.out.println("============= FIM DE PROGRAMA ============");
System.exit(0);
}
}

117

Potrebbero piacerti anche