Especificação



Baixar 2,81 Mb.
Página10/24
Encontro01.07.2018
Tamanho2,81 Mb.
1   ...   6   7   8   9   10   11   12   13   ...   24

5.6 Gravação do arquivo codificado


Com o propósito de distinguir entre características específicas da codificação daquelas específicas do armazenamento, o padrão H.264 é separado em duas camadas: a VCL (Video Coding Layer), cuja saída é uma seqüência de bits representando o vídeo codificado; e a NAL (Network Abstraction Layer), responsável por abstrair a maneira como os dados são escritos.

Os dados de saída da VCL são mapeados para unidades NAL antes do armazenamento ou da transmissão. Cada unidade NAL contém uma carga útil (payload) que corresponde aos dados de saída da VCL ou parâmetros da codificação.

Neste trabalho a NAL e a VCL foram explicitamente separadas em diferentes pacotes e classes. Além disso, a persistência do arquivo de vídeo foi separada da NAL, assim, o encapsulamento de dados na NAL e a gravação em arquivo são realizados por classes distintas.

Em relação à JMF, a escrita deve ser realizada por um componente Multiplexer. O capítulo 3 descreve mais detalhadamente o processo de multiplexação.


      1. 5.6.1 Formatos de saída


Dentre os mais comuns tipos de arquivos contendo vídeo H.264 estão o container MP4 e fluxo de bits puro 264, ou raw bitstream, que não é armazenado em container.



        1. 5.6.1.1 Fluxo de bits puro

O anexo B do documento do padrão ISO 14496-10 [3] define um formato de escrita de vídeo H.264 chamado fluxo de bits puro.



        1. 5.6.1.2 Container MP4

O documento ISO 14496-14 especifica um container, que dentre outras coisas pode conter vídeo H.264.



  1. Capítulo 6: Conclusões


Neste capítulos estão descritas as conclusões obtidas durante e após o desenvolvimento do codificador.




    1. 6.1 Fatores técnicos


Esta seção descreve os fatores técnicos relativos ao desempenho, qualidade da imagem e dificuldades técnicas durante o desenvolvimento.




      1. 6.1.1 Dificuldades durante o desenvolvimento


Sem dúvida a maior dificuldade foi organizar o código de referência de modo a entender o que cada módulo fazia. O código de referência [2] é um retalho de funções, mal organizado, pouco comentado e com diversas ambiguidades. Outro fator que também dificulta é a desconexão parcial com o documento padrão [3], sendo exigido um estudo muito detalhado de ambos para poder estabelecer uma ligação entre eles.

O nível de detalhes no código também foi fonte de atrasos no projeto. Foram necessários testes constantes durante todo o desenvolvimento para assegurar que o vídeo codificado estava de acordo com aquele gerado pelo código de referência, bastando a escrita errada de apenas um bit para invalidar toda a codificação.


    1. 6.2 Considerações para o futuro


Uma das principais preocupações durante o desenvolvimento deste trabalho foi a de permitir que ele seja continuado, por meio de uma cuidadosa modelagem orientada a objetos e documentação. A seguir estão algumas da sugestões para extensão deste trabalho.




      1. 6.2.1 Desempenho de algoritmos


O codificador implementado manteve os algoritmos originais do código de referência do ITU-T. Um trabalho futuro seria utilizar algoritmos mais eficientes para estimação de movimento (Motion Estimation), DCT e Quantização, para permitir uso com dispositivos móveis, os quais possuem menos poder de processamento.

Segundo artigo [44], a estimação de movimento consome a maior parte do tempo de processamento de um codificador. Por exemplo, ao invés de utilizar o algoritmo Full Search para estimação de movimento, utilizar um algoritmo de busca parcial, tal como o Predictive Algorithm (PA) ou o Diamond Search.

Utilizar uma DCT com inteiros ao invés de pontos flutuantes, permitindo utilizar somas e deslocamentos no lugar das multiplicações.




      1. 6.2.2 Transporte e armazenamento


A gravação deste arquivo é feita de acordo com o Anexo B do documento padrão [3], que é a forma de gravação em fluxo contínuo de bytes. Há diversas propostas para implementar uma forma de gravação de pacotes NAL para sobre RTP, uma delas é a indicada em [43], que sugere um formato de carga útil para pacotes RTP com H.264.

Um outra melhoria seria implementar um multiplexador MP4 (MPEG-4 Parte 14), para que a saída do codificador fosse compatível com a maioria dos reprodutores disponíveis.


      1. 6.2.3 Perfis


Extensões futuras poderiam adicionar os outros perfis do padrão, tal como o Main, Extended, High, etc. Com isso seria necessário implementar recursos ainda não disponíveis neste codificador, como por exemplo, a codificação por entropia CABAC.




      1. 6.2.4 Decodificador


Um decodificador H.264 em Java seria muito útil, e sua implementação seria facilitada pelo reuso de diversas classes já implementadas pelo codificador.



  1. Apêndice A: Código-fonte


Este apêndice contém o código-fonte desenvolvido neste trabalho. Devido ao grande volume de código desenvolvido, apenas as classes principais são exibidas. E pelo mesmo motivo, classes semelhantes são omitidas. Por exemplo, os modos de codificação, os quais mudam pouco um do outro.

As classes estão apresentadas em seções, de acordo com sua função dentro do codificador.

    1. A1 Classes de suporte




      1. A1.1 Classe Registry



package br.ufsc.inf.guiga.media;
import java.io.IOException;

import java.util.Vector;
import javax.media.Codec;

import javax.media.Demultiplexer;

import javax.media.Multiplexer;

import javax.media.PackageManager;

import javax.media.PlugInManager;
import br.ufsc.inf.guiga.media.codec.video.colorspace.JavaYUVToRGB;

import br.ufsc.inf.guiga.media.codec.video.h264.H264Encoder;

import br.ufsc.inf.guiga.media.multiplexer.video.H264Mux;

import br.ufsc.inf.guiga.media.multiplexer.video.MP4Mux;

import br.ufsc.inf.guiga.media.parser.video.YUVParser;
import com.sun.media.MimeManager;
/**

* H.264 CODEC registration routines.

*

* @author Guilherme Ferreira



*/

public class Registry {
@SuppressWarnings("unchecked")

public static void registerPackage() {

String packageName = "br.ufsc.inf.guiga";

Vector contentPrefixList;

Vector protocolPrefixList;


// PackageManager maintains a registry of packages that contain JMF classes,

// such as custom Players, Processors, DataSources and DataSinks. We add our

// packager first to be the first choice when creating plug-ins.

try {

contentPrefixList = PackageManager.getContentPrefixList();



if (!contentPrefixList.contains(packageName)) {

contentPrefixList.add(0, packageName);

PackageManager.setContentPrefixList(contentPrefixList);

}
protocolPrefixList = PackageManager.getProtocolPrefixList();



if (!protocolPrefixList.contains(packageName)) {

protocolPrefixList.add(0, packageName);

PackageManager.setProtocolPrefixList(protocolPrefixList);

}
PackageManager.commitContentPrefixList();

PackageManager.commitProtocolPrefixList();
} catch (SecurityException sex) {

System.err.println("Could not register the package " + packageName);

sex.printStackTrace();

}

}


public static void registerYUVHandler() {

// MimeManager maintains an associating between file extension and content

// descriptors, or MIME types

MimeManager.addMimeType("yuv", "video/yuv");

MimeManager.commit();
// PlugInManager maintains a registry of available JMF plug-in processing

// components, such as Multiplexers, Demultiplexers, Codecs, Effects and Renderers


// Register the YCbCr parser plugin. Allow JMF read .yuv files

Demultiplexer demuplexer = (Demultiplexer) new YUVParser();

String name = demuplexer.getClass().getName();

PlugInManager.addPlugIn(name, demuplexer.getSupportedInputContentDescriptors(),



null, PlugInManager.DEMULTIPLEXER);
// Register a plugin to convert from YCbCr to RGB color space

Codec plugin = (Codec) new JavaYUVToRGB();

name = plugin.getClass().getName();

PlugInManager.addPlugIn(name, plugin.getSupportedInputFormats(), plugin

.getSupportedOutputFormats(null), PlugInManager.CODEC);
try {

PlugInManager.commit();

} catch (IOException ex) {

ex.printStackTrace();

}

}
public static void registerH264Encoder() {



// Register a plugin to encode H.264 Video

Codec plugin = (Codec) new H264Encoder();

String name = plugin.getClass().getName();

PlugInManager.addPlugIn(name, plugin.getSupportedInputFormats(), plugin

.getSupportedOutputFormats(null), PlugInManager.CODEC);
// Register the 264 raw byte stream Multiplexer plugin. Allowing JMF write .264

// files


Multiplexer mulplexer = (Multiplexer) new H264Mux();

name = mulplexer.getClass().getName();

PlugInManager.addPlugIn(name, null, mulplexer

.getSupportedOutputContentDescriptors(null), PlugInManager.MULTIPLEXER);


// Register the MP4 File Format Multiplexer plugin. Allowing JMF write .mp4

// files


mulplexer = (Multiplexer) new MP4Mux();

name = mulplexer.getClass().getName();

PlugInManager.addPlugIn(name, null, mulplexer

.getSupportedOutputContentDescriptors(null), PlugInManager.MULTIPLEXER);


try {

PlugInManager.commit();

} catch (IOException ex) {

ex.printStackTrace();

}

}

}






1   ...   6   7   8   9   10   11   12   13   ...   24


©livred.info 2017
enviar mensagem

    Página principal