int GetStorage(IStorage* storage, int index, IStorage** out) { int res; wchar_t* name; STGTY type; assert(storage != NULL); assert(out != NULL); *out = NULL; res = GetStreamType(storage, index, &type); if ((res == 0) || (type != STGTY_STORAGE)) return 0; res = GetStreamName(storage, index, &name); if (res == 0) return 0; res = storage->lpVtbl->OpenStorage(storage, name, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, out); free(name); return (res == S_OK)? 1 : 0; }
int SaveStream(IStorage* storage, int index, FILE* out) { int res; ULONG bytesread; STATSTG st; IStream* stream; IStorage* temporary; IStorage* source; FILE* in; LARGE_INTEGER li; (void)memset(&li, 0, sizeof(li)); res = GetStreamType(storage,index,&st.type); if (res == 0) return 0; if (st.type == STGTY_STREAM) { fprintf(stderr, "Fetching stream\n"); res = GetStream(storage, index, &stream); } else if (st.type == STGTY_STORAGE) { fprintf(stderr, "Fetching store\n"); res = GetStorage(storage, index, &source); } else { fprintf(stderr, "Fetching unknown %x\n", st.type); res = 0; } if (res == 0) return 0; switch(st.type) { case STGTY_STREAM: fprintf(stderr, "Seeking to beginning of stream\n"); (HRESULT)stream->lpVtbl->Seek(stream, li, STREAM_SEEK_SET, NULL); fprintf(stderr, "Writing to file\n"); /* write stream to file */ for (;;) { res = stream->lpVtbl->Read(stream, g_TransferBuffer, sizeof(g_TransferBuffer), &bytesread); if (res != S_OK) { res = 1; goto stream_release; } (size_t)fwrite(g_TransferBuffer, 1, bytesread, out); if (bytesread < sizeof(g_TransferBuffer)) break; } res = 1; fprintf(stderr, "Done\n"); stream_release: (ULONG)stream->lpVtbl->Release(stream); break; case STGTY_STORAGE: fprintf(stderr, "Creating temporary storage on disk\n"); res = StgCreateStorageEx(NULL, STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE|STGM_DELETEONRELEASE, STGFMT_STORAGE, 0, NULL, NULL, &IID_IStorage, &temporary); if (res != S_OK) { res = 0; goto source_release; } fprintf(stderr, "Copying store to temporary storage\n"); res = source->lpVtbl->CopyTo(source, 0, NULL, NULL, temporary); if (res != S_OK) { res = 0; goto temporary_release; } res = source->lpVtbl->Commit(source, STGC_DEFAULT); if (res != S_OK) { res = 0; goto temporary_release; } fprintf(stderr, "Getting temporary storage filename\n"); res = temporary->lpVtbl->Stat(temporary, &st, STATFLAG_DEFAULT); if (res != S_OK) { res = 0; goto temporary_release; } fprintf(stderr, "Opening temporary storage %S\n", st.pwcsName); in = _wfopen(st.pwcsName, L"rb"); if (in == NULL) { res = 0; goto temporary_release; } fprintf(stderr, "Writing to file\n"); for (;;) { bytesread = fread(&g_TransferBuffer, 1, sizeof(g_TransferBuffer), in); (size_t)fwrite(g_TransferBuffer, 1, bytesread, out); if (bytesread < sizeof(g_TransferBuffer)) break; } fclose(in); res = 1; fprintf(stderr, "Done\n"); temporary_release: temporary->lpVtbl->Release(temporary); source_release: source->lpVtbl->Release(source); break; } return res; }
bool V4L2encStreamHandler::Configure(void) { if (m_streaming_cnt.load() > 0) { LOG(VB_RECORD, LOG_INFO, LOC + "Configure() -- Already configured."); return true; } LOG(VB_RECORD, LOG_INFO, LOC + "Configure() -- begin"); if (m_width > 0 && m_height > 0 && !m_v4l2.SetResolution(m_width, m_height)) { m_v4l2.Close(); LOG(VB_RECORD, LOG_ERR, LOC + "Configure() -- failed"); return false; } if (m_v4l2.HasTuner()) SetLanguageMode(); // we don't care if this fails... if (m_v4l2.HasAudioSupport()) m_v4l2.SetVolume(m_audio_volume); // we don't care if this fails... if (m_desired_stream_type >= 0) m_v4l2.SetStreamType(m_desired_stream_type); LOG(VB_RECORD, LOG_INFO, LOC + QString("Options for %1") .arg(m_v4l2.StreamTypeDesc(GetStreamType()))); if (m_aspect_ratio >= 0) m_v4l2.SetVideoAspect(m_aspect_ratio); if (m_bitrate_mode < 0) m_bitrate_mode = m_high_bitrate_mode; if (m_max_bitrate < 0 && m_high_peak_bitrate > 0) m_max_bitrate = m_high_peak_bitrate; if (m_bitrate < 0 && m_high_bitrate > 0) m_bitrate = m_high_bitrate; m_max_bitrate = std::max(m_max_bitrate, m_bitrate); if (m_bitrate_mode >= 0) m_v4l2.SetVideoBitrateMode(m_bitrate_mode); if (m_bitrate > 0) m_v4l2.SetVideoBitrate(m_bitrate * 1000); if (m_max_bitrate > 0) m_v4l2.SetVideoBitratePeak(m_max_bitrate * 1000); if (m_audio_input >= 0) m_v4l2.SetAudioInput(m_audio_input); else LOG(VB_CHANNEL, LOG_WARNING, "Audio input not set."); if (m_audio_codec >= 0) m_v4l2.SetAudioCodec(m_audio_codec); if (m_audio_samplerate >= 0) m_v4l2.SetAudioSamplingRate(m_audio_samplerate); if (m_audio_bitrateL2 >= 0) m_v4l2.SetAudioBitrateL2(m_audio_bitrateL2); ConfigureVBI(); LOG(VB_RECORD, LOG_INFO, LOC + "Configure() -- done"); return false; }
DWORD CMpegSplitterFile::AddStream(WORD pid, BYTE pesid, BYTE ps1id, DWORD len) { if (pid) { if (pesid) { m_pid2pes[pid] = pesid; } else { m_pid2pes.Lookup(pid, pesid); } } stream s; s.pid = pid; s.pesid = pesid; s.ps1id = ps1id; const __int64 start = GetPos(); int type = unknown; if (pesid >= 0xe0 && pesid < 0xf0) { // mpeg video // MPEG2 if (type == unknown) { CMpegSplitterFile::seqhdr h; if (!m_streams[video].Find(s) && Read(h, len, &s.mt)) { PES_STREAM_TYPE stream_type = INVALID; if (GetStreamType(s.pid, stream_type)) { if (IsMPEG2Video(stream_type)) { type = video; } } else { type = video; } } } // H.264 if (type == unknown) { Seek(start); // PPS and SPS can be present on differents packets // and can also be split into multiple packets if (!avch.Lookup(pid)) { memset(&avch[pid], 0, sizeof(CMpegSplitterFile::avchdr)); } #if defined(MVC_SUPPORT) if (!m_streams[video].Find(s) && !m_streams[stereo].Find(s) && Read(avch[pid], len, &s.mt)) { if (avch[pid].spspps[index_subsetsps].complete) { type = stereo; } else { type = video; } } #else if (!m_streams[video].Find(s) && Read(avch[pid], len, &s.mt)) { PES_STREAM_TYPE stream_type = INVALID; if (GetStreamType(s.pid, stream_type)) { if (IsH264Video(stream_type)) { type = video; } } else { type = video; } } #endif } } else if (pesid >= 0xc0 && pesid < 0xe0) { // mpeg audio // AAC if (type == unknown) { CMpegSplitterFile::aachdr h; if (!m_streams[audio].Find(s) && Read(h, len, &s.mt, m_type)) { PES_STREAM_TYPE stream_type = INVALID; if (GetStreamType(s.pid, stream_type)) { if (IsAACAudio(stream_type)) { type = audio; } } else { type = audio; } } } // AAC LATM if (type == unknown) { Seek(start); CMpegSplitterFile::latm_aachdr h; if (!m_streams[audio].Find(s) && Read(h, len, &s.mt)) { PES_STREAM_TYPE stream_type = INVALID; if (GetStreamType(s.pid, stream_type)) { if (IsAACLATMAudio(stream_type)) { type = audio; } } else { type = audio; } } } // MPEG Audio if (type == unknown) { Seek(start); CMpegSplitterFile::mpahdr h; if (!m_streams[audio].Find(s) && Read(h, len, false, &s.mt)) { PES_STREAM_TYPE stream_type = INVALID; if (GetStreamType(s.pid, stream_type)) { if (IsMpegAudio(stream_type)) { type = audio; } } else { type = audio; } } } } else if (pesid == 0xbd || pesid == 0xfd) { // private stream 1 if (s.pid) { if (!m_streams[audio].Find(s) && !m_streams[video].Find(s)) { // AC3, E-AC3, TrueHD if (type == unknown) { CMpegSplitterFile::ac3hdr h; if (Read(h, len, &s.mt, true, (m_AC3CoreOnly == 1))) { PES_STREAM_TYPE stream_type = INVALID; if (GetStreamType(s.pid, stream_type)) { if (IsAC3Audio(stream_type)) { type = audio; } } else { type = audio; } } } // DTS, DTS HD, DTS HD MA if (type == unknown) { Seek(start); CMpegSplitterFile::dtshdr h; if (Read(h, len, &s.mt, false)) { type = audio; } } // VC1 if (type == unknown) { Seek(start); CMpegSplitterFile::vc1hdr h; if (!m_streams[video].Find(s) && Read(h, len, &s.mt, m_nVC1_GuidFlag)) { PES_STREAM_TYPE stream_type = INVALID; if (GetStreamType(s.pid, stream_type)) { if (IsVC1Video(stream_type)) { type = video; } } else { type = video; } } } // DVB subtitles if (type == unknown) { Seek(start); CMpegSplitterFile::dvbsub h; if (!m_streams[video].Find(s) && Read(h, len, &s.mt)) { type = subpic; } } int iProgram; const CHdmvClipInfo::Stream* pClipInfo; const program* pProgram = FindProgram(s.pid, iProgram, pClipInfo); if ((type == unknown) && (pProgram != NULL)) { PES_STREAM_TYPE StreamType = INVALID; Seek(start); StreamType = pProgram->streams[iProgram].type; switch (StreamType) { case AUDIO_STREAM_LPCM: { CMpegSplitterFile::hdmvlpcmhdr h; if (!m_streams[audio].Find(s) && Read(h, &s.mt)) { type = audio; } } break; case PRESENTATION_GRAPHICS_STREAM: { CMpegSplitterFile::hdmvsubhdr h; if (!m_streams[subpic].Find(s) && Read(h, &s.mt, pClipInfo ? pClipInfo->m_LanguageCode : NULL)) { m_bIsHdmv = true; type = subpic; } } break; } } } else if ((m_AC3CoreOnly != 1) && m_init) { int iProgram; const CHdmvClipInfo::Stream* pClipInfo; const program* pProgram = FindProgram(s.pid, iProgram, pClipInfo); if ((type == unknown) && (pProgram != NULL) && AUDIO_STREAM_AC3_TRUE_HD == pProgram->streams[iProgram].type) { const stream* source = m_streams[audio].FindStream(s.pid); if (source && source->mt.subtype == MEDIASUBTYPE_DOLBY_AC3) { CMpegSplitterFile::ac3hdr h; if (Read(h, len, &s.mt, false, (m_AC3CoreOnly == 1)) && s.mt.subtype == MEDIASUBTYPE_DOLBY_TRUEHD) { m_streams[audio].Replace((stream&)*source, s, this); } } } } } else if (pesid == 0xfd) { CMpegSplitterFile::vc1hdr h; if (!m_streams[video].Find(s) && Read(h, len, &s.mt, m_nVC1_GuidFlag)) { type = video; } } else { BYTE b = (BYTE)BitRead(8, true); WORD w = (WORD)BitRead(16, true); DWORD dw = (DWORD)BitRead(32, true); if (b >= 0x80 && b < 0x88 || w == 0x0b77) { // ac3 s.ps1id = (b >= 0x80 && b < 0x88) ? (BYTE)(BitRead(32) >> 24) : 0x80; CMpegSplitterFile::ac3hdr h; if (!m_streams[audio].Find(s) && Read(h, len, &s.mt)) { type = audio; } } else if (b >= 0x88 && b < 0x90 || dw == 0x7ffe8001) { // dts s.ps1id = (b >= 0x88 && b < 0x90) ? (BYTE)(BitRead(32) >> 24) : 0x88; CMpegSplitterFile::dtshdr h; if (!m_streams[audio].Find(s) && Read(h, len, &s.mt)) { type = audio; } } else if (b >= 0xa0 && b < 0xa8) { // lpcm
} int MediaPacket::Size() const { return static_cast<int>(pAvPacket_->size); } void MediaPacket::Print() const { #if LOG_TRADITIONAL loginfo("packet: pts=%lu, dts=%lu, stream=%d, codec=%d, size=%lu", #else loginfo("packet: pts={}, dts={}, stream={}, codec={}, size={}", #endif static_cast<unsigned long>(pAvPacket_->pts), static_cast<unsigned long>(pAvPacket_->dts), GetStreamType(), GetCodec(), static_cast<unsigned long>(pAvPacket_->size)); } void MediaPacket::Dump(const std::string& _title) const { #if LOG_TRADITIONAL logdebug("%spts=%lu, dts=%lu, stream=%d, codec=%d, size=%lu", _title.c_str(), #else logdebug("{}pts={}, dts={}, stream={}, codec={}, size={}", _title.c_str(), #endif static_cast<unsigned long>(pAvPacket_->pts), static_cast<unsigned long>(pAvPacket_->dts), GetStreamType(), GetCodec(), static_cast<unsigned long>(pAvPacket_->size)); //PrintMem(Data(), Size()); }