次の方法で共有


データを圧縮解除せずにストリームをコピーする

あるファイルから別のファイルにストリームをコピーする最も簡単で最も一般的な方法は、圧縮状態のサンプルを取得し、圧縮を解除して再圧縮せずに新しいファイルに書き込む方法です。 圧縮状態のファイルから取得したサンプルは、ストリーム内の表現から変更されないため、ストリーム サンプルと呼ばれます。 デジタル メディア データを圧縮解除して再圧縮すると品質が低下するため、ストリーム サンプルを常に使用してストリームをコピーすることをお勧めします。 圧縮解除されたデータからストリームをコピーする必要がある場合は、「圧縮解除された サンプルを使用したストリームのコピー」を参照してください。

2 つ以上のストリームを、圧縮されたサンプルを使用して 1 つのストリームに連結できますが、ビット レートが同じ場合に限られます。 プロセスは基本的に、以下で説明する手順と同じですが、必要なすべてのコンテンツを取得するには、複数の元のファイルを読み取る必要があります。 ただし、圧縮されたすべてのストリームの WM_MEDIA_TYPE 構造体 (すべての pbFormat 構造体メンバーを含む) が同じ場合にのみ、複数のファイルから 1 つのストリームに圧縮されたサンプルを書き込むことができます。 同じ形式ではない複数のストリームのデータを結合するには、コンテンツを圧縮解除し、変換先ストリームに再圧縮する必要があります。 さらに、2 つ以上のストリームのデータを 1 つのストリームに結合する場合は、すべてのストリームのバッファー ウィンドウ値をまとめて追加して、新しいストリームのバッファー ウィンドウを取得する必要があります。 これは、あるストリームの最後と別のストリームの先頭でどの程度のバッファーが占有されているかを判断できないためです。

IWMReaderAdvanced::SetReceiveStreamSamples を使用して、非同期リーダーを使用してストリーム サンプルを取得できます。 ストリーム サンプルは IWMReaderCallbackAdvanced::OnStreamSample に配信され、 IWMReaderCallback::OnSample には配信されません。 ファイルを読み取り、圧縮されたストリームと圧縮解除されたストリームを取得する場合は、両方のコールバック メソッドを実装する必要があります。

同期リーダーを使用すると、サンプルを取得する柔軟性が高くなります。 IWMSyncReader::SetReadStreamSamples を使用して、再生中に圧縮されたサンプルと圧縮解除されたサンプルを自由に切り替えることができます。

1 つの ASF ファイルから新しい ASF ファイルにストリーム全体をコピーするには、次の手順を実行します。 これらの手順では同期リーダーが使用されます。これは、この種の操作に使用する方がはるかに簡単であるためです。

  1. WMCreateSyncReader 関数を呼び出して、同期リーダー オブジェクトを作成します。
  2. IWMSyncReader::Open を呼び出してリーダーでファイルを開きます。
  3. IWMSyncReader::QueryInterface を呼び出して、同期リーダー オブジェクトの IWMProfile インターフェイスへのポインターを取得します。
  4. IWMProfile::GetStreamByNumber を呼び出して、目的のストリームのプロパティを取得します。 これにより、目的のストリームのストリーム構成オブジェクトの IWMStreamConfig インターフェイスへのポインターが取得されます。
  5. ストリームの WM_MEDIA_TYPE 構造体のコピーを取得します。 IWMMediaProps::GetMediaType を 2 回呼び出します。1 つ目は構造体のサイズを取得し、2 つ目は構造体自体を取得します。
  6. WMCreateProfileManager 関数を呼び出して、プロファイル マネージャー オブジェクトを作成します。
  7. IWMProfileManager::CreateEmptyProfile を呼び出して新しいプロファイルを作成します (または、ストリームを追加する既存のプロファイルを開きます)。 新しいプロファイルで IWMProfile::AddStream を呼び出して、既存のファイルからストリームを追加します。 ストリームを追加する場合は、手順 4 で取得した IWMStreamConfig ポインターを使用します。
  8. WMCreateWriter 関数を呼び出してライター オブジェクトを作成します。 IWMWriter::SetProfile を呼び出して、新しく作成したプロファイルをライターのアクティブ プロファイルとして設定します。 IWMWriter::SetOutputFilename を呼び出して、出力用のファイルを作成します。
  9. コピーするストリームまたはストリームに関連付けられている各入力について、IWMWriter::SetInputProps を呼び出し、IWMInputMediaProps インターフェイスに NULL を渡します。 これにより、渡すデータを検証する必要がないことをライター オブジェクトに通知します。 BeginWriting (手順 14) を呼び出す前にこの呼び出しを行う必要があります。そうしないと、読み取りオブジェクトがコンテンツをデコードできない可能性があります。
  10. fCompressed パラメーターを True に設定して IWMSyncReader::SetReadStreamSamples を呼び出して、選択したストリームの圧縮ストリーム サンプルを配信するように同期リーダーを設定します。
  11. コピーされるすべてのストリームのコーデック情報を取得し、書き込む前にコーデック情報をヘッダーに追加します。 コーデック情報を取得するには、 IWMHeaderInfo2::GetCodecInfoCountIWMHeaderInfo2::GetCodecInfo を呼び出して、リーダー内のファイルに関連付けられているコーデックを列挙します。 ストリーム構成に一致するコーデック情報を選択します。 次に、 IWMHeaderInfo3::AddCodecInfo を呼び出してライターにコーデック情報を設定し、リーダーから取得した情報を渡します。
  12. IWMWriter::QueryInterface を呼び出して、IWMWriterAdvanced インターフェイスへのポインターを取得します。
  13. IWMWriter::BeginWriting を呼び出してライターを書き込みモードに設定します。
  14. 目的のストリーム番号を指定して、 IWMSyncReader::GetNextSample を繰り返し呼び出します。 サンプルを受信したら、 IWMWriterAdvanced::WriteStreamSample を呼び出してライターに渡します。 ビデオ ストリームの場合は、GetNextSample の各呼び出しでライターによって設定されたフラグ (存在する場合) をチェックする必要があります。 WM_SF_CLEANPOINTが設定されている場合は、 WriteStreamSample の呼び出しでも設定する必要があります。
  15. 読み取りが完了したら、 IWMWriter::EndWriting を呼び出します。 ストリームを転送する必要があります。

Note

ストリーム サンプルを使用して、あるファイルから別のファイルにイメージ ストリームをコピーすることはできません。 イメージ ストリーム データをコピーするには、圧縮されていないサンプルを取得し、通常と同様にライターを介して処理します。

 

あるファイルから別のファイルへのデータのコピー

圧縮解除されたサンプルを使用したストリームのコピー