2016-08-28 3 views
-1

私はisamplegrabberサンプルコールバックを使用してオーディオサンプルを取得しました。imediasampleからバッファとバッファ長を取得できます。avcodec_fill_audio_frame(frame、ost-> enc-> channels、ost-> enc-> sample_fmt、(uint8_t *)バッファー、長さ、0)を使用してavframeを作成しますが、このフレームはmuxファイルにオーディオを作成しません!私は長さがframe_sizeよりも非常に小さいと思います。 一人一人は私を助けてくれますか?可能であれば、私にいくつかの例を教えてください。ffmpeg audio frame from directshow sampleCB imediasample

 HRESULT AudioSampleGrabberCallBack::SampleCB(double Time, IMediaSample*pSample){ 
     BYTE *pBuffer; 
     pSample->GetPointer(&pBuffer); 
     long BufferLen = pSample->GetActualDataLength();   
     muxer->PutAudioFrame(pBuffer,BufferLen);  
} 

、これはsamplegrabberピンのメディアタイプです:その後

AM_MEDIA_TYPE pmt2; 
    ZeroMemory(&pmt2, sizeof(AM_MEDIA_TYPE)); 
    pmt2.majortype = MEDIATYPE_Audio; 
    pmt2.subtype = FOURCCMap(0x1602); 
    pmt2.formattype = FORMAT_WaveFormatEx; 
    hr = pSampleGrabber_audio->SetMediaType(&pmt2); 

私はフレームを処理するためにffmpegの多重化の例を使用して、私は必要だと思う が、これは私のsamplecbコードであるあなたに

に感謝しますコードの信号生成部分を変更する場合のみ:

AVFrame *Muxing::get_audio_frame(OutputStream *ost,BYTE* buffer,long length) 
{ 
    AVFrame *frame = ost->tmp_frame; 
    int j, i, v; 
    uint16_t *q = (uint16_t*)frame->data[0]; 

    int buffer_size = av_samples_get_buffer_size(NULL, ost->enc->channels, 
               ost->enc->frame_size, 
               ost->enc->sample_fmt, 0); 
// uint8_t *sample = (uint8_t *) av_malloc(buffer_size); 
    av_samples_alloc(&frame->data[0], frame->linesize, ost->enc->channels, ost->enc->frame_size, ost->enc->sample_fmt, 1); 
    avcodec_fill_audio_frame(frame, ost->enc->channels, ost->enc->sample_fmt,frame->data[0], buffer_size, 1); 

    frame->pts = ost->next_pts; 
    ost->next_pts += frame->nb_samples; 

    return frame; 
} 
+0

質問は明確に定義されていません。 DirectShowのキャプチャに関するデータをさらに提供する必要があります。また、libavを使用して書き込みを試みるコードも必要です。 –

+0

シンプル!私はdirectshowを使用してmediasampleを取得し、それのavframeをしたい、私はビデオフレームのためにこれを行うが、私はそうすることはできませんでしたオーディオフレーム。 – overtech

+0

はい。誰もが助けることができます。 – Felix

答えて

1

コードスニペットは、サンプルグラバを使用してAACデータを取得し、FFmpegのlibavformatを使用してそのデータをファイルに書き込もうとしていることを示唆しています。これはうまくいくかもしれません。

サンプルグラバーを初期化して、オーディオデータをWAVE_FORMAT_AAC_LATM形式で取得します。このフォーマットは広く普及しておらず、サンプルグラバのアップストリーム接続が期待どおりであることを確認するためにフィルタグラフを検討することに興味があります。何らかの形でAAC-LATMを生成しようとする奇妙なフィルタがあり、実際にはデータが無効である(またはグラバーコールバックに到達していない)可能性があります。したがって、フィルタグラフ(Loading a Graph From an External ProcessUnderstanding Your DirectShow Filter Graphを参照)を確認してから、デバッガを使用してコールバックを実行してデータを取得し、意味をなさないことを確認する必要があります。

次に、AVFormatContext,AVStreamを初期化して、AAC LATM形式でデータを書き込むことを示します。提供されたコードでは、正しいことを示していません。 sample you are referring toはデフォルトのコーデックを使用しています。

、あなたは両方の着信データとあなたのFFmpegの出力設定は、データが、提供されたコードを持っているか、ADTSヘッダを持っていないかどうかについては一致していることを確認する必要がありますこれについては何の光も当てない。

また、オーディオデータを誤って準備している可能性があります。問題のサンプルは生のオーディオデータを生成し、エンコーダを適用してavcodec_encode_audio2を使用して圧縮されたコンテンツを生成します。その後、圧縮されたオーディオでパックされたものが、av_interleaved_write_frameを使用して書き込みに送信されています。質問にコードスニペットを付けた方法は、あなたが間違っていることを私にしています。まず最初に、関連するコードはまだ表示されないので、どのコードが正確に関連しているかを特定するのに問題があると思います。次に、AACデータをそのままPCMオーディオのように処理しています(get_audio_frameコードスニペット).FDCmpegのサンプルコードを見直したい場合は、既にAACデータを圧縮していて、サンプルはavcodec_encode_audio2コール。これは、コードとサンプルをマージする場所です。

+0

はい私のsamplegrabberが正しく動作し、私はC++を使って生データをファイルに保存して再生することができます。それは正しいです、私は、私のincommingオーディオストリームのために私のサンプルグラバーピンのメディアタイプでaac_latmを使用しています、そして今私は私のavformatcontextでAV_CODEC_ID_AAC_LATMコーデックを使用する必要があるあなたの応答を見つけましたが、 avcodec_find_encoder(codec_id)は「このコーデックのエンコーダを見つけることができませんでした! – overtech