AWS Marketplace 구독 취소하기

기타 2017.04.17 09:51 Posted by 김한별 behonestar

AWS Marketplace AMI를 구매하여 EC2 인스턴스를 운영하다가 종료시켰다. 하지만 다음 달에도 해당 AMI에 대한 요금이 청구되었다. 


AMI를 사용하는 EC2가 없더라도 AMI에 대한 Subscription은 유효하기 때문이다. 따라서 Subscription을 취소해줘야 요금이 청구되지 않는다.



1. 마켓플레이스 접속

https://aws.amazon.com/marketplace





2. 구독 취소



'기타' 카테고리의 다른 글

AWS Marketplace 구독 취소하기  (0) 2017.04.17
visual studio에서 libcurl 빌드하고 사용하기  (1) 2017.04.13
[EC2] samba over ssh tunneling  (0) 2016.04.08
AWS EC2 tomcat 80 포트 사용하기  (0) 2015.10.14
정규식 시트  (0) 2015.03.05

visual studio에서 libcurl 빌드하고 사용하기

기타 2017.04.13 14:27 Posted by 김한별 behonestar

libcurl 빌드하기 (dll)

1. curl 다운로드 후 압축 풀기

https://curl.haxx.se/download/curl-7.53.1.tar.gz


2. 미리 컴파일된 openssl 다운로드 후 압축풀기

openssl-1.0.1f_vc_no-idea no-mdc2 no-rc5_build.zip


3.openssl\include\openssl 디렉토리를 curl-7.53.1\include에 복사


4. curl visual studio 솔루션 실행

curl-7.53.1\projects\Windows\VC10\curl-all.sln


5. 구성 및 플랫폼 설정

LIB Release - LIB OpenSSL / Win32


6. 빌드



libcurl 사용하기

<라이브러리 복사>

1. libcurl을 사용할 visual studio 프로젝트에 include, lib 디렉토리 생성 

2. include에 curl-7.53.1\include를 복사하고 디렉토리명을 curl로 변경

3. lib에 curl-7.53.1\build\Win32\VC10\LIB Release - LIB OpenSSL\libcurl.lib 복사

 lib에 openssl\lib\libeay32.lib, ssleay32.lib 복사

4. 프로젝트 경로에 openssl\bin\libeay32.dll과 ssleay32.dll 복사 (실행할 때 필요)


<프로젝트에 라이브러리 링크>

1. 프로젝트 속성 > 구성속성 > C/C++ > 일반 > 추가 포함 디렉터리 (-I)

$(ProjectDir)\include


2. 프로젝트 속성 > 구성속성 > C/C++ > 전처리기 > 전처리기 정의 (-D)

CURL_STATICLIB


3. 프로젝트 속성 > 구성속성 > 링커 > 일반 > 추가 라이브러리 디렉터리 (-L)

$(ProjectDir)\lib


4. 프로젝트 속성 > 구성속성 > 링커 > 입력 > 추가 종속성 (-l)

libcurl.lib

libeay32.lib

ssleay32.lib

wldap32.lib

ws2_32.lib


5. 빌드 후 실행



참고


'기타' 카테고리의 다른 글

AWS Marketplace 구독 취소하기  (0) 2017.04.17
visual studio에서 libcurl 빌드하고 사용하기  (1) 2017.04.13
[EC2] samba over ssh tunneling  (0) 2016.04.08
AWS EC2 tomcat 80 포트 사용하기  (0) 2015.10.14
정규식 시트  (0) 2015.03.05

증상

Node.js HTTPS 서버를 운영하고 있는데, Windows XP IE8 브라우저에서 접속이 안된다고 한다.



원인

https 서버 옵션의 ciphers 항목을 지정하지 않을 경우, Windows XP IE8과 호환되지 않음.


대책

1. ssl-config 모듈 설치

npm install ssl-config --save


2. ssl-config 모듈을 intermediate 모드로 로드

var sslConfig = require('ssl-config')('intermediate');


3. https 서버 옵션의 cipher 설정

var options = {

        key: fs.readFileSync(path.resolve(__dirname, 'ssl/key.pem')),

        cert: fs.readFileSync(path.resolve(__dirname, 'ssl/cert.pem')),

        ciphers: sslConfig.ciphers

};



참고

https://www.npmjs.com/package/ssl-config


[GStreamer] Push, Pull 방식

GStreamer 2017.04.05 16:08 Posted by 김한별 behonestar


이 글은 GStreamer 튜토리얼 문서 Different scheduling modes를 요약한 글입니다.


엘리먼트의 Pad는 Push 방식과 Pull 방식의 스케쥴링 모드를 지원합니다. 대표적으로 아래와 같은 use-case가 존재합니다.


1. 모든 엘리먼트의 패드들이 push 모드인 경우

① 첫번째 엘리먼트는 다음 엘리먼트의 sinkpad에게 버퍼를 push하는 작업을 반복합니다.

② 두번째 엘리먼트는 sinkpad에 등록된 _chain() 함수를 통해 전달받은 버퍼를 처리합니다.

③ _chain() 함수는 gst_pad_push() 함수를 통해 다음 엘리먼트의 sinkpad에게 버퍼를 push합니다.



2. sinkpad는 pull 모드, srcpad는 push 모드인 경우

① sinkpad가 pull 모드로 활성화되면 사용자가 정의한 GstTask 스레드가 시작됩니다.

② 해당 스레드는 gst_pad_pull_range() 함수를 통해 이전 엘리먼트의 버퍼로부터 특정 범위의 데이터를 얻어와서 데이터를 처리합니다. sinkpad가 데이터의 흐름을 제어하게 되는 것이죠.

③ gst_pad_push() 함수를 통해 다음 엘리먼트의 sinkpad에게 버퍼를 push합니다.


* sinkpad를 pull 모드로 설정하는 방법

엘리먼트의 상태가 READY -> PAUSED로 변경될 때 패드가 활성화됩니다. 내부적으로는 _activate() 함수와 _activate_mode() 함수가 호출됩니다. pull 모드로 변경하려면 이 두가지 함수를 오버라이딩하여 스케쥴링 모드를 변경하면 됩니다. 오버라이딩하지 않으면 기본값인 push 모드로 동작합니다.


1) _activate() 함수 오버라이딩 

static void

gst_my_filter_init (GstMyFilter * filter)

{

  [...]

  gst_pad_set_activate_function (filter->sinkpad, gst_my_filter_activate);

  [...]

}


2) 이전 엘리먼트의 srcpad가 pull 모드를 지원하면, 현재 엘리먼트의 sinkpad도 pull 모드로 설정

static gboolean

gst_my_filter_activate (GstPad * pad, GstObject * parent)

{

  GstQuery *query;

  gboolean pull_mode;


  query = gst_query_new_scheduling ();


  if (gst_pad_peer_query (pad, query)) {

    pull_mode = gst_query_has_scheduling_mode_with_flags (query,

        GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);


    if (pull_mode) {

      gst_query_unref (query);

      return gst_pad_activate_mode (pad, GST_PAD_MODE_PULL, TRUE);

    }

  }


  gst_query_unref (query);

  return gst_pad_activate_mode (pad, GST_PAD_MODE_PUSH, TRUE);

}


3) _activate_mode() 함수 오버라이딩

static void

gst_my_filter_init (GstMyFilter * filter)

{

  [...]

  gst_pad_set_activatemode_function (filter->sinkpad, gst_my_filter_activate_mode);

  [...]

}


4) pad가 pull 모드로 활성화되면 GstTask 스레드 실행, 비활성화되면 GstTask 스레드 종료

static gboolean

gst_my_filter_activate_mode (GstPad    * pad,

                 GstObject * parent,

                 GstPadMode  mode,

                 gboolean    active)

{

  gboolean res;

  GstMyFilter *filter = GST_MY_FILTER (parent);


  switch (mode) {

    case GST_PAD_MODE_PUSH:

      res = TRUE;

      break;

    case GST_PAD_MODE_PULL:

      if (active) {

        filter->offset = 0;

        res = gst_pad_start_task (pad,

            (GstTaskFunction) gst_my_filter_loop, filter, NULL);

      } else {

        res = gst_pad_stop_task (pad);

      }

      break;

    default:

      /* unknown scheduling mode */

      res = FALSE;

      break;

  }

  return res;

}


5) GstTask 스레드 구현 : 이전 엘리먼트로부터 데이터를 읽어와서 다음 엘리먼트에게 push 

    static void

    gst_my_filter_loop (GstMyFilter * filter)

    {

      GstFlowReturn ret;

      guint64 len;

      GstFormat fmt = GST_FORMAT_BYTES;

      GstBuffer *buf = NULL;


      [...]


      /* now, read BLOCKSIZE bytes from byte offset filter->offset */

      ret = gst_pad_pull_range (filter->sinkpad, filter->offset,

          BLOCKSIZE, &buf);


      [...]


      /* now push buffer downstream */

      ret = gst_pad_push (filter->srcpad, buf);


      [...]

    }



3. 현재 엘리먼트의 모든 패드들이 pull 모드인 경우

srcpad가 pull 모드로 동작한다는 것은 다음 엘리먼트의 sinkpad가 gst_pad_pull_range()를 통해 데이터를 가져갈 수 있도록 지원하겠다는 것을 의미합니다.


sinkpad가 pull 모드로 동작한다는 것은 gst_pad_pull_range()를 통해 이전 엘리먼트로부터 데이터를 가져오겠다는 것을 의미합니다. 


그런데 sinkpad와 srcpad가 모두 pull 모드이면 엘리먼트는 다음 엘리먼트에 종속되어 버립니다. 다음 엘리먼트가 gst_pad_pull_range()를 호출하면, 현재 엘리먼트도 gst_pad_pull_range()를 호출하여 이전 엘리먼트로부터 데이터를 가져와야 합니다. 따라서 sinkpad를 pull 모드로 설정하되 GstTask 스레드는 실행되지 않도록 합니다.


* srcpad를 pull 모드로 설정하는 방법

다음 엘리먼트의 sinkpad가 gst_pad_pull_range()를 통해 데이터를 가져갈 수 있도록 _get_range() 함수를 등록해줍니다. 


1) _get_range() 함수 오버라이딩

static void

gst_my_filter_init (GstMyFilter * filter)

{

  [...]

  gst_pad_set_getrange_function (filter->srcpad, gst_my_filter_get_range);

  [...]

}


2) 이전 엘리먼트로부터 데이터를 읽어와서 outbuf에 담고 데이터 처리

static GstFlowReturn

gst_my_filter_get_range (GstPad     * pad,

             GstObject  * parent,

             guint64      offset,

             guint        length,

             GstBuffer ** outbuf)

{


  GstMyFilter *filter = GST_MY_FILTER (parent);

  [...]

  /* pull data */

  gst_pad_pull_range (filter->sinkpad, filter->offset, BLOCKSIZE, outbuf);
  

  /* process data */
  [...]


  return GST_FLOW_OK;

}


끝.

[GStreamer] RTSP의 H264 영상 Dump 방법

GStreamer 2017.03.29 10:03 Posted by 김한별 behonestar

RTSP로 스트림되는 H264 영상을 GStreamer로 Dump하는 방법입니다. rtph264depay를 통해 출력되는 h264 데이터의 stream-format을 byte-stream으로 지정해줘야 streameye와 같은 툴로 분석이 가능합니다.


gst-launch-1.0 rtspsrc location="rtsp://media.smart-streaming.com/mytest/mp4:sample.mp4" ! rtph264depay ! video/x-h264,stream-format=byte-stream ! h264parse ! filesink location="/path/to/video.h264"



*H264 Byte Stream 포맷?

- SPS > PPS > I/P/B 슬라이스 순서로 나열됩니다.

- 각 프레임은 SCP(0x000001 또는 0x00000001)로 시작합니다.

- SCP와 SCP 사이에는 완전한 프레임 한장이 들어갑니다.

- 각 Access Unit 앞에 AUD(Access Unit Delimiter)를 넣어서 Access Unit의 시작을 표현할 수 있습니다.

 (※ HTML5 video 태그로 h264 영상을 재생할 때 AUD가 없는 영상은 재생이 안되더라구요!)




*H264 Access Unit?

- MPEG 규격의 비디오와 오디오 데이터를 다룰 때 기본 단위입니다.

- Access Unit 하나의 구조는 아래와 같습니다.

- Access Unit Delimiter는 00 00 00 01 09 xx 포맷을 따릅니다. (I: 0x10, P: 0x30)



[GStreamer] 디버깅 로그 출력하기

GStreamer 2017.03.29 09:12 Posted by 김한별 behonestar

rtspsrc 플러그인의 GST_DEBUG ()에 의해 기록되는 로그를 출력하는 방법입니다.


export GST_DEBUG=rtspsrc:DEBUG


참고

https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gst-running.html

[GStreamer] h264 profile 확인하는 방법

GStreamer 2017.03.27 20:16 Posted by 김한별 behonestar

명령어 입력

1. rtsp에서 h264 파싱 후 디코딩

2. x264enc 사용하여 h264로 재인코딩

gst-launch-1.0 -v rtspsrc location="rtsp://media.smart-streaming.com/mytest/mp4:sample.mp4" ! rtph264depay ! video/x-h264,stream-format=avc ! h264parse ! identity silent=false name=before ! avdec_h264 ! x264enc dct8x8=false cabac=false bframes=0 ! identity silent=false name=after ! mpegtsmux ! hlssink max-files=5 location=/home/ubuntu/media/playok/segment%05d.ts playlist-location=/home/ubuntu/media/playok/playlist.m3u8


실행 결과

rtsp로 전달받은 데이터는 h264 baseline 프로파일이며, x264enc로 인코딩한 데이터는 h264 main 프로파일인 것을 확인할 수 있다. 

/GstPipeline:pipeline0/GstIdentity:before: last-message = event   ******* (before:sink) E (type: tag (20510), GstTagList-stream, taglist=(taglist)"taglist\,\ video-codec\=\(string\)\"H.264\\\ \\\(Constrained\\\ Baseline\\\ Profile\\\)\"\;";) 0x7f2a0c007f40


...


/GstPipeline:pipeline0/GstIdentity:after.GstPad:src: caps = "video/x-h264\,\ stream-format\=\(string\)byte-stream\,\ alignment\=\(string\)au\,\ level\=\(string\)2.1\,\ profile\=\(string\)main\,\ width\=\(int\)424\,\ height\=\(int\)240\,\ pixel-aspect-ratio\=\(fraction\)1/1\,\ framerate\=\(fraction\)0/1"



[GStreamer] 윈도우 Visual Studio 개발 환경 설정

GStreamer 2017.03.06 19:42 Posted by 김한별 behonestar

Windows7 64bit, Visual Studio 10 기준으로 기술하였습니다.



GStreamer 1.10.4 설치

1. 다운로드 

2. gstreamer-1.0-x86_64-1.10.4.msi / gstreamer-1.0-devel-x86_64-1.10.4.msi 설치

 ※ 설치 경로를 기억하세요. 저는 D:\gstreamer에 설치하였습니다.



환경변수 등록

1. 내 컴퓨터 > 속성 > 고급시스템 설정 > 환경변수 > 시스템 변수 > Path [편집]

2. ..;D:\gstreamer\1.0\x86_64\bin 덧붙이고 [확인]


SDK 템플릿 Visual Studio로 복사

1. D:\gstreamer\1.0\x86_64\share\vs\2010\wizard의 파일 3개 복사

 - gst-sdk-template.ico

 - gst-sdk-template.vsdir

 - gst-sdk-template.vsz

2. C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcprojects에 붙여넣기

3. D:\gstreamer\1.0\x86_64\share\vs\2010\gst-template 폴더 복사

4. C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\VCWizards에 붙여넣기



Windows DDK 7.1.0 설치

1. 다운로드

2. 설치 후 경로 확인 (C:\WinDDK\7600.16385.1)



Visual Studio 10 설정

1. Visual Studio 10 실행

2. New > Project > Visual C++ > gstreamer template 선택하고 프로젝트 생성


3. 프로젝트 속성 > 구성 속성 > 디버깅 > 작업 디렉토리 > 편집 >  $(GSTREAMER_1_0_ROOT_X86_64)\bin 입력 > 확인


4. 프로젝트 속성 > 구성 속성 > C/C++ > 일반 > 추가 포함 디렉터리 > 편집에서 GStreamer 경로가 포함된 것을 확인


만약 포함되어 있지 않다면, 속성 관리자 > 프로젝트 > 기존 속성 시트 추가 > D:\gstreamer\1.0\x86_64\share\vs\2010\msvc 폴더의 x86.props(32비트) 또는 x86_64.props(64비트) 열기




5. 속성 관리자 > Debug > x86_64 > config > DDK 경로 들어간 것을 확인


6. Hello World 코드 빌드 및 실행

#include <gst/gst.h>


int main(int argc, char *argv[]) {

  GstElement *pipeline;

  GstBus *bus;

  GstMessage *msg;


  /* Initialize GStreamer */

  gst_init (&argc, &argv);


  /* Build the pipeline */

  pipeline = gst_parse_launch ("playbin uri=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm", NULL);


  /* Start playing */

  gst_element_set_state (pipeline, GST_STATE_PLAYING);


  /* Wait until error or EOS */

  bus = gst_element_get_bus (pipeline);

  msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_ERROR | GST_MESSAGE_EOS);


  /* Free resources */

  if (msg != NULL)

    gst_message_unref (msg);

  gst_object_unref (bus);

  gst_element_set_state (pipeline, GST_STATE_NULL);

  gst_object_unref (pipeline);

  return 0;

}



참고

  • https://gstreamer.freedesktop.org/documentation/installing/on-windows.html