Software decoding — กระบวนการบีบอัดข้อมูลมัลติมีเดียโดย CPU ผ่านไลบรารีซอฟต์แวร์ โดยไม่ใช้บล็อกฮาร์ดแวร์ของ SoC ตัวถอดรหัสซอฟต์แวร์ถูกนำมาใช้เป็นไลบรารีข้ามแพลตฟอร์ม: FFmpeg กับ libavcodec และ dav1d สำหรับ AV1 ตาม เอกสาร FFmpeg (2026), libavcodec รองรับโคเดกมากกว่า 200 ตัว ทำให้ software decoding เป็นวิธีเดียวในการเล่นรูปแบบที่หายาก
ประเด็นสำคัญ
Software decoding เป็นวิธีการขยายข้อมูลมัลติมีเดียที่การดำเนินการคำนวณทั้งหมดดำเนินการบนคอร์ CPU ที่ใช้งานทั่วไป ต่างจากการถอดรหัสฮาร์ดแวร์ที่แต่ละโคเดกมีบล็อกทางกายภาพเฉพาะ ตัวถอดรหัสซอฟต์แวร์เป็นโค้ดปกติที่ดำเนินการอัลกอริทึมเดียวกันโดยใช้คำสั่งของโปรเซสเซอร์
ตัวถอดรหัสซอฟต์แวร์เขียนด้วยภาษา C/C++ โดยมีการปรับให้เหมาะสมสำหรับสถาปัตยกรรม CPU เฉพาะ: คำสั่ง SIMD ARM NEON สำหรับอุปกรณ์มือถือ, Intel SSE/AVX สำหรับเดสก์ท็อป ไลบรารี libavcodec จาก FFmpeg มีโค้ดแอสเซมบลีที่ปรับให้เหมาะสมนับหมื่นบรรทัดสำหรับแพลตฟอร์มต่างๆ ทำให้การถอดรหัสซอฟต์แวร์มีประสิทธิภาพที่ดีแม้สำหรับรูปแบบหนักเช่น AV1 บน CPU ที่ทรงพลัง
ข้อได้เปรียบหลักของการถอดรหัสซอฟต์แวร์คือความอเนกประสงค์ หากตัวถอดรหัสฮาร์ดแวร์รองรับเพียง 4–5 รูปแบบหลัก (H.264, H.265, VP9, AV1) FFmpeg สามารถถอดรหัสโคเดกได้มากกว่า 200 ตัว: ตั้งแต่ AV1 และ H.265 ที่ทันสมัยไปจนถึง Sorenson Spark, RealVideo และ Motion JPEG แบบเก่า ทำให้การถอดรหัสซอฟต์แวร์เป็นเครื่องมือที่ขาดไม่ได้สำหรับแอปพลิเคชันที่ทำงานกับข้อมูลมัลติมีเดียที่ไม่ได้มาตรฐาน — เช่น โปรแกรมตัดต่อวิดีโอระดับมืออาชีพ ระบบเฝ้าระวังวิดีโอ และเครื่องเล่นเฉพาะทาง
การถอดรหัสซอฟต์แวร์เป็นไปตามขั้นตอนเดียวกับการถอดรหัสฮาร์ดแวร์ แต่บน CPU ที่ใช้งานทั่วไป แต่ละขั้นตอนถูกนำมาใช้เป็นฟังก์ชันที่ถูกเรียกตามลำดับสำหรับแต่ละมาโครบล็อกหรือเฟรม ความแตกต่างที่สำคัญคือความยืดหยุ่น: นักพัฒนาสามารถปรับเปลี่ยนไพพลายน์ เพิ่มฟิลเตอร์และการประมวลผลภายหลังระหว่างขั้นตอนการถอดรหัส
ตัวถอดรหัสซอฟต์แวร์ทั่วไปประกอบด้วยโมดูลที่ดำเนินการตามขั้นตอนอัลกอริทึมแต่ละขั้น โมดูลถอดรหัสเอนโทรปี อ่านบิตสตรีมและสร้างสัมประสิทธิ์ DCT ที่ควอนไทซ์ขึ้นมาใหม่ สำหรับ H.264 โมดูลนี้ใช้ CABAC (การเข้ารหัสเลขคณิตแบบไบนารีที่ปรับตามบริบท) — อัลกอริทึมที่ซับซ้อนที่มีการแยกเงื่อนไขซึ่งเร่งความเร็วด้วยฮาร์ดแวร์ได้ยาก แต่ทำงานได้อย่างมีประสิทธิภาพบน CPU ที่มีตัวทำนายสาขาที่ดี
โมดูลควอนไทเซชันผกผันคูณสัมประสิทธิ์ด้วยขั้นตอนควอนไทเซชัน และโมดูล DCT ผกผันใช้การแปลงโคไซน์ไม่ต่อเนื่อง การใช้งานซอฟต์แวร์ของ DCT ผกผันใช้อัลกอริทึม Chen แบบเร็วหรืออัลกอริทึม Loeffler ซึ่งลดจำนวนการดำเนินการคูณ-สะสมจาก 4096 เหลือ 256 สำหรับบล็อก 8x8 คำสั่ง SIMD NEON (ARM) หรือ SSE (x86) ช่วยให้ประมวลผลสัมประสิทธิ์ 4–8 ตัวต่อคำสั่ง ให้ความเร็วเพิ่มขึ้น 4–8 เท่าเมื่อเทียบกับโค้ดสเกลาร์
โมดูลชดเชยการเคลื่อนไหวเป็นโมดูลที่ใช้หน่วยความจำมากที่สุด มันแยกพื้นที่จากเฟมอ้างอิงตามเวกเตอร์การเคลื่อนไหวและใช้การประมาณค่าระดับย่อยพิกเซล สำหรับ H.265 ความแม่นยำของการประมาณค่าถึง 1/8 พิกเซล ซึ่งต้องใช้ ฟิลเตอร์ FIR 8 แทป สำหรับความสว่าง และ 4 แทปสำหรับสี การใช้งานซอฟต์แวร์ต้องโหลดข้อมูลเฟมอ้างอิงจำนวนมากจากแคช ทำให้การชดเชยการเคลื่อนไหวเป็นคอขวดเมื่อถอดรหัสความละเอียดสูงบน CPU
โปรเซสเซอร์มือถือสมัยใหม่ เช่น Apple A17 หรือ Qualcomm Snapdragon 8 Gen 2 มี 6–8 คอร์ที่มีประสิทธิภาพเพียงพอสำหรับการถอดรหัสซอฟต์แวร์ 1080p H.264 โดยไม่สูญเสียเฟรม อย่างไรก็ตาม สำหรับเนื้อหา 4K โดยเฉพาะในรูปแบบ H.265 และ AV1 การถอดรหัสซอฟต์แวร์บน CPU อาจมีปัญหา: โหลดทั่วไปบนทุกคอร์สูงถึง 70–90% ซึ่งสำคัญสำหรับการทำงานหลายอย่างพร้อมกัน คอร์ขนาดใหญ่ (Apple Performance, Qualcomm Kryo Prime) ให้ประสิทธิภาพ ~4–5 เท่าเมื่อเทียบกับคอร์ประหยัดพลังงานขนาดเล็ก แต่กินพลังงานมากกว่าตามสัดส่วน
ตลาดตัวถอดรหัสซอฟต์แวร์มีไลบรารีหลักหลายตัว แต่ละตัวปรับให้เหมาะสมสำหรับกลุ่มของตัวเอง การเลือกตัวถอดรหัสขึ้นอยู่กับรูปแบบที่ต้องการ แพลตฟอร์ม และข้อจำกัดด้านใบอนุญาต
FFmpeg เป็นมาตรฐานโดยพฤตินัยสำหรับการถอดรหัสซอฟต์แวร์ในอุตสาหกรรม ไลบรารี libavcodec มีตัวถอดรหัสสำหรับโคเดกหลักทั้งหมดและโคเดกหายากส่วนใหญ่ รองรับคอนเทนเนอร์ทั้งหมด (MP4, MKV, AVI, MOV, WebM) และทำงานบนทุกแพลตฟอร์ม FFmpeg ได้รับใบอนุญาตภายใต้ LGPL/GPL ซึ่งต้องปฏิบัติตามเงื่อนไขใบอนุญาตสำหรับการใช้ในเชิงพาณิชย์ บนอุปกรณ์มือถือ FFmpeg ถูกใช้ผ่านตัวหุ้ม: ffmpeg-kit สำหรับ iOS และ Android, mobile-ffmpeg สำหรับ React Native
Dav1d เป็นตัวถอดรหัส AV1 ซอฟต์แวร์จาก VideoLAN (ผู้พัฒนา VLC) เขียนด้วยภาษา C โดยมีการปรับปรุง SIMD เป้าหมายหลักคือการถอดรหัส AV1 ซอฟต์แวร์ที่เร็วที่สุดเท่าที่เป็นไปได้บน CPU ที่ไม่มีการสนับสนุนฮาร์ดแวร์ Dav1d เร็วกว่าตัวถอดรหัสอ้างอิง libaom จาก Alliance for Open Media 30–50% เนื่องจากการปรับปรุงเชิงรุก: การจัดการแคชด้วยตนเอง, การคอมไพล์ JIT สำหรับฟิลเตอร์ประมวลผลภายหลัง และการทำเวกเตอร์ของฟังก์ชันสำคัญ
บนอุปกรณ์มือถือ dav1d สามารถถอดรหัส 1080p AV1 แบบเรียลไทม์บน SoC ระดับเรือธง (Apple A16+, Snapdragon 8 Gen 2+) แต่ 4K ต้องใช้ CPU ที่ทรงพลัง ตัวอย่างเช่น บน Apple M1, dav1d ซอฟต์แวร์ให้ ~60 FPS สำหรับ 4K AV1 ในขณะที่บน Snapdragon 8 Gen 2 ให้ ~35 FPS สำหรับการเล่น 4K AV1 ที่เสถียรบนอุปกรณ์มือถือ ยังคงแนะนำให้ใช้การสนับสนุนฮาร์ดแวร์
| ตัวถอดรหัส | รูปแบบ | แพลตฟอร์ม | ใบอนุญาต |
|---|---|---|---|
| libavcodec | 200+ โคเดก | ทั้งหมด | LGPL/GPL |
| dav1d | AV1 | ทั้งหมด | BSD 2-Clause |
| libaom | AV1 | ทั้งหมด | BSD 2-Clause |
| MediaFoundation | H.264, H.265 | Windows | กรรมสิทธิ์ |
การเลือกระหว่างการถอดรหัสซอฟต์แวร์และฮาร์ดแวร์เป็นการแลกเปลี่ยนระหว่างความเข้ากันได้และประสิทธิภาพ ตารางด้านล่างให้การเปรียบเทียบรายละเอียดของคุณลักษณะสำคัญ
| พารามิเตอร์ | Software Decoding | Hardware Decoding |
|---|---|---|
| รูปแบบที่รองรับ | 200+ โคเดก | 4–6 โคเดก |
| การใช้พลังงาน | 1.5–5 W | 0.2–0.8 W |
| การปรับแต่ง | ควบคุมไพพลายน์ได้เต็มที่ | ผ่าน API เท่านั้น |
| ความหน่วง | 30–80 ms | 5–15 ms |
| การระบายความร้อน | สูง (45–50 C) | ต่ำ (35–40 C) |
| การอัปเดตโคเดก | ผ่านการอัปเดตไลบรารี | เฉพาะกับ SoC ใหม่ |
การถอดรหัสซอฟต์แวร์ ให้ความยืดหยุ่นสูงสุด: นักพัฒนาสามารถปรับเปลี่ยนอัลกอริทึม เพิ่มฟิลเตอร์แบบกำหนดเอง และใช้ไพพลายน์การประมวลผลของตัวเอง ตัวอย่างเช่น ในแอปพลิเคชันตัดต่อวิดีโอ แต่ละขั้นตอนการถอดรหัสสามารถเปลี่ยนเส้นทางไปยัง GPU สำหรับการแก้ไขสีหรือการซ้อนทับเอฟเฟกต์ — ซึ่งเป็นไปได้เฉพาะเมื่อมีการควบคุมซอฟต์แวร์เหนือการถอดรหัส
อย่างไรก็ตาม ราคาของความยืดหยุ่นคือการใช้พลังงาน สำหรับอุปกรณ์มือถือที่มีแบตเตอรี่ 3000–5000 mAh การถอดรหัสซอฟต์แวร์อย่างต่อเนื่องลดเวลาในการรับชมจาก 10–15 ชั่วโมง (ฮาร์ดแวร์) เหลือ 2–4 ชั่วโมง CPU ร้อนขึ้นถึง 45–50 องศาสามารถทำให้เกิด throttling — การลดความถี่ของโปรเซสเซอร์เพื่อป้องกันความร้อนสูงเกินไป ซึ่งนำไปสู่การตกเฟรมและประสบการณ์ผู้ใช้ที่แย่ลง
มาดูการนำการถอดรหัสซอฟต์แวร์ไปใช้จริงบนทั้งสองแพลตฟอร์มมือถือ บน iOS การถอดรหัสซอฟต์แวร์ใช้ผ่าน FFmpeg และบน Android — ผ่านไลบรารีเดียวกันกับตัวหุ้ม Java/Kotlin
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
}
class SoftwareDecoder {
AVCodecContext* codecCtx;
public:
bool init(const char* filename) {
AVFormatContext* fmtCtx = nullptr;
avformat_open_input(&fmtCtx, filename, nullptr, nullptr);
avformat_find_stream_info(fmtCtx, nullptr);
int videoStream = av_find_best_stream(
fmtCtx, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0
);
AVCodec* decoder = avcodec_find_decoder(
fmtCtx->streams[videoStream]->codecpar->codec_id
);
codecCtx = avcodec_alloc_context3(decoder);
avcodec_parameters_to_context(codecCtx,
fmtCtx->streams[videoStream]->codecpar);
avcodec_open2(codecCtx, decoder, nullptr);
return true;
}
AVFrame* decodePacket(AVPacket* packet) {
avcodec_send_packet(codecCtx, packet);
AVFrame* frame = av_frame_alloc();
int ret = avcodec_receive_frame(codecCtx, frame);
return (ret >= 0) ? frame : nullptr;
}
};
โค้ดแสดงไพพลายน์ FFmpeg ขั้นต่ำสำหรับการถอดรหัสซอฟต์แวร์ avformat_open_input เปิดไฟล์และกำหนดรูปแบบคอนเทนเนอร์, avcodec_find_decoder ค้นหาตัวถอดรหัสที่เหมาะสมสำหรับโคเดกใดๆ โดยอัตโนมัติ เมธอด decodePacket ใช้ API ใหม่ (avcodec_send_packet / avcodec_receive_frame) ซึ่งรองรับการถอดรหัสแบบหลายเธรดโดยเปิดใช้แฟลก AV_CODEC_FLAG_LOW_DELAY สำหรับแอปพลิเคชันแบบเรียลไทม์
class SoftwareDecoder(private val context: Context) {
fun decodeVideo(inputPath: String, outputFolder: String) {
val cmd = "-i $inputPath -vf fps=1 $outputFolder/frame_%04d.jpg"
FFmpegExecutor(context).executeCommand(cmd) { rc ->
Log.d("Decoder", "Finished with rc: $rc")
}
}
fun getFrameCount(filePath: String): Int {
val probe = MediaMetadataRetriever()
probe.setDataSource(filePath)
val duration = probe.extractMetadata(
MediaMetadataRetriever.METADATA_KEY_DURATION
)?.toIntOrNull() ?: 0
val fps = probe.extractMetadata(
MediaMetadataRetriever.METADATA_KEY_VIDEO_FRAME_COUNT
)?.toIntOrNull() ?: 0
probe.release()
return fps
}
}
ตัวอย่าง Kotlin ใช้ FFmpegExecutor เพื่อแยกหนึ่งเฟรมต่อวินาทีจากวิดีโอ พารามิเตอร์ -vf fps=1 สร้างฟิลเตอร์ที่ข้าม 59 เฟรมจาก 60 เฟรม ลดภาระของ CPU วิธีการนี้มีประโยชน์สำหรับการสร้างตัวอย่างและตัวยึดตำแหน่งในแอปพลิเคชันมือถือ สำหรับการถอดรหัสซอฟต์แวร์แบบเรียลไทม์ แนะนำให้ใช้ API ระดับต่ำของ libavcodec โดยตรงผ่าน JNI
#include <dav1d/dav1d.h>
int decode_av1_frame(const uint8_t* data, size_t size) {
Dav1dContext* ctx = nullptr;
Dav1dSettings settings = { 0 };
dav1d_default_settings(&settings);
settings.n_threads = 4;
dav1d_open(&ctx, &settings);
Dav1dData dav1d_data = { 0 };
dav1d_data_wrap(&dav1d_data, data, size, nullptr, nullptr);
Dav1dPicture pic = { 0 };
if (dav1d_send_data(ctx, &dav1d_data) == 0) {
dav1d_get_picture(ctx, &pic);
}
dav1d_close(&ctx);
return pic.p.w;
}
Dav1d มี API ที่เรียบง่าย: dav1d_open สร้างบริบทตัวถอดรหัสด้วยจำนวนเธรดที่ระบุ, dav1d_send_data รับบิตสตรีมที่บีบอัด, dav1d_get_picture ส่งคืนเฟรมที่ถอดรหัสแล้วในรูปแบบ YUV420 สำหรับอุปกรณ์มือถือ จำนวนเธรดที่เหมาะสม (n_threads) คือจำนวนคอร์ CPU ที่มีประสิทธิภาพลบหนึ่ง เพื่อให้ทรัพยากรสำหรับเธรดอินเทอร์เฟซผู้ใช้ Dav1d ยังรองรับ Dav1dPicAllocator สำหรับการจัดการหน่วยความจำและหลีกเลี่ยงการคัดลอกที่ไม่จำเป็นเมื่อถ่ายโอนเฟรมไปยัง GPU
แม้จะใช้พลังงานสูงกว่า แต่การถอดรหัสซอฟต์แวร์ก็ขาดไม่ได้ในหลายสถานการณ์ที่การถอดรหัสฮาร์ดแวร์ไม่สามารถให้ฟังก์ชันการทำงานที่ต้องการได้ การทำความเข้าใจสถานการณ์เหล่านี้ช่วยให้นักพัฒนาตัดสินใจด้านสถาปัตยกรรม
ตัวถอดรหัสฮาร์ดแวร์รองรับเฉพาะรูปแบบที่ทันสมัยเท่านั้น หากแอปพลิเคชันทำงานกับการบันทึกที่เก็บถาวร การเฝ้าระวังวิดีโอ (MJPEG, H.263), โคเดกระดับมืออาชีพ (ProRes, DNxHD, CineForm) หรือเนื้อหาจากแหล่งภายนอก — การถอดรหัสซอฟต์แวร์ผ่าน FFmpeg จะเป็นตัวเลือกเดียว ProRes ถอดรหัสด้วยซอฟต์แวร์เท่านั้นบนอุปกรณ์ทั้งหมดยกเว้นชิป Apple A13+ ที่มีการสนับสนุนฮาร์ดแวร์ สำหรับ H.263 ไม่มีการสนับสนุนฮาร์ดแวร์บน SoC สมัยใหม่ใดๆ — มีเพียงการถอดรหัสซอฟต์แวร์
การถอดรหัสซอฟต์แวร์ให้การเข้าถึงเต็มรูปแบบในแต่ละขั้นตอนการประมวลผลเฟรม นี่เป็นสิ่งสำคัญสำหรับแอปพลิเคชันที่ต้องใช้ฟิลเตอร์ (เบลอ, ลดสัญญาณรบกวน, คมชัด) โดยตรงกับข้อมูลที่ถอดรหัสแล้วก่อนส่งออก ฟิลเตอร์ FFmpeg ช่วยให้สร้างลูกโซ่ที่ซับซ้อน: การถอดรหัส -> การแก้ไขสี -> การปรับขนาด -> การซ้อนทับคำบรรยาย -> การเข้ารหัส — ทั้งหมดภายในไลบรารีเดียวโดยไม่ต้องถ่ายโอนข้อมูลระหว่าง API ต่างๆ
สถาปัตยกรรมเครื่องเล่นมีเดียที่แนะนำคือแบบไฮบริด: การถอดรหัสฮาร์ดแวร์เป็นหลัก การถอดรหัสซอฟต์แวร์เป็นตัวสำรอง ก่อนการเล่น แอปพลิเคชันตรวจสอบความพร้อมของตัวถอดรหัสฮาร์ดแวร์สำหรับโคเดกที่กำหนด หากไม่พบตัวถอดรหัส การถอดรหัสซอฟต์แวร์จะเริ่มผ่าน FFmpeg กลยุทธ์นี้ รับประกันความเข้ากันได้สูงสุดโดยไม่เสียสละประสิทธิภาพสำหรับรูปแบบหลัก ควรตรวจสอบความพร้อมใช้งานทุกครั้งที่เริ่มต้น เนื่องจากการสนับสนุนฮาร์ดแวร์อาจแตกต่างกันแม้ในอุปกรณ์รุ่นเดียวกันเนื่องจากการแก้ไข SoC ที่แตกต่างกัน
คำถามที่พบบ่อย
CPU เป็นโปรเซสเซอร์อเนกประสงค์ที่ทำงานหลายอย่างแตกต่างกัน สำหรับการถอดรหัส มันใช้หน่วยคำนวณที่ใช้ร่วมกันและหน่วยความจำแคช ซึ่งใช้พลังงานแม้ในขณะทำงานเดียว ตัวถอดรหัสฮาร์ดแวร์ เป็นวงจรเฉพาะทางสูงที่มีไพพลายน์คงที่ ซึ่งทรานซิสเตอร์ทุกตัวทุ่มเทให้กับการถอดรหัสเท่านั้น ช่วยลดการใช้พลังงานลงอย่างรุนแรง
สำหรับ H.264/H.265 — libavcodec จาก FFmpeg ที่เปิดใช้การปรับปรุง SIMD สำหรับ AV1 — dav1d ซึ่งเร็วกว่า libaom อ้างอิง 30–50% บนอุปกรณ์มือถือ ประสิทธิภาพของ dav1d ช่วยให้ถอดรหัส 1080p AV1 แบบเรียลไทม์บน SoC ระดับเรือธง (A16+, Dimensity 9200+)
ได้ FFmpeg ถูกพอร์ตไปยังทั้งสองแพลตฟอร์ม สำหรับ iOS ให้ใช้ ffmpeg-kit — บิลด์สำเร็จรูปที่รองรับโคเดกและรูปแบบทั้งหมด สำหรับ Android — mobile-ffmpeg หรือสร้าง FFmpeg ผ่าน NDK โปรดคำนึงถึงข้อจำกัดด้านใบอนุญาต GPL/LGPL สำหรับการแจกจ่ายเชิงพาณิชย์
การถอดรหัสแบบเรียลไทม์หมายความว่า CPU สามารถถอดรหัสเฟรมได้เร็วกว่าที่แสดงบนหน้าจอ (ปกติ 30 หรือ 60 FPS) สำหรับ 1080p H.264, CPU มือถือสมัยใหม่จัดการได้สบายๆ โดยใช้ประมาณ 30–50% ของคอร์ประสิทธิภาพหนึ่งคอร์ สำหรับ 4K H.265, การทำงานแบบเรียลไทม์บน CPU เป็นไปได้เฉพาะบน SoC ระดับเรือธงที่มีโหลด 70–90% บนทุกคอร์
ใช้การถอดรหัสแบบหลายเธรด (ความขนานระดับเฟรม) ผ่าน FFmpeg ด้วยแฟลก thread_count, ตั้งค่า skip_frame เป็น B-frames (หากยอมรับได้สำหรับสถานการณ์), ลดความละเอียดผ่านฟิลเตอร์ scale ก่อนการถอดรหัส สำหรับ AV1 ด้วย dav1d ใช้ n_threads = จำนวนคอร์ CPU ลบหนึ่ง
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม