タスク条件の分析
mp3とは、MPEG-1 / 2 / 2.5レイヤー3を意味します。mp3ファイルとは何かを見てみましょう。
したがって、mp3ファイルは多くのフレームで構成され、フレームは相互に接続できます。つまり、1つのフレームをデコードするには、別のフレームを調べる必要がある場合があります。 ファイルには、オーディオデータの前後にタグが含まれる場合があります。 各フレームには1152サンプル(ステレオモードの場合)が保存され、26 msの持続時間があります。 フレームサイズは、使用されるビットレートとサンプリングレートによって異なり、次の式で計算されます。
パディングは、フレームヘッダー内の特別なフラグで、フレームが1バイトでパディングされることを意味します。
フレームは、ヘッダー、検証コード(オプション)、サンプルのデコードに必要な情報(このフレーズのロシア語の翻訳を受け入れられないため、この情報を「サイド情報」と呼びます)、実際にパックされたサンプル、およびエンコードされたサンプルとの直接的な関係:
32ビットヘッダーの構造は次のとおりです。
役職 | フィールド長 | 予定 |
---|---|---|
同期ワード | 11 | タイトルの検索に使用されます。 11ビットすべてが「1」に設定されます |
MPEGバージョン | 2 | |
レイヤーインデックス | 2 | |
少しの保護 | 1 | 設定されていない場合、フレームにはCRCが含まれます |
ビットレートインデックス | 4 | |
サンプルレートインデックス | 2 | |
パディングビット | 1 | フレームに1バイトが追加されたことを示す同じフラグ |
プライベートビット | 1 | 特定の情報を保持します。 |
チャネルコーディングモード | 2 | モノラル、ステレオ、ジョイントステレオ、デュアルチャネル |
モード拡張 | 2 | ジョイントステレオチャネルエンコーディングモードで使用 |
著作権ビット | 1 | このビットが設定されている場合、ファイルのコピーは違法であることを意味します |
元のビット | 1 | このビットが設定されている場合、ファイルが元のメディアにあることを意味します |
アクセント(強調) | 2 | 追加のオーディオ処理が必要であることをデコーダに伝えます |
実際には、一部のヘッダーフィールドは使用されず、かつ/またはmp3ファイル全体で同じままです。 たとえば、MPEGバージョン、レイヤーインデックス、プライベートビット、著作権ビット、元のビットなど。 ファイルが固定ビットレート(CBR)を使用して作成された場合、ビットレートインデックスフィールドは変更されません。
最初に考えたのは、フレームのすべてのヘッダーフィールドを保存する必要はなく、ファイル全体で変化するヘッダーフィールドのみを保存する必要があるということです。 残りのフィールドは、フィールドの変更ではなく、1回のみ保存できます。 すべてのフレームのヘッダーを調べて、統計を収集し、実際に使用されているフィールドを特定できます。
CRC検証コードは、ヘッダーのすぐ後ろにあります。 フレームヘッダーの最後の16ビットとすべてのサイド情報バイトに対してCRC16アルゴリズムを使用して計算される16ビット整数です。
2番目の考えは、検証コードの計算方法がわかっているため、保存できないことです。 もちろん、フレームからCRCを取り出して捨てる権利はありません。 最初に、エラーが検証コード自体または計算されるバイトに侵入する可能性があるため、それが正しい値を表していることを確認する必要があります。
サイド情報の詳細については詳しく説明しません。 サイド情報は、各フレームで変化する多くのフィールドを持つかなり複雑な構造です。 フレームヘッダーフィールドと同じように、サイドインフォメーションフィールドでも同じトリックを実行することはできません。
サイド情報の後には、ハフマン圧縮オーディオデータが続きます。 実際、ハフマンコードはスケールファクターと交互に変化するため、これは完全に真実ではありませんが、簡単にするために、サイド情報の後、フレームの最後までオーディオデータが配置されると仮定します。
このデータ間にフレームヘッダーシグネチャ(同期ワード)がない場合のみ、他のデータがフレーム間にある可能性があります。
アルゴリズム
7-Zipのソースコードを調べた後、実行可能ファイル(* .exe、* .dll)の圧縮を改善するために設計されたBCJ2フィルターの実装に出会いました。 このフィルターの特徴は、1つの入力と4つの出力があることです。 各出力には独自のエンコーダがあります。 したがって、入力ファイルは4つのストリームに分割され、各ストリームは独自のエンコーダーで圧縮されていることがわかります。
いくつかのexitのアイデアが気に入ったので、フィルターに適用することにしました。
-最初の考えに従って、フレームヘッダーフィールドを1つのストリームにパックする
-2番目のストリームのサイド情報をパックする
-最後に、3番目のストリームで、残りの情報(ハフマンのタグとコード)をパックします
最初の2つのストリームは、アーカイブヘッダーを圧縮するために7-Zip内で使用される設定でLZMAアルゴリズムを使用して圧縮され、3番目のストリームは[アーカイブに追加]ウィンドウでユーザーが選択したアルゴリズムによって圧縮されます。
エンコーダは次のように機能します。ファイルのすべてのフレームが順番に検索されます。 フレームは3つの部分に分かれています。サイド情報はサイド情報ストリームに送信され、ハフマンコードはメイン出力ストリームに送信され、ヘッダーフィールドはバッファに保存されます。 フレームにCRCが存在し、それが真であることが判明した場合、スキップされます。それ以外の場合、その値はアンパック時に復元できるようにヘッダーストリームに転送されます。
各ヘッダーの同期ワード(11ビット)は、単に破棄されます。 ファイル中に変更されなかったフィールドの値は、ヘッダーストリームに1回だけ書き込まれますが、変更フィールドは次々に順番に書き込まれます。
デコーダーはエンコーダーにミラーリングされて機能します。まず、すべてのヘッダーが復元され、次に各フレームの復元が開始されます。 最初のCRCストリームから計算または復元され、その後にサイド情報とフレームの残りが続きます。
実装と実際の結果
実装は特に複雑ではないため、ここに実装する意味はわかりません。 githubに投稿されたソース。 7-Zipでのそのようなフィルター(1つの入力と複数の出力)のサポートが十分に透過的に実装されていないことに注意してください。 はい、ところで、フィルターを開発するとき、7-Zip 9.20のソースが使用されました。
コンパイルされたdllは同じgithubにあります。 彼女は、7-Zipをインストールしたフォルダー内の7z.dllを置き換える必要があります。
作業のテストは、Windows XPオペレーティングシステム、Intel Core 2 6700プロセッサ(2.66 GHz)、および3ギガバイトのRAMを搭載したコンピューターで、総容量16755839778バイト(15.605 GB)の1351ファイルのサンプルで実行されました。 各ファイルは個別にアーカイブに圧縮され、解凍されました。 まず、フィルターを使用せずに、次にフィルターを使用します。 すべての場所でUltra圧縮レベルが使用されました。
フィルターなし | フィルター付き | |
---|---|---|
圧縮データの総量 | 16300442691バイト(15.181 GB) | 16064243440バイト(14.961 GB) |
パッケージングに費やした合計時間 | 12181.09秒 | 11273.47秒 |
開梱にかかった合計時間 | 3215.44秒 | 2744.76秒 |
保存できるフィルター:
-ハードドライブ上の236199251バイト(〜225 MB)のメモリ
-パッケージで908秒(〜15分)
-開梱で407秒(〜8分)
ご覧のように、パッケージング速度は8%増加し、解凍速度は最大15%増加しました。
おわりに
このフィルターにより、mp3ファイルの圧縮率が1.5%向上しました。 フィルターは圧縮データで機能するため、この結果は未解決とは言えませんが、悪いとも言えません。
以上です。 ご清聴ありがとうございました。