• testd3p


    decodeUnit.cpp

    #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.
    ");
            ret = AVERROR(ENOMEM);
            printf("alloc err %d
    ", 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
    ", err);
        }
        printf("come 2
    ");
    
        ret = avformat_find_stream_info(ic, nullptr);
        if (ret < 0)
        {
            av_log(NULL, AV_LOG_ERROR, "Find input file stream inform failed
    ");
        }
        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
    ", inputUrl.c_str());
        }
    
        
        int reta = initAudioDecodeContext();
        
        
    
    
        int ret1 = initVideoDecodeContext();
        printf("ret1  %d, reta %d
    ", 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
    ");
            return -1;
        }
        */
        AVFrame * videoFrame = av_frame_alloc();
        byte buffer[640 * 360 * 3 / 2];
        for (int i = 0; i <1; 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 
    ", 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
     ", 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
    ",  r3); 
                        int g = 0;
    
                    }
                }
    
    
    
            }
            else {
                break;
            }
        }
    
        //playDsAudio();
    
        av_frame_free(&videoFrame);
        //fclose(fp);
        return 0;
    }
    
    //明天可以同步---,to thi tha

    directSoundAudio.cpp

    #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 
    #define BUFFERNOTIFYSIZE 1024*2 
    
    
    //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
    ");
            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
        int j = 0;
        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;
                }
            */
                
        
    
                while (gAudioBufOffset + buf_len >= gAudioBufUsed){
                    if ((gAudioBufOffset + buf_len) >= MAX_AUDIOBUFF_LEN)
                        break;
                    gDu->MainExe();
                    j++;
                }
                if (j > 500) break;
        
    
                memcpy(buf, gAudioBuf + gAudioBufOffset, buf_len);
                gAudioBufOffset += buf_len;
            
                offset += buf_len;
                offset %= (BUFFERNOTIFYSIZE * MAX_AUDIO_BUF);
                printf("this is %7d of buffer
    ", offset);
                m_pDSBuffer8->Unlock(buf, buf_len, NULL, 0);
            }
            res = WaitForMultipleObjects(MAX_AUDIO_BUF, m_event, FALSE, INFINITE);
        }
    
        return 0;
    }
  • 相关阅读:
    流体布局、响应式布局
    CSS
    表格的合并
    HTML
    http请求与响应
    MySQL存储引擎
    MySQL之索引以及正确使用索引
    MySQL之视图、触发器、存储过程、函数、事务、数据库锁
    MySQL之正则表达式
    MySQL练习题
  • 原文地址:https://www.cnblogs.com/cnchengv/p/15261585.html
Copyright © 2020-2023  润新知