Theory/Multimedia

멀티미디어 서비스를 위한 얕은 지식

멀티미디어의 특징

데이터가 매우 크다.

문자 데이터와 비교하면 비디오나 오디오 데이터는 엄청나가 크다.

24-bit, 1080p @ 60 fps: 24 × 1920×1080 × 60 = 2.98 Gbit/s.

출처 : Wikidepia, Uncompressed video

방대한 분량의 자료를 저장하고 전송하는 기술이 요구된다.


시간에 민감하다.

멀티미디어 정보의 유효성은 시간과 밀접하다.
시간내에 처리되지 않으면 정보의 품질이 급격히 떨어진다.
실시간 처리와 네트워크 서비스 품질(QoS)이 필요하고
각 매채간의 상호 동기를 해결해야 한다.


인간의 오감으로 수용하는 데이터이다.

멀티미디어는 궁극적으로 인간의 오감(대부분 시각과 청각)으로 수용된다.
이로 인해 약간의 오류를 허용하는 특징이 있다.
이를 활용한 압축과 오류 보정/은닉 기법이 요구된다.


기술적인 도전

멀티미디어 압축

방대한 분량을 저장하고 전송하려면 크기를 줄여야 한다.
이때 사용하는 기술이 압축(compression)이다.
압축의 기본 원리는 중복 데이터 제거이다.
위 원리와 더불어, 멀티미디어 압축은 덜 민감하거나 인식하기 어려운 부분까지 제거한다.[각주:1]


파일 시스템과 RAID, Object Storage

멀티미디어는 시간적인 연속성이 있는 대용량 데이터라는 특징이 있다.
가능하면 큰 블록들이 연속되어 있는 것이 더 효과적이다.
멀티미디어는 약간의 오류를 허용하기 때문에 오류 탐지와 보정 기능이 매우 강력할 필요는 없다.
높은 대역폭을 제공하기 위해 대용량 객체의 병렬 입출력이 요구된다.


네트워크 서비스 품질 (QoS: Quality of Service)

높은 대역폭과 실시간적 특성을 해결해야 한다.
인터넷의 best-effort 정책은 문자 데이터는 괜찮지만,
멀티미디어 전송에는 적합하지 않다.
멀티미디어 전송을 위해서는
- 네트워크 자원을 예약할 수 있어야 하고,
- 특정 프로그램이 필요 이상으로 점유하는 것을 막아야 한다.


캐싱(Caching)과 버퍼링(Buffering)

캐싱과 버퍼링은 이차 저장소의 지연과 오버헤드를 피하기 위해
접근과 읽기가 빠른 일차 저장소를 사용하는 것이다.
방대한 분량을 지연 없이 효과적으로 전송하기 위해서 필요한 기술이다.
전자는 공유 저장 장치에 읽은 부분을 저장하고,
후자는 자신의 저장 장치에 다음 부분을 미리 가져온다.


FEC(Forward Error Correction)

재전송 기법을 사용 할 수 없거나 시간이 중요할 경우에 오류를 해소하는 방법이다.
멀티케스팅이나 무선 환경에서 주로 사용한다.


멀티케스팅(multicasting)

같은 데이터를 여럿이 동시에 받는 상황에서
높은 대역폭을 효과적으로 처리하는 방법이다.
멀티캐스트는 소스로부터 패킷을 한 번만 전송한다.
네트워크에서 필요한 경우에만 여러 수신자에 도달하는 패킷을 복제한다.
라이브 서비스처럼 하나가 송신하고 다수가 수신하는 경우 네트워크를 효율적으로 사용할 수 있다.


이 글은 대강의 큰 그림을 보여준다.
이외에도 알아야 하는 것은 정말 많고
각각에 대한 깊은 이해도 필요하다.
연극이나 영화가 종합 예술이라면
멀티미디어 서비스는 종합 기술이고 할 수 있다.
이 글이 멀티미디어 서비스에 입문하려는 분들께 도움이 되기를 희망한다.

  1. 오감으로 수용하는 데이터라는 특징이 여기서 활용된다. [본문으로]
Practice/Python, Perl

Emacs의 Python3 개발 환경

emacs의 python 개발 환경은 크게 두 가지가 유명하다.
하나는 elpy 나머지 하나는 anaconda이다.

이 두가지 중에 하나를 선택해서 사용한다.


elpy

한마디로, emacs에서 python 개발을 위한 all in one 패키지이다.
설치와 설정이 매우 쉬운면서 여느 IDE와 견주어도 꿀리지 않는 강력함이 있다.

(use-package elpy
  :ensure t
  :config
  (elpy-enable)
  (setq elpy-rpc-python-command "python3")
  (setq elpy-rpc-backend "jedi")
  (elpy-use-cpython (or (executable-find "python3")
                        (executable-find "/usr/bin/python3")
                        (executable-find "/usr/local/bin/python3")
                        "python3"))
  ;; (elpy-use-ipython)
  (setq python-shell-interpreter-args "--simple-prompt -i")
  (add-hook 'python-mode-hook (lambda ()
                              (setq indent-tabs-mode nil))))

(use-package ein
  :ensure t)


anaconda

anaconda 최대한 작은 것을 지향한다.
elpy가 자동으로 해주던 것을 일일이 설치하고 설정해야 한다.

python-mode

(use-package python
  :mode ("\\.py\\'" . python-mode)
        ("\\.wsgi$" . python-mode)
  :interpreter ("python" . python-mode)

  :init
  (setq-default indent-tabs-mode nil)

  :config
  (setq python-indent-offset 4)
  ;; TODO pyvenv
  (setq flycheck-python-pycompile-executable
        (or (executable-find "python3")
            (executable-find "/usr/bin/python3")
            (executable-find "/usr/local/bin/python3")
            "python"))
  (setq flycheck-python-pylint-executable
        (or (executable-find "pylint3")
            (executable-find "/usr/bin/pylint3")
            (executable-find "/usr/local/bin/pylint3")
            "pyline"))
  (setq flycheck-python-flake8-executable
        (or (executable-find "flake8")
            (executable-find "/usr/bin/flake8")
            (executable-find "/usr/local/bin/flake8")
            "flake8")))

anaconda-mode

(use-package anaconda-mode
  :ensure t
  :diminish anaconda-mode
  :defer t
  :init (progn
          (add-hook 'python-mode-hook #'anaconda-mode)
          (add-hook 'python-mode-hook #'anaconda-eldoc-mode)))

(use-package company-anaconda
  :ensure t
  :commands (company-anaconda)
  :after company
  :init (add-to-list 'company-backends #'company-anaconda))

unit test

(use-package nose
  :commands (nosetests-one
             nosetests-pdb-one
             nosetests-all
             nosetests-pdb-all
             nosetests-module
             nosetests-pdb-module
             nosetests-suite
             nosetests-pdb-suite)
  :config
  (progn
    (add-to-list 'nose-project-root-files "setup.cfg")
    (setq nose-use-verbose nil)))

(use-package pytest
  :commands (pytest-one
             pytest-pdb-one
             pytest-all
             pytest-pdb-all
             pytest-module
             pytest-pdb-module)
  :config (add-to-list 'pytest-project-root-files "setup.cfg"))

virtualenv

(use-package pyenv-mode
  :if (executable-find "pyenv")
  :commands (pyenv-mode-versions))

(use-package pyvenv
  :defer t)


Practice/Emacs

Emacs의 Programming 관련 공통 설정

elpa

(require 'package)
(add-to-list 'package-archives
             '("melpa" . "https://melpa.org/packages/"))
(add-to-list 'package-archives
             '("melpa-stable" . "http://melpa-stable.milkbox.net/packages/"))
(setq package-enable-at-startup nil)
(setq package-archive-priorities '(("melpa-stable" . 1)))
(package-initialize)

use-package

(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))

(setq use-package-verbose t)
(setq use-package-always-bin "melpa-stable")

(eval-when-compile
  (require 'use-package))

flycheck

(use-package flycheck
  :ensure t
  :diminish flycheck-mode
  :commands flycheck-mode
  :init (global-flycheck-mode)
  :config
  (setq flycheck-check-syntax-automatically '(save idle-change mode-enabled)
        flycheck-idle-change-delay 5.0))

helm

(use-package helm
  :ensure t
  :diminish helm-mode
  :bind (("C-c h" . helm-mini)
         ("C-h a" . helm-apropos)
         ;; ("C-x C-b" . helm-buffers-list)
         ;; ("C-x b" . helm-buffers-list)
         ("M-y" . helm-show-kill-ring)
         ("M-x" . helm-M-x)
         ("C-x c o" . helm-occur)
         ("C-x c s" . helm-swoop)
         ("C-x c y" . helm-yas-complete)
         ("C-x c Y" . helm-yas-create-snippet-on-region)
         ("C-x c b" . my/helm-do-grep-book-notes)
         ("C-x c SPC" . helm-all-mark-rings)
         ("C-x C-o" . ffap))
  :init
  (require 'helm-config)
  (setq helm-candidate-number-limit 100)
  (setq helm-yas-display-key-on-candidate t)
  ;; for pretty fast updates when hitting RET too quickly
  ;; after typing fast:
  (setq helm-idle-delay 0.0 ; update fast sources immediately (doesn't).
        helm-input-idle-delay 0.01  ; this actually updates things
                                        ; reeeelatively quickly.
        helm-quick-update t
        helm-M-x-requires-pattern nil
        helm-ff-skip-boring-files t)
  :config
  (use-package helm-descbinds
    :ensure t
    :config (helm-descbinds-mode)))

projectile

(use-package projectile
  :ensure t
  :diminish projectile-mode
  :config
  (setq projectile-enable-caching t
        projectile-indexing-method 'alien
        projectile-completion-system 'helm
        projectile-switch-project-action 'helm-projectile)
  ;; https://github.com/bbatsov/projectile/issues/1183
  (setq projectile-mode-line
        '(:eval (format " Projectile[%s]"
                        (projectile-project-name))))
  (projectile-global-mode))

(use-package helm-projectile
  :ensure t
  :commands (helm-projectile)
  :after helm
  :config (helm-projectile-on))

company

(use-package company
  :ensure t
  :diminish company-mode
  :commands (company-complete company-mode)
  :bind (([remap dabbrev-expand] . company-complete)
         :map prog-mode-map
         ([tab] . company-indent-or-complete-common))
  :init (if (fboundp 'evil-declare-change-repeat)
            (mapc #'evil-declare-change-repeat
                  '(company-complete-common
                    company-select-next
                    company-select-previous
                    company-complete-selection
                    company-complete-number)))
  ;; (add-hook 'after-init-hook 'global-company-mode)
  :config
  (use-package company-statistics
              :ensure t
              :init
              (company-statistics-mode))
  (setq company-idle-delay 0)
  (setq company-show-numbers "on")
  (add-hook 'prog-mode-hook 'company-mode))
Practice/Lisp, Scala

Emacs의 Scala 개발 환경

sbt 설치

Ubuntu에서 sbt 0.13.15 설치하기

curl -L -o sbt.deb http://dl.bintray.com/sbt/debian/sbt-0.13.15.deb
sudo dpkg -i sbt.deb
sudo apt-get update
sudo apt-get install sbt

sbt 설정하기

~/.sbt/0.13/plugins/plugins.sbt 파일을 편집한다.

addSbtPlugin("org.ensime" % "sbt-ensime" % "1.12.14")


프로젝트 만들기

편의상, 프로젝트 디렉토리를 '~/my-project'로 가정한다.
'~/my-project/project/build.properties' 파일에 프로젝트에 sbt 버젼을 명시한다.

sbt.version=0.13.15

아래 명령으로 프로젝트를 위한 '.ensime' 파일을 생성한다.

cd ~/my-project
sbt ensimeConfig


Emacs 설정

Emacs의 Programming 관련 공통 설정

(use-package ensime
  :ensure t)

(use-package scala-mode
  :interpreter
  ("scala" . scala-mode)
  :config
  (add-hook 'scala-mode-hook 'ensime-scala-mode-hook))

(use-package sbt-mode
  :commands sbt-start sbt-command
  :config
  ;; WORKAROUND: https://github.com/ensime/emacs-sbt-mode/issues/31
  ;; allows using SPACE when in the minibuffer
  (substitute-key-definition 'minibuffer-complete-word
                             'self-insert-command
                             minibuffer-local-completion-map))


Ensime 시작하기

프로젝트의 파일이나 디렉토리에서, 아래 이맥스 명령어를 입력한다.

M-x ensime


참고 링크


Practice/C, C++, Java, C#

C++에서 언제 어떻게 struct를 사용하는가?

C++로 코딩할 때에 class와 struct 중에 무엇을 사용할 지 고민을 할 때가 있다.
내가 C++에서 struct를 선택하는 기준은 다음과 같다.

  • 분해하면 모든 멤버 변수가 scala data type이다.
    멤버 변수 중에 union, struct 또는 고정 길이 array를 만다면 재귀적으로 분해한다.
    모든 말단이 scala data type으로 이루어졌다면 struct를 사용한다.
    즉, 분해하는 과정에서 포인터나 가변 길이 배열, 클래스를 만나면 struct를 사용하지 않는다.
  • 구조체를 이진 데이타로 고스란히 pack/unpack 해야 한다.
    struct는 메모리 형태 그대로 데이터로 상호 변환 가능함으로 개발하기 편하다.
    굳이 별도의 pack/unpack 함수를 작성할 필요가 없다.
    이와 같은 용도의 struct를 만들 때에는, 데이터 구조체 정렬(data structure alignment)를 주의한다.[각주:1]
  • 모든 멤버 변수를 외부에 공개할 수 있다.
    반대로 외부에 공개할 필요가 없는-예를 들여, 구현의 변경에 따라서 얼마든지 바뀔 수 있는 구현 의존적인- 멤버 변수가 있다면 class로의 구현을 고민한다.[각주:2]


비록 C++의 struct가 기본 접근 속성이 다른 class의 변종 정도지만,
되도록 C의 그것과 동일한 의미로 사용되도록 작성하는 편이다.
그렇게 하기 위해서는 아래 제약 사항을 지켜야 한다.

  • 상속(inheritance)을 받지 않았다.
    상속은 메모리 구성을 보장하지 않는다.
    상속이 필요하면 구성(composition)으로 해결한다.
    상속받을 struct를 대개 첫번째 멤버 변수로 등록한다.
  • 멤버 함수를 만들지 않는다.
    생성, 초기화, 복사, 할당은 대개 변수의 선언이나 메모리 초기화/복사 등으로 구현한다.
    다른 연관 함수들은 전역 함수 내지는 별도의 구현 class를 이용하여 작성한다.


  1. 이에 관해서는 "C언어에서 struct 정의 그대로 이진 데이터로 만들기"를 참고한다. [본문으로]
  2. 외부 공개용 struct와 내부 구현용 struct/class로 분리하는 전략도 있음으로 반드시 class를 선택할 필요는 없다. [본문으로]
  1. Favicon of http://moneycoach.kr/ 소액결제 현금화 M/D Reply

    관리자의 승인을 기다리고 있는 댓글입니다

  2. Favicon of http://www.joyalba.com 알바 . M/D Reply

    관리자의 승인을 기다리고 있는 댓글입니다

알림

이 블로그는 구글에서 제공한 크롬에 최적화 되어있고, 네이버에서 제공한 나눔글꼴이 적용되어 있습니다.

카운터

Today : 10
Yesterday : 147
Total : 202,573