//-----------------------------------------------------------------------------
//
// MONOGRAM Multimedia FLV Mux
//
// Author : Igor Janos
//
//-----------------------------------------------------------------------------
#include "stdafx.h"
//-------------------------------------------------------------------------
//
// ExtraData
//
//-------------------------------------------------------------------------
ExtraData::ExtraData() :
data(NULL),
size(0)
{
// nothing more
}
ExtraData::~ExtraData()
{
Free();
}
void ExtraData::Free()
{
if (data) free(data);
data = NULL;
size = 0;
}
void ExtraData::ReadBuf(void *buf, int s)
{
data = (char*)malloc(s);
size = s;
memcpy(data, buf, size);
}
int ExtraData::Read(CMediaType *mt)
{
Free();
if (mt->formattype == FORMAT_WaveFormatEx) {
return ReadFromWaveFormatEx((WAVEFORMATEX*)mt->pbFormat);
} else
if (mt->formattype == FORMAT_VideoInfo) {
size = mt->cbFormat - sizeof(VIDEOINFOHEADER);
if (size <= 0) {
size = 0;
data = NULL;
} else {
ReadBuf((char*)mt->pbFormat + sizeof(VIDEOINFOHEADER), size);
}
return 0;
} else
if (mt->formattype == FORMAT_VideoInfo2) {
size = mt->cbFormat - sizeof(VIDEOINFOHEADER2);
if (size <= 0) {
size = 0;
data = NULL;
} else {
ReadBuf((char*)mt->pbFormat + sizeof(VIDEOINFOHEADER2), size);
}
return 0;
} else
if (mt->formattype == FORMAT_MPEGVideo) {
MPEG1VIDEOINFO *mi = (MPEG1VIDEOINFO*)mt->pbFormat;
size = mi->cbSequenceHeader;
if (size <= 0) {
size = 0;
data = NULL;
} else {
ReadBuf((char*)mi->bSequenceHeader, size);
}
return 0;
} else
if (mt->formattype == FORMAT_MPEG2Video) {
MPEG2VIDEOINFO *mi = (MPEG2VIDEOINFO*)mt->pbFormat;
size = mi->cbSequenceHeader;
if (size <= 0) {
size = 0;
data = NULL;
} else {
ReadBuf((char*)mi->dwSequenceHeader, size);
}
return 0;
}
// error
return -1;
}
int ExtraData::ReadFromWaveFormatEx(WAVEFORMATEX *wfx)
{
Free();
// najdeme data
size = wfx->cbSize;
if (size <= 0) return 0;
char *src = ((char*)wfx) + sizeof(WAVEFORMATEX);
data = (char*)malloc(size);
memcpy(data, src, size);
// vsetko je okej
return 0;
}
//-----------------------------------------------------------------------------
//
// FLVIO class
//
//-----------------------------------------------------------------------------
FLVIO::FLVIO()
{
stream = NULL;
}
FLVIO::~FLVIO()
{
Detach();
}
void FLVIO::Attach(IStream *str)
{
stream = NULL;
stream = str;
}
void FLVIO::Detach()
{
stream = NULL;
}
__int64 FLVIO::Write(BYTE *buffer, int size)
{
if (!stream) return 0;
ULONG ret;
stream->Write((void*)buffer, (ULONG)size, &ret);
return ret;
}
__int64 FLVIO::Seek(__int64 offset)
{
if (!stream) return (__int64)-1;
LARGE_INTEGER pos;
ULARGE_INTEGER newpos;
HRESULT hr;
pos.QuadPart = offset;
hr = stream->Seek(pos, 0, &newpos);
if (FAILED(hr)) return (uint64)-1;
return newpos.QuadPart;
}
__int64 FLVIO::GetPosition()
{
if (!stream) return (__int64)-1;
LARGE_INTEGER pos;
ULARGE_INTEGER newpos;
pos.QuadPart = 0;
stream->Seek(pos, STREAM_SEEK_CUR, &newpos);
return newpos.QuadPart;
}
//-----------------------------------------------------------------------------
//
// FLVWriter class
//
//-----------------------------------------------------------------------------
FLVWriter::FLVWriter() :
io(NULL)
{
video_codec = FLV_CODEC_NONE;
audio_codec = FLV_CODEC_NONE;
video_width = 0;
video_height = 0;
video_raw_size = 0;
time_first_ms = 0;
time_last_ms = 0;
video_frames = 0;
audio_channels = 0;
audio_samplerate = 0;
is_first = true;
duration_ms = 0;
video_fps = 0;
file_size = 0;
}
FLVWriter::~FLVWriter()
{
Reset();
}
int FLVWriter::Reset()
{
// reset all internal states
video_width = 0;
video_height = 0;
video_raw_size = 0;
video_frames = 0;
audio_channels = 0;
audio_samplerate = 0;
last_tag_size = 0;
video_fps = 0;
file_size = 0;
// no streams...
video_codec = FLV_CODEC_NONE;
audio_codec = FLV_CODEC_NONE;
time_first_ms = 0;
time_last_ms = 0;
duration_ms = 0;
is_first = true;
io = NULL;
return 0;
}
int FLVWriter::ConfigStream(CMediaType *pmt)
{
/*
now we try to detect the stream format.
there's a limitation - there can be only one instance of each stream type (audio, video...)
*/
if (pmt->majortype == MEDIATYPE_Video) {
int codec = FLV_CODEC_NONE;
if (pmt->subtype == MEDIASUBTYPE_FLV1) codec = FLV_CODEC_FLV1; else
if (pmt->subtype == MEDIASUBTYPE_FLV4) codec = FLV_CODEC_FLV4; else
if (pmt->subtype == MEDIASUBTYPE_AVC) codec = FLV_CODEC_H264; else
/*
TODO: Find out why VP6 is not working
if (pmt->subtype == MEDIASUBTYPE_FLV4 ||
pmt->subtype == MEDIASUBTYPE_VP60 ||
pmt->subtype == MEDIASUBTYPE_VP61 ||
pmt->subtype == MEDIASUBTYPE_VP62
) codec = FLV_CODEC_FLV4; else
*/
{
// unsupported video codec
return -1;
}
// we can only have one video stream
if (video_codec != FLV_CODEC_NONE) return -1;
REFERENCE_TIME timeperframe = 0;
// parse the video size
if (pmt->formattype == FORMAT_VideoInfo) {
VIDEOINFOHEADER *vih = (VIDEOINFOHEADER*)pmt->pbFormat;
video_width = vih->bmiHeader.biWidth;
video_height = vih->bmiHeader.biHeight;
timeperframe = vih->AvgTimePerFrame;
} else
if (pmt->formattype == FORMAT_VideoInfo2) {
VIDEOINFOHEADER2 *vih = (VIDEOINFOHEADER2*)pmt->pbFormat;
video_width = vih->bmiHeader.biWidth;
video_height = vih->bmiHeader.biHeight;
timeperframe = vih->AvgTimePerFrame;
} else
if (pmt->formattype == FORMAT_MPEG2Video) {
MPEG2VIDEOINFO *mvi = (MPEG2VIDEOINFO*)pmt->pbFormat;
video_width = mvi->hdr.bmiHeader.biWidth;
video_height = mvi->hdr.bmiHeader.biHeight;
timeperframe = mvi->hdr.AvgTimePerFrame;
} else
if (pmt->formattype == FORMAT_MPEGVideo) {
MPEG1VIDEOINFO *mvi = (MPEG1VIDEOINFO*)pmt->pbFormat;
video_width = mvi->hdr.bmiHeader.biWidth;
video_height = mvi->hdr.bmiHeader.biHeight;
timeperframe = mvi->hdr.AvgTimePerFrame;
}
video_fps = 0;
if (timeperframe != 0) {
video_fps = (double)10000000.0 / (double)timeperframe;
}
// we're done
video_codec = codec;
video_extradata.Read(pmt);
return 0;
} else
if (pmt->majortype == MEDIATYPE_Audio) {
int codec = FLV_CODEC_NONE;
if (pmt->subtype == MEDIASUBTYPE_MP3) codec = FLV_CODEC_MP3; else
if (pmt->subtype == MEDIASUBTYPE_AAC) codec = FLV_CODEC_AAC; else
{
// unsupported audio codec
return -1;
}
// we can only have one audio stream
if (audio_codec != FLV_CODEC_NONE) return -1;
// audio parameters
if (pmt->formattype == FORMAT_WaveFormatEx) {
WAVEFORMATEX *wfx = (WAVEFORMATEX*)pmt->pbFormat;
audio_channels = wfx->nChannels;
audio_samplerate = wfx->nSamplesPerSec;
}
// we're done
audio_codec = codec;
audio_extradata.Read(pmt);
return 0;
} else {
// unsupported stream type
return -1;
}
return 0;
}
int FLVWriter::Start(FLVIO *flvio)
{
io = flvio;
if (!io) return -1;
// write the file header
BYTE header[9] = {
'F','L','V', // FLV file signature
0x01, // FLV file version = 1
0, // Flags - modified later
0, 0, 0, 9 // size of the header
};
if (video_codec != FLV_CODEC_NONE) header[4] |= 0x01;
if (audio_codec != FLV_CODEC_NONE) header[4] |= 0x04;
io->Seek(0);
file_size = 0;
io->Write(header, sizeof(header));
// write the onMetaData tag with duration=0
metadatapos = io->GetPosition();
WriteMetaData();
file_size = io->GetPosition();
return 0;
}
int FLVWriter::Sto
FLVmux—FLV复用
4星 · 超过85%的资源 需积分: 9 124 浏览量
2010-06-22
10:21:00
上传
评论 3
收藏 21KB ZIP 举报
tvxq040918
- 粉丝: 0
- 资源: 5
最新资源
- 鸢尾花(iris)数据集
- %E8%A7%86%E9%A2%91%E8%BD%AC%E9%9F%B3%E9%A2%9120240424092849.mp3
- 数据库中的分组查询及数据筛选
- J185-VB一款SOT23封装P-Channel场效应MOS管
- 计算整数各位数字之和,利用java代码实现
- J185-T2B-VB一款SOT23封装P-Channel场效应MOS管
- map20231226Kalmanfilter.ipynb
- J185-T1B-VB一款SOT23封装P-Channel场效应MOS管
- ASME Y14.5-2018 尺寸与公差标注 中文版
- J185-T1B-A-VB一款SOT23封装P-Channel场效应MOS管
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
- 1
- 2
- 3
前往页