Bagikan melalui


Menghasilkan Paket Data ASF Baru

Multiplexer ASF adalah komponen lapisan WMContainer yang bekerja dengan Objek Data ASF dan memberi aplikasi kemampuan untuk menghasilkan paket data ASF untuk aliran yang cocok dengan persyaratan yang ditentukan dalam objek ContentInfo.

Multiplexer memiliki satu input dan satu output. Ini menerima sampel aliran yang berisi data media digital dan menghasilkan satu atau beberapa paket data yang dapat ditulis ke kontainer ASF.

Daftar berikut ini merangkum proses pembuatan paket data ASF:

  1. Teruskan data input ke multiplexer di IMFASFMultiplexer::P rocessSample.
  2. Kumpulkan paket data dengan memanggil IMFASFMultiplexer::GetNextPacket dalam perulangan hingga semua paket lengkap telah diambil.
  3. Setelah data input dikonversi menjadi paket lengkap, mungkin ada beberapa data yang tertunda di multiplexer, yang tidak diambil oleh GetNextPacket. Panggil IMFASFMultiplexer::Flush untuk mengemas sampel yang tertunda dan mengumpulkannya dari multiplexer dengan memanggil GetNextPacket lagi.
  4. Perbarui Objek Header ASF terkait dengan memanggil IMFASFMultiplexer::End untuk mencerminkan perubahan yang dibuat oleh multiplexer selama pembuatan paket data.

Diagram berikut mengilustrasikan pembuatan paket data untuk file ASF melalui multiplexer.

diagram showing data packet generation for an asf file

Pembuatan Paket Data ASF

Setelah membuat dan menginisialisasi multiplexer seperti yang dijelaskan dalam Membuat Objek Multiplexer, panggil IMFASFMultiplexer::P rocessSample untuk meneruskan data input ke multiplexer untuk diproses ke dalam paket data. Input yang ditentukan harus dalam sampel media (antarmuka IMFSample ) yang dapat memiliki satu atau beberapa buffer media (antarmuka IMFMediaBuffer ) yang berisi data untuk aliran. Dalam kasus transcoding ASF-ke-ASF, sampel media input dapat dihasilkan dari pemisah yang membuat sampel aliran yang dikemas. Untuk informasi selengkapnya, lihat Pemisah ASF.

Sebelum memanggil ProcessSample, pastikan bahwa stempel waktu sampel media input adalah waktu presentasi yang valid; jika tidak , ProcessSample gagal dan mengembalikan kode MF_E_NO_SAMPLE_TIMESTAMP.

Multiplexer dapat menerima input sebagai sampel media terkompresi atau tidak terkompresi melalui ProcessSample. Multiplexer menetapkan waktu pengiriman ke sampel ini tergantung pada penggunaan bandwidth aliran. Selama proses ini, multiplexer memeriksa parameter wadah bocor (laju bit dan pemanfaatan jendela buffer) dan dapat menolak sampel yang tidak mematuhi nilai-nilai tersebut. Sampel media input dapat gagal dalam pemeriksaan bandwidth karena salah satu alasan berikut:

  • Jika sampel media input datang terlambat karena waktu pengiriman yang ditetapkan terakhir lebih besar dari stempel waktu pada sampel media ini. ProcessSample gagal dan mengembalikan kode kesalahan MF_E_LATE_SAMPLE .
  • Jika stempel waktu pada sampel media input lebih awal dari waktu pengiriman yang ditetapkan (ini menunjukkan luapan buffer). Multiplexer dapat mengabaikan situasi ini jika dikonfigurasi untuk menyesuaikan laju bit dengan mengatur bendera MFASF_MULTIPLEXER_AUTOADJUST_BITRATE selama inisialisasi multiplexer. Untuk informasi selengkapnya, lihat "Inisialisasi Multiplexer dan Pengaturan Wadah Bocor" dalam Membuat Objek Multiplexer. Jika bendera ini tidak diatur dan multiplexer mengalami overrun bandwidth, ProcessSample gagal dan mengembalikan kode kesalahan MF_E_BANDWIDTH_OVERRUN .

Setelah multiplexer menetapkan waktu pengiriman, sampel media input ditambahkan ke jendela kirim—daftar sampel media input yang diurutkan berdasarkan waktu pengiriman dan siap diproses ke dalam paket data. Selama konstruksi paket data, sampel media input diurai dan data yang relevan ditulis ke paket data sebagai payload. Paket data lengkap dapat berisi data dari satu atau beberapa sampel media input.

Ketika sampel media input baru tiba di jendela kirim, sampel tersebut ditambahkan ke antrean hingga ada cukup sampel media untuk membentuk satu paket lengkap. Data dalam buffer media yang terkandung oleh sampel media input tidak disalin ke paket data yang dihasilkan. Paket data menyimpan referensi ke buffer media input sampai sampel media input telah sepenuhnya dikemas dan paket lengkap telah dikumpulkan dari multiplekser.

Ketika paket data lengkap tersedia, paket tersebut dapat diambil dengan memanggil IMFASFMultiplexer::GetNextPacket. Jika Anda memanggil ProcessSample saat ada paket lengkap yang siap diambil, paket gagal dan mengembalikan kode kesalahan MF_E_NOTACCEPTING . Ini menunjukkan bahwa multiplexer tidak dapat menerima lebih banyak input dan Anda harus memanggil GetNextPacket untuk mengambil paket tunggu. Idealnya, setiap panggilan ProcessSample harus diikuti oleh satu atau beberapa panggilan GetNextPacket untuk mendapatkan paket data lengkap. Mungkin perlu lebih dari satu sampel media input untuk membuat paket data lengkap. Sebaliknya, data dalam satu sampel media input mungkin mencakup beberapa paket. Oleh karena itu, tidak semua panggilan ke ProcessSample akan menghasilkan sampel media output.

Jika sampel media input berisi bingkai kunci yang ditunjukkan oleh atribut MFSampleExtension_CleanPoint , multiplexer menyalin atribut ke paket.

Mendapatkan Paket Data ASF

Untuk mengumpulkan sampel media output untuk paket data lengkap yang dihasilkan oleh multiplexer, panggil IMFASFMultiplexer::GetNextPacket dalam perulangan hingga tidak ada lagi sampel media output yang tersisa untuk paket. Berikut ini mencantumkan kasus keberhasilan:

  • Jika ada paket data lengkap yang tersedia, GetNextPacket menerima bendera ASF_STATUS_FLAGS_INCOMPLETE dalam parameter pdwStatusFlags ; parameter ppIPacket menerima pointer ke paket data pertama. Anda harus memanggil metode ini selama menerima bendera ini. Dengan setiap iterasi, ppIPacket menunjuk ke paket berikutnya dalam antrean.
  • Jika hanya ada satu paket data, ppIPacket menunjuk ke sana dan bendera ASF_STATUS_FLAGS_INCOMPLETE tidak diterima di pdwStatusFlags.
  • GetNextPacket dapat berhasil tanpa menghasilkan paket data apa pun jika multiplexer masih dalam proses pengemasan dan penambahan paket data. Dalam hal ini, ppIPacket menunjuk ke NULL. Untuk melanjutkan, Anda harus menyediakan multiplexer dengan lebih banyak sampel media input dengan memanggil ProcessSample.

Contoh kode berikut menunjukkan fungsi yang menghasilkan paket data dengan menggunakan multiplexer. Konten paket data yang dihasilkan akan ditulis ke aliran byte data yang dialokasikan oleh pemanggil.

//-------------------------------------------------------------------
// GenerateASFDataPackets
// 
// Gets data packets from the mux. This function is called after 
// calling IMFASFMultiplexer::ProcessSample. 
//-------------------------------------------------------------------

HRESULT GenerateASFDataPackets( 
    IMFASFMultiplexer *pMux, 
    IMFByteStream *pDataStream
    )
{
    HRESULT hr = S_OK;

    IMFSample *pOutputSample = NULL;
    IMFMediaBuffer *pDataPacketBuffer = NULL;

    DWORD dwMuxStatus = ASF_STATUSFLAGS_INCOMPLETE;

    while (dwMuxStatus & ASF_STATUSFLAGS_INCOMPLETE)
    {
        hr = pMux->GetNextPacket(&dwMuxStatus, &pOutputSample);

        if (FAILED(hr))
        {
            break;
        }

        if (pOutputSample)
        {
            //Convert to contiguous buffer
            hr = pOutputSample->ConvertToContiguousBuffer(&pDataPacketBuffer);
            
            if (FAILED(hr))
            {
                break;
            }

            //Write buffer to byte stream
            hr = WriteBufferToByteStream(pDataStream, pDataPacketBuffer, NULL);

            if (FAILED(hr))
            {
                break;
            }
        }

        SafeRelease(&pDataPacketBuffer);
        SafeRelease(&pOutputSample);
    }

    SafeRelease(&pOutputSample);
    SafeRelease(&pDataPacketBuffer);
    return hr;
}

Fungsi WriteBufferToByteStream ini ditampilkan dalam topik IMFByteStream::Write.

Untuk melihat aplikasi lengkap yang menggunakan contoh kode ini, lihat Tutorial: Menyalin Aliran ASF dari Satu File ke File Lainnya.

Memposting Panggilan Packet-Generation

Untuk memastikan bahwa tidak ada paket data lengkap yang menunggu di multiplexer, panggil IMFASFMultiplexer::Flush. Ini memaksa multiplexer untuk mengemas semua sampel media yang sedang berlangsung. Aplikasi dapat mengumpulkan paket-paket ini dalam bentuk sampel media melalui GetNextPacket dalam perulangan sampai tidak ada lagi paket yang tersisa untuk diambil.

Setelah semua sampel media dihasilkan, panggil IMFASFMultiplexer::End untuk memperbarui Objek Header ASF yang terkait dengan paket data ini. Objek Header ditentukan dengan meneruskan objek ContentInfo yang digunakan untuk menginisialisasi multiplexer. Panggilan ini memperbarui berbagai Objek Header untuk mencerminkan perubahan yang dibuat oleh multiplexer selama pembuatan paket data. Informasi ini mencakup jumlah paket, durasi pengiriman, durasi pemutaran, dan nomor streaming semua aliran. Ukuran header keseluruhan juga diperbarui.

Anda harus memastikan bahwa Akhir dipanggil setelah semua paket data diambil. Jika ada paket yang menunggu di multiplexer, End akan gagal dan mengembalikan kode kesalahan MF_E_FLUSH_NEEDED . Dalam hal ini, dapatkan paket tunggu dengan memanggil Flush dan GetNextPacket dalam perulangan.

Catatan

Untuk pengodean VBR, setelah memanggil Akhir, Anda harus mengatur statistik pengodean di properti pengodean objek ContentInfo. Untuk informasi tentang proses ini, lihat "Mengonfigurasi Objek ContentInfo dengan Encoder Pengaturan" di Mengatur Properti di Objek ContentInfo. Daftar berikut ini memperlihatkan properti tertentu yang akan diatur:

 

ASF Multiplexer

Tutorial: Menyalin Aliran ASF dari Satu File ke File Lainnya

Tutorial: Menulis File WMA dengan Menggunakan Pengodean CBR