2013-01-18 2 views
2

저는 컴퓨터간에 인코딩/디코딩 및 스트리밍 비디오에 대한 연구를 해오 고 있습니다. 파일에서 스트림으로의 파이프 라인을 상당히 잘 이해 한 것처럼 느낍니다. 컨테이너를 열고 개별 프레임과 오디오 청크를 디코딩하고 잡을 수 있으며 네트워크를 통해 프레임을 이동하는 것이 단순히 원시 데이터와 비효율적 인 바이트 데이터를 보내는 것처럼 쉽습니다. 내가 이해하지 못하는 것은 그것이 실제로 어떻게 연주되었는지입니다. 프레임을 일부 이미지 상자에 쓰고 사운드 카드 버퍼에서 오디오 데이터를 제거하는 것은 실제로 잘 작동하지 않습니다. 아무도 나에게 정확히 그들이 무슨 CPU와 메모리를 파괴하지 않고 화면에이 프레임 데이터를 보낼 수있는 Windows Media Player와 같은 프로그램에서 무슨 일이 일어 났는지 설명 할 수 있습니까? 그냥 일반 아이디어 또는 일부 높은 수준의 문서가 좋을 것입니다. 어디서부터 시작해야할지 모르겠다. ...비디오 플레이어는 프레임 데이터를 화면에 어떻게 기록합니까?

고마워!

+0

VLC는 오픈 소스가 아닙니까? 당신은 그것을 확인할 수 있었다 :) –

+1

나는 방금 포켓 PC에 mpeg lib로 어떻게 그것을했는지 기억했다. 그리고 그것은 당신이 묘사 한 것과 같았습니다. 2D 라이브러리를 사용하여 서페이스를 열고 프레임 비트를 서페이스로 복사 한 다음 화면에 뒤집습니다. 이제 당장 두 개의 프레임을 버퍼링하거나 프레임간에 보간하는 것과 같은 깔끔한 작업을 수행 할 수 있습니다. 그러나 나는이 시점에서 화면에 픽셀을 가져 오는 것보다 훨씬 더 많은 마법이 있다고 생각하지 않습니다. – dowhilefor

+0

이미지를 그려 오디오 데이터를 오디오 - 비디오 시간 동기화와 함께 넣습니다. – 9dan

답변

1

OpenGL을 사용하는 경우 텍스처를 만들고 끊임없이 새 프레임 데이터로 바꿀 수 있습니다. 매우 비싼 작업은 아닙니다. 그런 다음 윈도우에 질감 사각형을 그립니다. glOrtho이 유용합니다.

Windows에서 DirectX 또는 Direct3D를 사용하는 경우 동일한 종류의 것이 적용됩니다. DIB 섹션 (GDI)을 블리 팅하면 좋은 성능을 얻을 수도 있습니다. Fastest method for blitting from a pixel buffer into a device context

픽셀을 그리는 방법에 관계없이 업데이트 타이머를 설정하면 간단합니다.

원활하게 작동하려면 디스크 (또는 네트워크) 및 디코딩 지연이 실시간 드로잉에 영향을주지 않도록 드로잉보다 먼저 버퍼링해야합니다. 심지어 비디오에서 가장 작은 갑작스러운 점도 인간에 의해 감지 될 수 있습니다. 타이머가 작동하면 픽셀을 이미지 버퍼에서 디코딩하여 그릴 준비가 필요합니다.

+1

+1하지만 Windows에서'bitblt'-ing은 발생하는 불행한 부작용이 있습니다 ([tearing] http://stackoverflow.com/questions/2448831/how-to-eliminate-tearing-from-animation). 이미지 업데이트가 새로 고침 될 때마다 불행히도 찢어지지 않도록 직접 API 또는 최신 API를 사용해야합니다. – MusiGenesis

+0

그래, 내가 조립할 때 블리치 루틴을 써서 내 이빨을 자르다가 찢어지는 것을 기억한다. =) 나는 VSync를 기다리는 oldschool 메서드가 적용되지 않을 것이라고 생각한다. 당신의 의견을 보내 주셔서 감사합니다. – paddy

+0

오래 전에 플레이어를 쓴이 정확한 문제에 부딪 혔습니다. DirectX를 사용하여 v-sync 이벤트 (DirectX가 노출되는 시간)를 측정하는 데 관련된 이상한 해결 방법을 생각해 냈습니다. v-syncs의 타이밍을 거의 완벽하게 유지하기 때문에 몇 가지 이벤트를 등록하면됩니다. 애니메이션 엔진에서 양쪽 프레임의 동기화가 몇 밀리 초 이내에 이루어지면 프레임을 렌더링하지 않아도됩니다. 대신에 직후까지 지연됩니다. 그것은 작동하지만 그것은 현명하게 바보입니다. DirectX를 사용한다면 DirectX를 사용할 수도 있습니다. – MusiGenesis

1

저는 비디오와 오디오를 결합하고 둘 사이의 정확한 동기화가 필요한 다수의 플레이어 응용 프로그램 (Windows 용)을 작성했습니다. Windows 오디오에서는 기본적으로 오디오 샘플 값의 배열 인 버퍼를 준비하고 재생을 위해 오디오 하위 시스템에 대기시킵니다. 서브 시스템은 각 버퍼가 재생을 완료 할 때마다 앱에 콜백을 만들고 앱은 각 콜백을 사용하여 다음 프레임을 화면에 렌더링하고 2) 오디오 하위 시스템에 대기 할 다음 오디오 청크를 준비합니다.

예를 들어, 초당 50 프레임, 모노, 2 바이트 샘플 및 44,100 샘플/초의 오디오와 동기화하여 비디오의 일부 프레임이 메모리에 있다고 가정 해 봅시다. 즉, 오디오 버퍼의 크기는 각각 882 샘플 (44,100/50 = 882)이어야하므로 각 버퍼는 882 개 요소의 짧은 (2 바이트) 정수 배열입니다. 적어도 두 개의 버퍼가 필요하지만 실제로는 더 좋습니다. 버퍼가 많으면 많을수록 재생 지연이 길어지고 메모리 공간이 커진다는 단점이 있습니다.

적어도 하나의 프레임을 항상 렌더링 할 준비가되도록 동일한 방식으로 비디오 프레임을 "버퍼링"해야합니다. 하나의 이미지를 PC 화면으로 전송하는 속도가 너무 빨라 사실상 순간적으로 걱정할 필요가 없습니다. 유일한 관심사는 프레임을 추출하거나 합성하는 모든 방법에 있습니다. 이러한 방법은 재생 속도를 따라 잡을 수있을만큼 빨라야하거나 재생 전에 미리 버퍼링해야하기 때문에 시작 지연이 길어지고 메모리 공간이 커집니다 (이러한 문제는 비디오보다 훨씬 나쁩니다. 그들은 합리적인 해결책으로 오디오 용입니다).

앱이 재생을 시작하면 모든 버퍼에 오디오가 사전로드되고 재생을 위해 대기합니다. 그런 다음 동시에 재생을 시작하고 첫 번째 프레임을 화면에 렌더링합니다. 사용자는 첫 번째 프레임을보고 오디오의 처음 20ms (20ms = 1/50 초)를 듣습니다.이 시점에서 오디오 하위 시스템은 첫 번째 버퍼에서 두 번째 버퍼로 재생을 전환하고 응용 프로그램에 대한 콜백을 수행합니다. 그런 다음 응용 프로그램은 두 번째 프레임을 화면에 렌더링하고 첫 번째 버퍼를 사용 가능한 다음 청크로 채운 다음이 첫 번째 버퍼를 다시 오디오 하위 시스템에 대기시킵니다.

응용 프로그램에서 버퍼 및 프레임을 채우는 데 사용할 수있는 오디오 및 비디오 데이터가있는 경우이 프로세스가 계속되고 비디오를 보거나들을 수 있습니다.

관련 문제