2011년 12월 27일 화요일

error: 'UINT64_C' was not declared in this scope 문제 해결하기

출처 : http://frontjang.tistory.com/213

ffmpeg을 컴파일하는 도중 다음과 같은 오류가 나올경우 컴파일 옵션에 CXXFLAGS=-D__STDC_CONSTANT_MACROS 
을 추가해 주면 된다. 아니면 헤더파일에 아래 항목을 추가해 줄수도 있다. ffmpeg 뿐 아니라 다른 프로젝트에서도 이 방법을 사용할 수 있다.

#ifdef __cplusplus
#define __STDC_CONSTANT_MACROS
#ifdef _STDINT_H
  #undef _STDINT_H
#endif
# include <stdint.h>
#endif

출처 : Issue 11 - ffmpegsource - 'UINT64_C' was not declared in this scope - An FFmpeg based source library and Avisynth plugin for easy frame accurate access - Google Project Hosting

Capture Audio with MediaRecorder

출처 : http://www.androidsnippets.com/capture-audio-with-mediarecorder


/* Create a MediaRecorder */
recorder = new MediaRecorder();
/* ContentValues include title, timestamp, mime type */
ContentValues values = new ContentValues(3);
values.put(MediaStore.MediaColumns.TITLE, SOME_NAME_HERE);
values.put(MediaStore.MediaColumns.TIMESTAMP, System.currentTimeMillis());
values.put(MediaStore.MediaColumns.MIME_TYPE, recorder.getMimeContentType());
/* Create entry in the content database */
ContentResolver contentResolver = new ContentResolver();
Uri base = MediaStore.Audio.INTERNAL_CONTENT_URI;
Uri newUri = contentResolver.insert(base, values);
if (newUri == null) {
    /* Handle exception here - not able to create a new content entry */
}
/* Receive the real path as String */
String path = contentResolver.getDataFilePath(newUri);
/* Set Audio Source, Format, Encode and File */
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(path);
/* Prepare the Recorder */
recorder.prepare();
/* Start Recording */
recorder.start();
/* ... */
/* Stop Recording Again */
recorder.stop();
recorder.release();

Broadcasting on Android

출처 : http://zimly.tistory.com/14


안드로이드 폰에서의 미디어 녹화는 크게 두 가지 방법으로 나뉜다. 하나는 안드로이드 자체에서 제공하는 SDK를 사용해서 H/W 인코더 기능을 이용하는 것이고, 다른 하나는 S/W 인코더를 이용하는 방법이다.

안드로이드 SDK 에서는 MediaRecorder를 통해서 파일에 미디어 데이터를 녹화할 수 있는 기능을 제공하고 있다. 현재로서는 Camera와 Mic만을 소스로 제공하고 있으며, 포맷은 H.263/H.264/MP4(SP)/AMR_NB/MP4/3GPP만을 제공하고 있다. 실제 기능으로는 더 제공할 수도 있겠지만, Android 2.1 버전에서는 해당 포맷만을 제공하는 것으로 되어 있다. 만일 이러한 포맷 이상의 것을 원한다면 S/W 인코더를 이용하는 방법이 있겠다. 이것은 MediaRecorder SDK에서 제공하는 원본 미디어 소스를 받아들인 후에 S/W 인코더를 통해서 원하는 포맷으로 만드는 방법이다. 하지만, 현재 모바일 폰에서 제공하는 CPU 자원의 능력을 고려해 볼 때에, 그렇게 높은 성능을 내지는 못 할 것으로 예상된다.

현재 안드로이드에서는 MP4 컨테이너 포맷만을 지원하고 있는데, - 3GPP도 비슷한 계열이다. - MP4의 특징은 raw data의 metadata를 뒤에다가 적는 특징이 있다. 물론 이것은 라이브 방송이나 브로드캐스팅에서는 적합하지 않기 때문에, hinting이라는 방법을 사용해서 스트리밍을 하는 경우도 있다. 하지만 안드로이드에서는 파일에 저장하는 것만을 고려하기 때문에 그러한 옵션을 제공하고 있지는 않다. 따라서 헤더와 moov ATOM은 MediaRecorder가 stop을 실행한 후에 파일에 저장된다.

일단 S/W 인코더를 이용해서 Cam/Mic의 데이터를 전송하는 것은 가능하다. 하지만 MediaRecorder를 이용해서 전송하기 위해서는 Socket의 File Descriptor를 넘겨줘서, 네트워크로 전송되도록 하는 작업이 필요하다. 또한 UDP로 보내기 위해서는 Socket 대신에 Datagram을 사용해야 하는데, (Socket은 TCP로 전송한다.) 이러한 작업을 하기 위해서는 Loopback을 통해서 재전송 한후에 다시 UDP로 보내는 방법을 사용하는 것도 고려할 수 있다.

또한, 위에서 언급한 것처럼 moov ATOM과 header 정보는 실제 저장되는 동안에는 파일에 저장되지 않기 때문에, 비디오 데이터와 오디오 데이터를 실제로 파싱을 통해서 분리를 하는 작업이 별도로 필요하겠다. MP4의 경우에는 structure 구조로 되어 있어서, 실제 디코딩하는 레벨로 파싱 작업을 진행해야 된다. 이러한 작업을 통해서 실제 비디오, 오디오 데이터를 분리한 후에는 각각의 다시 트랜스코딩해서 보내거나, hinting 작업을 통해서 re-muxing해서 보내게 되면, 다른 곳에서도 재생이 가능하다.

현재 uStream/Qik/Knocking Video 등에서는 이러한 방법을 통해서 안드로이드 폰에서 방송을 할 수  있는 서비스를 제공하고 있으며, 점점 그 사용빈도가 늘어나고 있다. (얼마 전에 구글에 인수된 GIPS도 이러한(S/W 방식의) 솔루션을 가지고 있었다.)

앞으로 안드로이드 OS를 이용한 타블렛에 웹캠이 장착된다면, 이러한 기술을 통해서 상호간에 화상통화나 개인 방송 송출을 하는 것이 충분히 가능할 것으로 보인다.