#include "stdafx.h" #include <stdio.h> #include "directSound.h" #include "decodeUnit.h" #include "d3dhead.h" #pragma comment(lib, "d3d9.lib") extern HWND gd3wnd; void DecodeUnit::Init() { av_register_all(); avfilter_register_all(); avformat_network_init(); av_log_set_level(AV_LOG_ERROR); ic = NULL; } std::shared_ptr <AVPacket> DecodeUnit::readPacketFromSource() { std::shared_ptr<AVPacket> packet(static_cast<AVPacket*>(av_malloc(sizeof(AVPacket))), [&](AVPacket *p) { av_packet_free(&p); av_freep(&p); }); av_init_packet(packet.get()); lastReadPacktTime = av_gettime(); int ret = av_read_frame(ic, packet.get()); if (ret >= 0) { return packet; } else { return nullptr; } } bool DecodeUnit::videoDecode(AVPacket* packet, AVFrame *frame) { int gotFrame = 0; //videoIndex auto hr = avcodec_decode_video2(ic->streams[videoIndex]->codec, frame, &gotFrame, packet); int pmt = ic->streams[videoIndex]->codec->pix_fmt; if (hr >= 0 && gotFrame != 0) { return true; } return false; } int DecodeUnit::initVideoDecodeContext() { if (videoIndex < 0) return -1; auto codecId = ic->streams[videoIndex]->codec->codec_id; auto codec = avcodec_find_decoder(codecId); if (!codec) { return -1; } int ret = avcodec_open2(ic->streams[videoIndex]->codec, codec, NULL); return ret; } int DecodeUnit::initAudioDecodeContext() { if (audioIndex < 0) return -1; auto codecId = ic->streams[audioIndex]->codec->codec_id; auto codec = avcodec_find_decoder(codecId); if (!codec) { return -1; } int ret = avcodec_open2(ic->streams[audioIndex]->codec, codec, NULL); if (ret < 0) return ret; if (ic->streams[audioIndex]->codec->sample_fmt != AV_SAMPLE_FMT_S16) { swr = swr_alloc(); av_opt_set_int(swr, "in_channel_layout", ic->streams[audioIndex]->codec->channel_layout, 0); av_opt_set_int(swr, "out_channel_layout", ic->streams[audioIndex]->codec->channel_layout, 0); av_opt_set_int(swr, "in_sample_rate", ic->streams[audioIndex]->codec->sample_rate, 0); av_opt_set_int(swr, "out_sample_rate", ic->streams[audioIndex]->codec->sample_rate, 0); av_opt_set_sample_fmt(swr, "in_sample_fmt", ic->streams[audioIndex]->codec->sample_fmt, 0); av_opt_set_sample_fmt(swr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0); swr_init(swr); } return ret; } bool DecodeUnit::audioDecode(AVPacket* packet, AVFrame *frame) { int gotFrame = 0; auto hr = avcodec_decode_audio4(ic->streams[audioIndex]->codec, frame, &gotFrame, packet); if (hr >= 0 && gotFrame != 0) { return true; } return false; } #define MAX_AUDIOBUFF_LEN 192000*128 //BYTE* gAudioBuf[MAX_AUDIOBUFF_LEN]; BYTE gAudioBuf[MAX_AUDIOBUFF_LEN]; DWORD gAudioBufUsed = 0; DWORD gAudioBufOffset = 0; int DecodeUnit::InitMainExe(char* spath) { int scan_all_pmts_set = 0; /* register all codecs, demux and protocols */ Init(); ic = avformat_alloc_context(); int ret; if (!ic) { av_log(NULL, AV_LOG_FATAL, "Could not allocate context.\n"); ret = AVERROR(ENOMEM); printf("alloc err %d\n", ret); } /* if (!av_dict_get(iformat_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE)) { av_dict_set(&iformat_opts, "scan_all_pmts", "1", AV_DICT_DONT_OVERWRITE); scan_all_pmts_set = 1; } */ int err = avformat_open_input(&ic, spath, nullptr, nullptr); if (err < 0) { printf("open err err=%d\n", err); } printf("come 2\n"); ret = avformat_find_stream_info(ic, nullptr); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Find input file stream inform failed\n"); } else { for (int i = 0; i < ic->nb_streams; i++) { if (ic->streams[i]->codec->codec_type == AVMediaType::AVMEDIA_TYPE_VIDEO) { videoIndex = i; } else if (ic->streams[i]->codec->codec_type == AVMediaType::AVMEDIA_TYPE_AUDIO) { audioIndex = i; initDsAudio(ic->streams[audioIndex]->codec->sample_rate, ic->streams[audioIndex]->codec->channels); //std::thread t(playDsAudio); //t.detach(); } } //playState = CGPlayState::POpen; //av_log(NULL, AV_LOG_FATAL, "Open input file %s success\n", inputUrl.c_str()); } int reta = initAudioDecodeContext(); int ret1 = initVideoDecodeContext(); printf("ret1 %d, reta %d\n", ret1, reta); //std::shared_ptr<CGSDLRender> sdlRender = std::make_shared<CGSDLRender>();//??????? if (videoIndex >= 0){ int w = ic->streams[videoIndex]->codec->width; int h = ic->streams[videoIndex]->codec->height; InitD3D(gd3wnd); Build(w ,h); } //FILE* f = fopen("single.pcm", "wb+"); //FILE* f = fopen("1.yuv", "wb+"); //FILE* fr = fopen("1.yuv", "rb+"); //playDsAudio(); //fclose(f); //fclose(fr); //system("pause"); return 0; } int DecodeUnit::MainExe(){ /* FILE * fp; if ((fp = fopen("test0906.pcm", "wb+")) == NULL) { printf("cannot open this file\n"); return -1; } */ AVFrame * videoFrame = av_frame_alloc(); byte buffer[640 * 360 * 3 / 2]; for (int i = 0; i <500; i++) { auto packet = readPacketFromSource(); if (packet) { if (packet->stream_index == videoIndex) { //continue; if (videoDecode(packet.get(), videoFrame)) { int w = ic->streams[videoIndex]->codec->width; int h = ic->streams[videoIndex]->codec->height; AVFrame * frame = videoFrame; AVPixelFormat a; int iFormat = frame->format; //int ret =fread(buffer, 1, 640*360*3/2, fr) ; //if (0 == ret) break; //Render(frame->linesize[0], h, frame->data[0]); //Render(frame->linesize[0], h, frame->data[0], frame->data[1], frame->data[2]); Render(frame->linesize[0], h, frame->data[0], frame->data[1], frame->data[2]); //Render(640, 360, buffer, buffer + 640 * 360, buffer + 640 * 360+640*360/4); //Render1(buffer); int frame_size_y = frame->linesize[0] * frame->height; //int frame_size_uv = ((frame->linesize[0] + 1) >> 1) * ((frame->height + 1) >> 1); int frame_size_uv = frame->linesize[0] * frame->height / 4; /* int r1 = fwrite(frame->data[0], 1, frame_size_y, f); int r2 = fwrite(frame->data[1], 1, frame_size_uv, f); int r3 = fwrite(frame->data[2], 1, frame_size_uv, f); */ double dt = (packet->dts - lastDts) * av_q2d(ic->streams[videoIndex]->time_base); int dms = dt * 1000; //if (dms<1000 & dms>0) Sleep(dms); // SDL_Delay(dms); printf("SDL_Delay %d \n", dms); lastDts = packet->dts; } } if (packet->stream_index == audioIndex) { if (audioDecode(packet.get(), videoFrame)) { //----------------- int dstNbChannels = 1; int srcNbSamples = videoFrame->nb_samples; int srcRate = ic->streams[audioIndex]->codec->sample_rate; int dstRate = ic->streams[audioIndex]->codec->sample_rate; int dstNbSamples = av_rescale_rnd(srcNbSamples, dstRate, srcRate, AV_ROUND_UP); AVSampleFormat dst_sample_fmt = AV_SAMPLE_FMT_S16; uint8_t** dst_data = nullptr; int dstLinesize; dstNbChannels = av_get_channel_layout_nb_channels(ic->streams[audioIndex]->codec->channel_layout); dstNbChannels = dstNbChannels > 0 ? dstNbChannels : 1; int ret = av_samples_alloc_array_and_samples(&dst_data, &dstLinesize, dstNbChannels, dstNbSamples, dst_sample_fmt, 0); ret = swr_convert(swr, dst_data, dstNbSamples, (const uint8_t **)videoFrame->data, srcNbSamples); //sdlRender->PlaySamples((BYTE*)dst_data[0], dstLinesize); //PlaySamples((BYTE*)dst_data[0], dstLinesize); printf("PlaySamples dstLinesize %d i %d\n ", dstLinesize, i); //int r3 = fwrite((BYTE*)dst_data[0], 1, dstLinesize, fp); if (gAudioBufUsed + dstLinesize > MAX_AUDIOBUFF_LEN){ //Sleep(300); break; } memcpy((BYTE*)(gAudioBuf + gAudioBufUsed), (BYTE*)dst_data[0], dstLinesize); gAudioBufUsed += dstLinesize; //printf("write r3 = %d\n", r3); int g = 0; } } } else { break; } } playDsAudio(); av_frame_free(&videoFrame); //fclose(fp); return 0; } //明天可以同步---,to thi tha
audio里
#include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include <windows.h> #include <mmsystem.h> #include <dsound.h> #include "directSound.h" #include "decodeUnit.h" #define MAX_AUDIO_BUF 4 #define BUFFERNOTIFYSIZE 192000 //int sample_rate = 44100; //PCM sample rate //int channels = 2; //PCM channel number int bits_per_sample = 16; //bits per sample int i; IDirectSound8 *m_pDS = 0; IDirectSoundBuffer8 *m_pDSBuffer8 = NULL; //used to manage sound buffers. IDirectSoundBuffer *m_pDSBuffer = NULL; IDirectSoundNotify8 *m_pDSNotify = 0; DSBPOSITIONNOTIFY m_pDSPosNotify[MAX_AUDIO_BUF]; HANDLE m_event[MAX_AUDIO_BUF]; bool initDsAudio(int sample_rate, int channels){ //sample_rate = 44100; //channels = 2; //SetConsoleTitle(TEXT("Simplest Audio Play DirectSound"));//Console Title //Init DirectSound if (FAILED(DirectSoundCreate8(NULL, &m_pDS, NULL))) return FALSE; //if (FAILED(m_pDS->SetCooperativeLevel(FindWindow(NULL, TEXT("Simplest Audio Play DirectSound")), DSSCL_NORMAL))) if (FAILED(m_pDS->SetCooperativeLevel(FindWindow(NULL, TEXT("testD3P")), DSSCL_NORMAL))) return FALSE; DSBUFFERDESC dsbd; memset(&dsbd, 0, sizeof(dsbd)); dsbd.dwSize = sizeof(dsbd); dsbd.dwFlags = DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GETCURRENTPOSITION2; dsbd.dwBufferBytes = MAX_AUDIO_BUF*BUFFERNOTIFYSIZE; dsbd.lpwfxFormat = (WAVEFORMATEX*)malloc(sizeof(WAVEFORMATEX)); dsbd.lpwfxFormat->wFormatTag = WAVE_FORMAT_PCM; /* format type */ (dsbd.lpwfxFormat)->nChannels = channels; /* number of channels (i.e. mono, stereo...) */ (dsbd.lpwfxFormat)->nSamplesPerSec = sample_rate; /* sample rate */ (dsbd.lpwfxFormat)->nAvgBytesPerSec = sample_rate*(bits_per_sample / 8)*channels; /* for buffer estimation */ (dsbd.lpwfxFormat)->nBlockAlign = (bits_per_sample / 8)*channels; /* block size of data */ (dsbd.lpwfxFormat)->wBitsPerSample = bits_per_sample; /* number of bits per sample of mono data */ (dsbd.lpwfxFormat)->cbSize = 0; //Creates a sound buffer object to manage audio samples. HRESULT hr1; if (FAILED(m_pDS->CreateSoundBuffer(&dsbd, &m_pDSBuffer, NULL))) { return FALSE; } if (FAILED(m_pDSBuffer->QueryInterface(IID_IDirectSoundBuffer8, (LPVOID*)&m_pDSBuffer8))) { return FALSE; } //Get IDirectSoundNotify8 if (FAILED(m_pDSBuffer8->QueryInterface(IID_IDirectSoundNotify, (LPVOID*)&m_pDSNotify))) { return FALSE; } for (i = 0; i<MAX_AUDIO_BUF; i++) { m_pDSPosNotify[i].dwOffset = i*BUFFERNOTIFYSIZE; m_event[i] = ::CreateEvent(NULL, false, false, NULL); m_pDSPosNotify[i].hEventNotify = m_event[i]; } m_pDSNotify->SetNotificationPositions(MAX_AUDIO_BUF, m_pDSPosNotify); m_pDSNotify->Release(); return -1; } extern DecodeUnit* gDu ; //Start Playing BOOL isPlaying = TRUE; LPVOID buf = NULL; DWORD buf_len = 0; DWORD res = WAIT_OBJECT_0; DWORD offset = BUFFERNOTIFYSIZE; #define MAX_AUDIOBUFF_LEN 192000*128 extern BYTE gAudioBuf[MAX_AUDIOBUFF_LEN]; extern DWORD gAudioBufUsed ; extern DWORD gAudioBufOffset ; #define READ_FILE_LOOP 1024//19200*2 bool playDsAudio() { //---------------------------- /* FILE * fp; //if ((fp = fopen("F:\\NocturneNo2inEflat_44.1k_s16le.pcm", "rb")) == NULL) { if ((fp = fopen("test0906.pcm", "rb")) == NULL) { printf("cannot open this file\n"); return -1; } byte fbuf[READ_FILE_LOOP+1] = {0}; while (1) { int ret = fread(fbuf, 1, READ_FILE_LOOP, fp); if (ret != READ_FILE_LOOP){ fclose(fp); break; } memcpy((BYTE*)(gAudioBuf + gAudioBufUsed), (BYTE*)fbuf, READ_FILE_LOOP); gAudioBufUsed += READ_FILE_LOOP; //File End //Loop: //Close: //isPlaying=0; } */ //------------------------- m_pDSBuffer8->SetCurrentPosition(0); m_pDSBuffer8->Play(0, 0, DSBPLAY_LOOPING); //Loop while (isPlaying) { if ((res >= WAIT_OBJECT_0) && (res <= WAIT_OBJECT_0 + 3)) { m_pDSBuffer8->Lock(offset, BUFFERNOTIFYSIZE, &buf, &buf_len, NULL, NULL, 0); /* if (fread(buf, 1, buf_len, fp) != buf_len) { //File End //Loop: fseek(fp, 0, SEEK_SET); fread(buf, 1, buf_len, fp); //Close: //isPlaying=0; } */ if (gAudioBufOffset >= gAudioBufUsed) break; memcpy(buf, gAudioBuf + gAudioBufOffset, buf_len); gAudioBufOffset += buf_len; offset += buf_len; offset %= (BUFFERNOTIFYSIZE * MAX_AUDIO_BUF); printf("this is %7d of buffer\n", offset); m_pDSBuffer8->Unlock(buf, buf_len, NULL, 0); } res = WaitForMultipleObjects(MAX_AUDIO_BUF, m_event, FALSE, INFINITE); } return 0; }