demux_rtp_codec.cpp
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C++ 代码 · 共 400 行 · 第 1/2 页
CPP
400 行
wf->nChannels = subsession->numChannels(); // Map known audio MIME types to the WAVEFORMATEX parameters // that this program uses. (Note that not all types need all // of the parameters to be set.) wf->nSamplesPerSec = subsession->rtpSource()->timestampFrequency(); // by default if (strcmp(subsession->codecName(), "MPA") == 0 || strcmp(subsession->codecName(), "MPA-ROBUST") == 0 || strcmp(subsession->codecName(), "X-MP3-DRAFT-00") == 0) { wf->wFormatTag = sh_audio->format = 0x55; // Note: 0x55 is for layer III, but should work for I,II also wf->nSamplesPerSec = 0; // sample rate is deduced from the data } else if (strcmp(subsession->codecName(), "AC3") == 0) { wf->wFormatTag = sh_audio->format = 0x2000; wf->nSamplesPerSec = 0; // sample rate is deduced from the data } else if (strcmp(subsession->codecName(), "L16") == 0) { wf->wFormatTag = sh_audio->format = 0x736f7774; // "twos" wf->nBlockAlign = 1; wf->wBitsPerSample = 16; wf->cbSize = 0; } else if (strcmp(subsession->codecName(), "L8") == 0) { wf->wFormatTag = sh_audio->format = 0x20776172; // "raw " wf->nBlockAlign = 1; wf->wBitsPerSample = 8; wf->cbSize = 0; } else if (strcmp(subsession->codecName(), "PCMU") == 0) { wf->wFormatTag = sh_audio->format = 0x7; wf->nAvgBytesPerSec = 8000; wf->nBlockAlign = 1; wf->wBitsPerSample = 8; wf->cbSize = 0; } else if (strcmp(subsession->codecName(), "PCMA") == 0) { wf->wFormatTag = sh_audio->format = 0x6; wf->nAvgBytesPerSec = 8000; wf->nBlockAlign = 1; wf->wBitsPerSample = 8; wf->cbSize = 0; } else if (strcmp(subsession->codecName(), "AMR") == 0) { wf->wFormatTag = sh_audio->format = mmioFOURCC('s','a','m','r'); } else if (strcmp(subsession->codecName(), "AMR-WB") == 0) { wf->wFormatTag = sh_audio->format = mmioFOURCC('s','a','w','b'); } else if (strcmp(subsession->codecName(), "GSM") == 0) { wf->wFormatTag = sh_audio->format = mmioFOURCC('a','g','s','m'); wf->nAvgBytesPerSec = 1650; wf->nBlockAlign = 33; wf->wBitsPerSample = 16; wf->cbSize = 0; } else if (strcmp(subsession->codecName(), "QCELP") == 0) { wf->wFormatTag = sh_audio->format = mmioFOURCC('Q','c','l','p'); wf->nAvgBytesPerSec = 1750; wf->nBlockAlign = 35; wf->wBitsPerSample = 16; wf->cbSize = 0; } else if (strcmp(subsession->codecName(), "MP4A-LATM") == 0) { wf->wFormatTag = sh_audio->format = mmioFOURCC('m','p','4','a'); // For the codec to work correctly, it needs "AudioSpecificConfig" // data, which is parsed from the "StreamMuxConfig" string that // was present (hopefully) in the SDP description: unsigned codecdata_len; sh_audio->codecdata = parseStreamMuxConfigStr(subsession->fmtp_config(), codecdata_len); sh_audio->codecdata_len = codecdata_len; //faad doesn't understand LATM's data length field, so omit it ((MPEG4LATMAudioRTPSource*)subsession->rtpSource())->omitLATMDataLengthField(); } else if (strcmp(subsession->codecName(), "MPEG4-GENERIC") == 0) { wf->wFormatTag = sh_audio->format = mmioFOURCC('m','p','4','a'); // For the codec to work correctly, it needs "AudioSpecificConfig" // data, which was present (hopefully) in the SDP description: unsigned codecdata_len; sh_audio->codecdata = parseGeneralConfigStr(subsession->fmtp_config(), codecdata_len); sh_audio->codecdata_len = codecdata_len; } else if (strcmp(subsession->codecName(), "X-QT") == 0 || strcmp(subsession->codecName(), "X-QUICKTIME") == 0) { // QuickTime generic RTP format, as described in // http://developer.apple.com/quicktime/icefloe/dispatch026.html // We can't initialize this stream until we've received the first packet // that has QuickTime "sdAtom" information in the header. So, keep // reading packets until we get one: unsigned char* packetData; unsigned packetDataLen; float pts; QuickTimeGenericRTPSource* qtRTPSource = (QuickTimeGenericRTPSource*)(subsession->rtpSource()); unsigned fourcc, numChannels; do { if (!awaitRTPPacket(demuxer, demuxer->audio, packetData, packetDataLen, pts)) { return; } } while (!parseQTState_audio(qtRTPSource->qtState, fourcc, numChannels)); wf->wFormatTag = sh_audio->format = fourcc; wf->nChannels = numChannels; uint8_t *pos = (uint8_t*)qtRTPSource->qtState.sdAtom + 52; uint8_t *endpos = (uint8_t*)qtRTPSource->qtState.sdAtom + qtRTPSource->qtState.sdAtomSize; while (pos+8 < endpos) { unsigned atomLength = pos[0]<<24 | pos[1]<<16 | pos[2]<<8 | pos[3]; if (atomLength == 0 || atomLength > endpos-pos) break; if (!memcmp(pos+4, "wave", 4) && fourcc==mmioFOURCC('Q','D','M','2') && atomLength > 8 && atomLength <= INT_MAX) { sh_audio->codecdata = (unsigned char*) malloc(atomLength-8); if (sh_audio->codecdata) { memcpy(sh_audio->codecdata, pos+8, atomLength-8); sh_audio->codecdata_len = atomLength-8; } break; } pos += atomLength; } } else { fprintf(stderr, "Unknown MPlayer format code for MIME type \"audio/%s\"\n", subsession->codecName()); }}static void needVideoFrameRate(demuxer_t* demuxer, MediaSubsession* subsession) { // For some codecs, MPlayer's decoding software can't (or refuses to :-) // figure out the frame rate by itself, so (unless the user specifies // it manually, using "-fps") we figure it out ourselves here, using the // presentation timestamps in successive packets, extern float force_fps; if (force_fps != 0.0) return; // user used "-fps" demux_stream_t* d_video = demuxer->video; sh_video_t* sh_video = (sh_video_t*)(d_video->sh); // If we already know the subsession's video frame rate, use it: int fps = (int)(subsession->videoFPS()); if (fps != 0) { sh_video->fps = fps; sh_video->frametime = 1.0f/fps; return; } // Keep looking at incoming frames until we see two with different, // non-zero "pts" timestamps: unsigned char* packetData; unsigned packetDataLen; float lastPTS = 0.0, curPTS; unsigned const maxNumFramesToWaitFor = 300; int lastfps = 0; for (unsigned i = 0; i < maxNumFramesToWaitFor; ++i) { if (!awaitRTPPacket(demuxer, d_video, packetData, packetDataLen, curPTS)) { break; } if (curPTS != lastPTS && lastPTS != 0.0) { // Use the difference between these two "pts"s to guess the frame rate. // (should really check that there were no missing frames inbetween)##### // Guess the frame rate as an integer. If it's not, use "-fps" instead. fps = (int)(1/fabs(curPTS-lastPTS) + 0.5); // rounding if (fps == lastfps) { fprintf(stderr, "demux_rtp: Guessed the video frame rate as %d frames-per-second.\n\t(If this is wrong, use the \"-fps <frame-rate>\" option instead.)\n", fps); sh_video->fps = fps; sh_video->frametime=1.0f/fps; return; } if (fps>lastfps) lastfps = fps; } lastPTS = curPTS; } fprintf(stderr, "demux_rtp: Failed to guess the video frame rate\n");}static BooleanparseQTState_video(QuickTimeGenericRTPSource::QTState const& qtState, unsigned& fourcc) { // qtState's "sdAtom" field is supposed to contain a QuickTime video // 'sample description' atom. This atom's name is the 'fourcc' that we want: char const* sdAtom = qtState.sdAtom; if (sdAtom == NULL || qtState.sdAtomSize < 2*4) return False; fourcc = *(unsigned*)(&sdAtom[4]); // put in host order return True;}static BooleanparseQTState_audio(QuickTimeGenericRTPSource::QTState const& qtState, unsigned& fourcc, unsigned& numChannels) { // qtState's "sdAtom" field is supposed to contain a QuickTime audio // 'sample description' atom. This atom's name is the 'fourcc' that we want. // Also, the top half of the 5th word following the atom name should // contain the number of channels ("numChannels") that we want: char const* sdAtom = qtState.sdAtom; if (sdAtom == NULL || qtState.sdAtomSize < 7*4) return False; fourcc = *(unsigned*)(&sdAtom[4]); // put in host order char const* word7Ptr = &sdAtom[6*4]; numChannels = (word7Ptr[0]<<8)|(word7Ptr[1]); return True;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?