FFmpeg을 빌드하면
FFprobe 폴더와 FFmpeg폴더가 나뉘는데, 먼저 FFprobe는
(https://ffmpeg.org/ffprobe.html 의 설명 해석해봄)
FFprobe는 멀티미디어 스트림으로부터 정보를 모으고 사람과 기계가 읽을수 있게 프린트한다. 예를 들어 이것은 멀티미디어 스트림에 의해 쓰인 컨테이너와 컨테이너 속 각 미디어 스트림의 포맷을 체크하는데 쓰일 수 있다. 만약 url이 input에 구체화되어 있다면, ffprobe는 url 컨텐츠를 open하고 조사할 것이다. 만약 url이 멀티미디어 파일로써 열릴 수 없거나 인식되지 않으면, 종료 코드가 반환될 것이다.
FFprobe는 단일 어플리케이션으로도 쓰이고 textual 필터와의 조합으로도 쓰인다(더 정교한 통계적 프로세싱이나 플로팅 등으로 수행됨)
ffprobe에 의해 지원되는 포맷을 리스팅하거나 어떤 정보를 보여줄 지 정하거나 어떻게 보여줄 지를 정하기 위해 옵션이 쓰인다.
ffprobe 산출물은 textual 필터를 통해 쉽게 읽히도록 디자인 되어있으며 print_format 옵션으로 구체화되는 writer에 의해 정의되는 form의 하나 이상의 섹션들로 구성되어 있다.
섹션들은 다른 얽혀진 섹션들을 포함하거나 유니크한 이름으로 구분된다.
컨테이너에 저장되거나 스트림에 있는 Metadata 태그들은 FORMAT, STREAM이나 PROGRAM_STREAM 섹션에 의해 인식되고 프린트 되어진다.
한줄요약: ffprobe는 간단한 멀티미디어 스트림 분석기
FFMpeg의 상위 dir들 중 fftools는 그야말로 ffmpeg을 사용하기 위한 코드들이 있으며 fftools/ffmpeg.c 에 main 함수가 있다. cmdutils에는 커맨드라인의 사용 커맨드라인
apple http steam은 순차적으로 재생되는 미디어 조각 파일들의 플레이리스트로 구성되어 있다. 하나의 비디오 컨텐츠에 대해 다른 bandwidth들에 따라 여러 플레이리스트들이 존재할 수 있으며, 한번에 하나의 bandwidth 변수로 병렬적으로 플레이된다. 이 경우에, 유저는 여러 리스트들을 가지고있는 메인 플레이리스트의 url를 제공받는다. -> master playlist에 대한 설명
KeyType
enum KeyType {
KEY_NONE,
KEY_AES_128,
KEY_SAMPLE_AES
};
Segment
struct segment {
int64_t duration;
int64_t url_offset;
int64_t size;
char *url;
char *key;
enum KeyType key_type;
uint8_t iv[16];
/* associated Media Initialization Section, treated as a segment */
struct segment *init_section;
};
하나의 조각을 표현하는 스트럭트. 지속 시간, offset, 사이즈, url 스트링, key와 key종류(보통 0->None으로 사용했던듯), iv는뭔지 아직 모르겠고 또다른 segment를 가리키는 포인터 init_section이 있다. init_section
은 첫번째 조각을 나타내는 걸까?
각각의 플레이리스트는 자기만의 demuxer를 가진다. 지금 active하다면 open AVIOContext를 가진다. 그리고 이 스트림의 다음 패킷을 가지는 AVPacket을 포함할 수 있다.
AV?
AV는 아마 Audio-Visual의 약자인 거 같은데 확실하지않다 대체 뭐라고 검색해야 정확히 나오는건지...
AVIOContext
libavformat/avio.h에 선언되어 있으며 private options를 위한 클래이스이다.
AVIOContext Struct는 Bytestream IO Context로,
libavformat의 avformat_open_input()을 호출 할 때 이 컨텍스트를 설정해서 콘텐츠의 경로를 설정할 수 있다고 한다.
이 그림은 읽거나 쓸 때 buffer, buf_ptr, buf_ptr_max, buf_end, buf_size, and pos 간의 관계를 나타낸다
Reading
Writing
간단하게 버퍼의 시작포인터, 크기, 현재 버퍼의 위치, 버퍼의 끝 위치 부터 체크썸이나 eof_reached, 파일 전체에서의 현재 버퍼의 위치 등 파일 정보를 나타낸 구조체이다.
libavformat/avio.h 에는 AVIODir~ 등 경로 설정 구조체도 있는 등 주로 버퍼나 파일 접근에 관한 내용인 것 같다.
Playlist
struct playlist {
char url[MAX_URL_SIZE];
AVIOContext pb;
uint8_t* read_buffer;
AVIOContext *input;
int input_read_done;
AVIOContext *input_next;
int input_next_requested;
AVFormatContext *parent;
int index;
AVFormatContext *ctx;
AVPacket pkt;
int has_noheader_flag;
/* main demuxer streams associated with this playlist
* indexed by the subdemuxer stream indexes */
AVStream **main_streams;
int n_main_streams;
int finished;
enum PlaylistType type;
int64_t target_duration;
int start_seq_no;
int n_segments;
struct segment **segments;
int needed;
int broken;
int cur_seq_no;
int last_seq_no;
int m3u8_hold_counters;
int64_t cur_seg_offset;
int64_t last_load_time;
/* Currently active Media Initialization Section */
struct segment *cur_init_section;
uint8_t *init_sec_buf;
unsigned int init_sec_buf_size;
unsigned int init_sec_data_len;
unsigned int init_sec_buf_read_offset;
char key_url[MAX_URL_SIZE];
uint8_t key[16];
/* ID3 timestamp handling (elementary audio streams have ID3 timestamps
* (and possibly other ID3 tags) in the beginning of each segment) */
int is_id3_timestamped; /* -1: not yet known */
int64_t id3_mpegts_timestamp; /* in mpegts tb */
int64_t id3_offset; /* in stream original tb */
uint8_t* id3_buf; /* temp buffer for id3 parsing */
unsigned int id3_buf_size;
AVDictionary *id3_initial; /* data from first id3 tag */
int id3_found; /* ID3 tag found at some point */
int id3_changed; /* ID3 tag data has changed at some point */
ID3v2ExtraMeta *id3_deferred_extra; /* stored here until subdemuxer is opened */
int64_t seek_timestamp;
int seek_flags;
int seek_stream_index; /* into subdemuxer stream array */
/* Renditions associated with this playlist, if any.
* Alternative rendition playlists have a single rendition associated
* with them, and variant main Media Playlists may have
* multiple (playlist-less) renditions associated with them. */
int n_renditions;
struct rendition **renditions;
/* Media Initialization Sections (EXT-X-MAP) associated with this
* playlist, if any. */
int n_init_sections;
struct segment **init_sections;
};
플레이리스트 구조체에는 url, AVIOContext 부터 현재/마지막 시퀀스번호 부터 현재 실행중인 미디어 섹션의 정보 등 플레이리스트와 관련된 정보들이 있다.
struct rendition {
enum AVMediaType type;
struct playlist *playlist;
char group_id[MAX_FIELD_LEN];
char language[MAX_FIELD_LEN];
char name[MAX_FIELD_LEN];
int disposition;
};
rendition은 외부적인 플레이리스트이거나 플레이리스트가 NULL인 경우 메인 플레이리스트에 포함되어 있다. Rendition은 subtitle이나 audio stream의 대체제이다.
미디어타입, 플레이리스트, 언어, 이름 등으로 구성되어있다.
struct variant {
int bandwidth;
/* every variant contains at least the main Media Playlist in index 0 */
int n_playlists;
struct playlist **playlists;
char audio_group[MAX_FIELD_LEN];
char video_group[MAX_FIELD_LEN];
char subtitles_group[MAX_FIELD_LEN];
};
variant struct는 bandwidth 정보를 포함하며, 적어도 메인 미디어 플레이리스트를 가지고 있다.