📄 fssapmp4parser.cpp
字号:
leng = wcslen(str_wchar);
for (i=j=0; i<leng; i++, j++)
{
c = str_wchar[i];
if (c == 0) {
str_char[j] = '\0';
break;
}
else if (c < 0x80) {
str_char[j] = (char)str_wchar[i];
}
else {
// Currently the non-alphanumeric characters are not supported.
str_char[j] = '\0';
break;
}
}
str_char[j] = '\0';
}
//
// ReadTheFile
//
HRESULT CMP4ParserFilter::CheckFile(LPCTSTR pszFileName)
{
char *video_name, *audio_name;
char filename[256];
///////////////////////////////////////////////
///// /////
///// 1. Open the mp4 file for reading. /////
///// /////
///////////////////////////////////////////////
wchar_t2char(pszFileName, filename);
//printf("\n(CMP4ParserFilter::CheckFile) filename=%s.", filename);
// m_hMP4File = MP4Read(filename, 0);
RETAILMSG(1, (L"\n(CMP4ParserFilter::CheckFile) filename=%s.", pszFileName));
m_hMP4File = MP4ReadWchar(pszFileName, 0);
if (!m_hMP4File)
return E_FAIL;
RETAILMSG(1, (L"\n MP4Read succeed.."));
/////////////////////////////////////////////////////////
///// /////
///// 2. Identify the video & get its properties. /////
///// /////
/////////////////////////////////////////////////////////
m_video_trId = MP4FindTrackId(m_hMP4File, 0, MP4_VIDEO_TRACK_TYPE, 0);
if (m_video_trId != MP4_INVALID_TRACK_ID) {
video_name = (char *) MP4GetTrackMediaDataName(m_hMP4File, m_video_trId);
if (strcmp(video_name, "mp4v") == 0)
m_video_codec = RAW_STRM_TYPE_M4V; // MPEG4
else if (strcmp(video_name, "s263") == 0)
m_video_codec = RAW_STRM_TYPE_H263; // H.263
else if (strcmp(video_name, "avc1") == 0)
m_video_codec = RAW_STRM_TYPE_H264RAW; // H.264
else
m_video_codec = 4; // Unknown
// Timescale (ticks per second) and duration of the Video track
m_video_timescale = MP4GetTrackTimeScale(m_hMP4File, m_video_trId);
m_video_duration = MP4GetTrackDuration(m_hMP4File, m_video_trId);
// Number of video samples, video frame rate
m_video_num_samples = MP4GetTrackNumberOfSamples(m_hMP4File, m_video_trId);
m_video_framerate = MP4GetTrackVideoFrameRate(m_hMP4File, m_video_trId);
m_video_sample_max_size = MP4GetTrackMaxSampleSize(m_hMP4File, m_video_trId);
// video width and height information is extracted from 'tkhd' header.
// But this information is often wrong.
// Therefore, the size information is obtained from "Video Header" directly.
// m_video_width = MP4GetTrackVideoWidth(m_hMP4File, m_video_trId);
// m_video_height = MP4GetTrackVideoHeight(m_hMP4File, m_video_trId);
GetVideoProfileAndSize(m_hMP4File, m_video_trId, m_video_codec,
&m_video_profile, &m_video_width, &m_video_height);
if (m_video_codec == RAW_STRM_TYPE_H264RAW) {
if (MP4GetTrackH264LengthSize(m_hMP4File, m_video_trId, &m_h264_bufleng_size)) {
m_h264_tmp_buf = (unsigned char *) malloc(m_video_sample_max_size + 128); // 128 : for SPS+PPS
}
else {
m_h264_bufleng_size = 4;
if (m_h264_tmp_buf) {
free(m_h264_tmp_buf);
m_h264_tmp_buf = NULL;
}
}
}
}
/////////////////////////////////////////////////////////
///// /////
///// 3. Identify the audio & get its properties. /////
///// /////
/////////////////////////////////////////////////////////
m_audio_trId = MP4FindTrackId(m_hMP4File, 0, MP4_AUDIO_TRACK_TYPE, 0);
if (m_audio_trId != MP4_INVALID_TRACK_ID) {
audio_name = (char *) MP4GetTrackMediaDataName(m_hMP4File, m_audio_trId);
if (strcmp(audio_name, "mp4a") == 0)
m_audio_codec = RAW_STRM_TYPE_M4A; // MPEG4 AAC
else if (strcmp(audio_name, "samr") == 0)
m_audio_codec = RAW_STRM_TYPE_AMR_NB; // AMR-NB
else {
printf("\n !! Unknown Audio (%s) !!\n", audio_name);
m_audio_codec = 4; // Unknown
}
// Timescale (ticks per second) and duration of the Video track
m_audio_timescale = MP4GetTrackTimeScale(m_hMP4File, m_audio_trId);
m_audio_duration = MP4GetTrackDuration(m_hMP4File, m_audio_trId);
// Number of video samples, video width, video height, video frame rate
m_audio_num_samples = MP4GetTrackNumberOfSamples(m_hMP4File, m_audio_trId);
m_audio_num_channels = 2;//MP4GetTrackAudioChannels(m_hMP4File, m_audio_trId);
m_audio_sample_max_size = MP4GetTrackMaxSampleSize(m_hMP4File, m_audio_trId);
printf("\n m_audio_trId = %d, m_audio_duration = (%d), m_audio_timescale = (%d) !!\n", m_audio_trId, m_audio_duration, m_audio_timescale);
}
return S_OK;
}
//
// MakeVideoMediaType
//
HRESULT CMP4ParserFilter::MakeVideoMediaType(CMediaType *pMediaType)
{
unsigned int *size;
pMediaType->InitMediaType();
pMediaType->SetType(&MEDIATYPE_Stream);
switch (m_video_codec) {
case RAW_STRM_TYPE_M4V:
case RAW_STRM_TYPE_H263:
pMediaType->SetSubtype(&MEDIASUBTYPE_m4v);
break;
case RAW_STRM_TYPE_H264RAW:
pMediaType->SetSubtype(&MEDIASUBTYPE_h264raw);
break;
default:
RETAILMSG(1, (L"[SSAP MP4Parser]unsupported file type\n"));
return E_FAIL;
}
size = (unsigned int *) pMediaType->ReallocFormatBuffer(sizeof(unsigned int) * 2);
size[0] = m_video_width;
size[1] = m_video_height;
pMediaType->SetFormat((BYTE *)size, sizeof(unsigned int) * 2);
return S_OK;
}
//
// MakeAudioMediaType
//
HRESULT CMP4ParserFilter::MakeAudioMediaType(CMediaType *pMediaType)
{
WAVEFORMATEX *wfe;
unsigned char strm_hdr_buf[128];
int strm_hdr_leng;
pMediaType->InitMediaType();
// pMediaType->SetType(&MEDIATYPE_Stream);
pMediaType->SetType(&MEDIATYPE_Audio);
switch (m_audio_codec) {
case RAW_STRM_TYPE_M4A:
// pMediaType->SetSubtype(&MEDIASUBTYPE_m4a);
pMediaType->SetSubtype(&MEDIASUBTYPE_EAACPLUS);
break;
case RAW_STRM_TYPE_AMR_NB:
pMediaType->SetSubtype(&MEDIASUBTYPE_AmrDec);
break;
default:
RETAILMSG(1, (L"[SSAP MP4Parser]unsupported file type\n"));
return E_FAIL;
}
// Audio stream header
strm_hdr_leng = sizeof(strm_hdr_buf);
if (GetAudioStreamHeader(m_hMP4File, m_audio_trId, m_audio_codec, strm_hdr_buf, &strm_hdr_leng) != 0)
return E_FAIL;
wfe = (WAVEFORMATEX *) pMediaType->ReallocFormatBuffer(sizeof(WAVEFORMATEX) + strm_hdr_leng);
memset(wfe, 0, sizeof(WAVEFORMATEX) + strm_hdr_leng);
// wfe->wFormatTag = ;
wfe->nSamplesPerSec = m_audio_timescale;
wfe->nChannels = m_audio_num_channels;
wfe->cbSize = strm_hdr_leng;
wfe->wBitsPerSample = 16;
memcpy(wfe + 1, strm_hdr_buf, strm_hdr_leng);
pMediaType->SetFormat((BYTE *)wfe, sizeof(WAVEFORMATEX) + wfe->cbSize);
return S_OK;
}
static int GetVideoStreamHeader(MP4FileHandle mp4File, MP4TrackId video_trId, int video_codec,
unsigned char *strm_hdr_buf, int *strm_hdr_leng)
{
int b;
// for MPEG4
u_int8_t *p_video_conf;
u_int32_t n_video_conf;
// for H.264
u_int8_t **pp_sps, **pp_pps;
u_int32_t *pn_sps, *pn_pps;
u_int32_t n_strm_size;
int i;
switch (video_codec) {
case RAW_STRM_TYPE_M4V: // MPEG4
p_video_conf = NULL;
n_video_conf = 0;
b = MP4GetTrackESConfiguration(mp4File, video_trId,
&p_video_conf, &n_video_conf);
if (!b)
return -1;
memcpy(strm_hdr_buf, p_video_conf, n_video_conf);
free(p_video_conf);
*strm_hdr_leng = n_video_conf;
break;
case RAW_STRM_TYPE_H263: // H.263
*strm_hdr_leng = 0;
break;
case RAW_STRM_TYPE_H264RAW: // H.264
pp_sps = pp_pps = NULL;
pn_sps = pn_pps = NULL;
n_strm_size = 0;
b = MP4GetTrackH264SeqPictHeaders(mp4File, video_trId, &pp_sps, &pn_sps, &pp_pps, &pn_pps);
if (!b)
return -1;
// SPS memcpy
if (pp_sps) {
for (i=0; *(pp_sps + i); i++) {
memcpy(strm_hdr_buf + n_strm_size, h264_delimiter, sizeof(h264_delimiter));
n_strm_size += sizeof(h264_delimiter);
memcpy(strm_hdr_buf + n_strm_size, *(pp_sps + i), *(pn_sps + i));
/*
if (NAL_UNIT_TYPE_TYPE(strm_hdr_buf[n_strm_size]) == 7) {
strm_hdr_buf[n_strm_size + 1] = 66;
}
*/
n_strm_size += *(pn_sps + i);
free(*(pp_sps + i));
}
free(pp_sps);
}
// PPS memcpy
if (pp_pps) {
for (i=0; *(pp_pps + i); i++) {
memcpy(strm_hdr_buf + n_strm_size, h264_delimiter, sizeof(h264_delimiter));
n_strm_size += sizeof(h264_delimiter);
memcpy(strm_hdr_buf + n_strm_size, *(pp_pps + i), *(pn_pps + i));
n_strm_size += *(pn_pps + i);
free(*(pp_pps + i));
}
free(pp_pps);
}
*strm_hdr_leng = n_strm_size;
break;
default: // Unknown
*strm_hdr_leng = 0;
break;
}
return 0;
}
static int GetAudioStreamHeader(MP4FileHandle mp4File, MP4TrackId audio_trId, int audio_codec,
unsigned char *strm_hdr_buf, int *strm_hdr_leng)
{
int b;
// for MPEG4
u_int32_t n_audio_conf;
u_int8_t *p_audio_conf;
// for AMR-NB
u_int16_t amr_mode_set;
switch (audio_codec) {
case RAW_STRM_TYPE_M4A:
p_audio_conf = NULL;
n_audio_conf = 0;
b = MP4GetTrackESConfiguration(mp4File, audio_trId, &p_audio_conf, &n_audio_conf);
if (!b)
return -1;
memcpy(strm_hdr_buf, p_audio_conf, n_audio_conf);
*strm_hdr_leng = n_audio_conf;
free(p_audio_conf);
break;
case RAW_STRM_TYPE_AMR_NB:
amr_mode_set = MP4GetAmrModeSet(mp4File, audio_trId);
strm_hdr_buf[0] = (unsigned char) amr_mode_set;
strm_hdr_buf[1] = (unsigned char) (amr_mode_set >> 8);
*strm_hdr_leng = 2;
break;
default:
RETAILMSG(1, (L"[SSAP MP4Parser]unsupported file type\n"));
return E_FAIL;
}
return 0;
}
static int GetVideoProfileAndSize(MP4FileHandle mp4File, MP4TrackId video_trId, int video_codec,
int *profile, int *width, int *height)
{
int b, ret;
unsigned char strm_hdr_buf[512];
int strm_hdr_leng;
u_int8_t *p_video_sample=NULL;
u_int32_t n_video_sample=0;
if (RAW_STRM_TYPE_H263 == video_codec) {
b = MP4ReadSample(mp4File, video_trId, 1/*sample_id=1*/,
&p_video_sample, &n_video_sample,
NULL, NULL, NULL, NULL);
ret = get_h263_info(p_video_sample, n_video_sample, profile, width, height);
free(p_video_sample);
}
else if (RAW_STRM_TYPE_M4V == video_codec) {
strm_hdr_leng = sizeof(strm_hdr_buf);
ret = GetVideoStreamHeader(mp4File, video_trId, video_codec,
strm_hdr_buf, &strm_hdr_leng);
// Profile and size information are directly obtained from the video stream header.
ret = get_mpeg4_info(strm_hdr_buf, strm_hdr_leng, profile, width, height);
}
else if (RAW_STRM_TYPE_H264RAW == video_codec) {
strm_hdr_leng = sizeof(strm_hdr_buf);
ret = GetVideoStreamHeader(mp4File, video_trId, video_codec,
strm_hdr_buf, &strm_hdr_leng);
// Profile and size information are directly obtained from the video stream header.
ret = get_h264_info(strm_hdr_buf, strm_hdr_leng, profile, width, height);
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -