รู้จักเทคนิคการทำ Video Coding แบบต่าง ๆ กัน
ปัจจุบันวิดีโอถือเป็นสิ่งที่อยู่รอบตัวเราในทุกวัน สามารถพบได้ทั้งในรูปแบบ Online Streaming, YouTube, ไฟล์หนัง, หรือแม้กระทั่งเวลาเรากดอัดในมือถือก็ตาม ในขณะที่ไฟล์วิดีโอคือการนำภาพที่ขยับได้และเสียงมารวมอยู่ด้วยกัน แล้วเบื้องหลังมันมีหลักการอะไรที่ทำให้ไฟล์ ๆ นั้นมีขนาดเล็กจนเราสามารถเก็บวิดีโอได้หลายไฟล์ทั้ง ๆ ที่มันยาวหรือมีรายละเอียดเยอะกันล่ะ?
ก่อนอื่นต้องเข้าใจก่อนว่า Concept ขึ้นพื้นฐานของวิดีโอนั้น มันก็คือการนำหลาย ๆ ภาพมาเรียงต่อกันนั่นแหละ เมื่อมีภาพมาก ๆ ฉายเรียงกันใน 1 วินาที สายตาของคนเราก็จะตีความว่ามันคือภาพเคลื่อนไหว โดยจำนวนภาพต่อ 1 วินาทีที่น้อยที่สุดที่คนจะเห็นเป็นภาพเคลื่อนไหวได้ คือประมาณ 24 ภาพ/วินาที หรือ 24 fps (frame per second) ซึ่งต่อไปเราจะเรียกภาพพวกนี้ว่า “frame”
สมัยนี้เวลาเราถ่ายรูปในมือถือ จะสังเกตเห็นว่าภาพ ๆ นึงจะมีขนาดอยู่ที่ประมาณ 2–3 MB — ถ้าเกิดว่าวิดีโอคือชุดของภาพที่มาเรียงต่อกันจริง มันจะขนาดเท่าไหร่กัน? มาลองคำนวณดูกันครับ
3MB * 24 frame * 60 วินาที = 4320MB
นั่นหมายความว่าวิดีโอระยะเวลา 1 นาทีจะมีขนาดถึง 4320MB หรือประมาณ 4GB เลยเหรอ!!? คำตอบคือไม่ใช่ครับ เพราะถ้าเราลองเปิดไปดูไฟล์วิดีโอในเครื่องของตัวเอง จะเห็นว่าขนาดมันเล็กกว่านี้มาก ๆ บางคลิปยาวกว่านี้ไฟล์ยังเล็กกว่า 4GB ด้วยซ้ำ
Container & Codec
จริง ๆ แล้วไฟล์วิดีโอในเครื่องเรานั้นถูกแบ่งออกเป็น 2 ส่วนครับ คือสิ่งที่เรียกว่า container และ codec ตัว container คือตัวที่เก็บข้อมูลต่าง ๆ ของวิดีโอไว้ รวมถึง bitstream ต่าง ๆ และ metadata ของวิดีโอ ส่วนเจ้าตัว codec (coder-decoder) จะมีหน้าที่ Encode และ Decode ไฟล์ข้างในวิดีโอตามที่ algorithm แต่ละตัวได้เขียนไว้ ตรงนี้แหละครับ ที่มีการบีบอัดไฟล์เกิดขึ้น
ตัวอย่าง container: MP4, MOV, AVI, MKV
ตัวอย่าง codec: H.264, H.265, M-JPEG, ProRes
กล่าวคือ สมมติว่าเรามีไฟล์ชื่อ video.mp4
หมายความว่า container คือ mp4 ส่วน codec อาจจะเป็นอะไรก็ได้ ต้องดูลึกเข้าไปอีกขั้น
มาดูตรง codec กันหน่อยดีกว่า ว่าเค้ามีวิธีบีบอัดไฟล์แบบไหนกันบ้าง
การบีบอัดไฟล์วิดีโอนั้นจะมีอยู่ 2 รูปแบบใหญ่ ๆ ได้แก่ Intraframe Compression และ Interframe Compression ชื่อคล้าย ๆ กันแต่ไม่เหมือนกันนะ
1. Intraframe Compression
คือการบีบอัดแบบเฟรมต่อเฟรม เช่นถ้าแต่ละเฟรมมีภาพมาอย่างนี้ มันก็จะทำการบีบอัดภาพนั้นเป็นรายเดี่ยว ๆ ไป ซึ่งการบีบอัดรูปแบบนี้ก็จะลดขนาดไฟล์ได้ประมาณนึง
2. Interframe Compression
คือการบีบอัดแบบลบเอาส่วนที่เหมือนกันในแต่ละเฟรมออก เหลือแค่เฉพาะส่วนที่ไม่เหมือนกัน หรือมีการเปลี่ยนแปลงไว้แทน เช่นมีการขยับแขนแต่ตัวอยู่ที่เดิมก็ไม่ต้องเก็บตัวไว้ โดยทั่วไปการบีบอัดประเภทนี้จะลดขนาดไฟล์ได้มากกว่าแบบ Intraframe มาก ซึ่งวันนี้เราจะมาดูเจ้าตัวนี้กันแหละครับ
Interframe Compression
ประเภทของเฟรมใน Interframe Compression จะถูกแบ่งออกเป็น 2 แบบ นั่นคือ I-Frame (หรือ Key Frame) และ P-Frame ครับ
I-Frame ก็คือเฟรมหลัก หรือเฟรมที่มีองค์ประกอบครบทุกอย่างอยู่ เหมือนเฟรมธรรมดาทั่วไปเลย
P-Frame คือเฟรมที่จะเก็บเฉพาะภาพส่วนที่มีการเปลี่ยนแปลงไว้เท่านั้น โดยจะอ้างอิงไปยังเฟรมก่อนหน้าเพื่อให้ได้ภาพเดิมแบบเต็ม ๆ ออกมาครับ
(จริง ๆ มี B-Frame ด้วยซึ่งจะคล้ายกับ P-Frame แต่จะยังไม่พูดถึงในเนื้อหานี้)
ดังนั้นถ้าดูจากภาพตัวอย่าง ถ้าคอมอยากแสดงเฟรมที่สี่ ก็ต้องย้อนไปดูเฟรมที่สาม เฟรมที่สอง ไปจนถึงเฟรมที่เป็น I-Frame เพื่อให้ได้ภาพสมบูรณ์ออกมาครับ
ลักษณะของ Interframe จะเป็นการมี I-Frame เป็นช่วง ๆ แล้วถูกคั่นด้วย P-Frame นั่นเอง
อ่านมาจนถึงตรงนี้แล้ว หลายคนก็อาจเกิดคำถามว่า อ้าว… แล้วคอมมันรู้ได้ยังไงล่ะว่าเฟรมนี้มีการเปลี่ยนแปลงไปยังไง? มันก็มีหลักการของมันอยู่ครับ เดี๋ยวผมจะพามาดูเป็นคอนเซปต์คร่าว ๆ ให้พอเข้าใจกัน
Basic Concept
สมมติว่าเรามีวิดีโอลูกบอลสีดำเริ่มจากตรงกลาง แล้วเคลื่อนที่ไปทางขวานะ ตอนนี้เราดูคลิปผ่านไปแล้วเฟรมนึง เพราะฉะนั้นเฟรมปัจจุบันของเราก็จะเป็นลูกบอลที่อยู่ทางขวาไปนิดหน่อย
หลักการของการหาการเปลี่ยนแปลงก็ง่าย ๆ เลยครับ เราเอาเฟรมปัจจุบัน ไปลบกับเฟรมก่อนหน้าก็จะได้ Difference Frame หรือการเปลี่ยนแปลงของเรานี่เอง แล้วถ้าเราอยากได้ภาพเดิมกลับมา ก็แค่เอา Difference Frame ไปบวกกับเฟรมก่อนหน้า เท่านั้นเองครับ เป็นไง ง่ายมะ
ดังนั้นแทนที่คอมจะเป็นเฟรมเต็ม ๆ สองเฟรมในวิดิโอแบบแรก เราก็ให้มันเก็บเฟรมที่สองเป็น Difference Frame แทนสิ เพราะใช้เนื้อที่น้อยกว่าเห็นๆ แล้วเวลาดูถึงเฟรมที่สอง ก็แค่ให้มันอิงไปบวกกับเฟรมก่อนหน้าก็ได้แล้ว ถ้าเกิดว่ายังไม่ลืมเรื่องก่อนหน้าที่เพิ่งพูดกันไป เฟรมแรกก็คือ I-Frame ส่วนเฟรมที่สองก็คือ P-Frame นี่แหละครับ
Block Partitioning & Motion Compensation
อีกเทคนิคนึงในการบีบอัดวิดีโอแบบ Interframe Compression ที่น่าสนใจและน่าพูดถึง คือเรื่องของ Block Partitioning และ Motion Compensation ครับ
อย่าเพิ่งหนีไปไหนกันล่ะ มันไม่ยาก! จริงๆ!!!
Block Partitioning
เอาคลิปบอลสีดำอันเดิมของเรามาดูกันครับ จะบอกว่าเวลาคอมมันประมวลผล มันไม่ได้มองเป็นภาพใหญ่ทั้งแบบนี้เลยนะ แต่มันทำการแบ่งภาพเป็นส่วนย่อย ๆ ลงอีกทีนึง แล้วในส่วนย่อยนั้นก็ย่อยลงอีกได้เหมือนกัน
Motion Compensation
ทีนี้สมมติเราเลือกจุดที่สนใจคือตรงวงกลมสีแดงนี้ไว้ก่อน เล่นคลิปผ่านไปเฟรมนึงบอลขยับแล้ว คอมก็จะไปหาว่าบล็อกไหนมีความใกล้เคียงกับบล็อกที่เราวงกลมไว้เฟรมก่อนที่สุด ทำการเลือกบล็อกนั้นไว้ แล้ววาดลูกศรบอกทิศทางว่าบล็อกนี้มันขยับมาทางนี้นะจากเฟรมก่อน โดยลูกศรนี้เนี่ย จะมีชื่อว่า “Motion Vector” นั่นเอง แต่ของจริงมันไม่ได้ทำบล็อกเดียวนะ มันทำหลาย ๆ บล็อกเลยในหนึ่งเฟรม
ก็เหมือนเดิมครับ แทนที่เราจะเก็บเป็นเฟรมเต็ม ๆ สองเฟรมแบบแรก ทำไมไม่เก็บเฟรมที่สองเป็น Motion Vector แล้วเวลาเล่นคลิปก็ให้มันอิงไปถึงเฟรมแรกเอาล่ะ? เก็บข้อมูลน้อยกว่าเยอะเลย!
สรุป
เทคนิคในการทำ Video Coding ต่าง ๆ ที่ผมยกมาในครั้งนี้เป็นเพียงหนึ่งในหลากหลายวิธีที่มีการใช้กันจริง ๆ เท่านั้น นอกจากนี้ยังเป็นคอนเซปต์แบบเบสิคมาก ๆ อีกด้วย ก็หวังว่าจะช่วยให้ผู้อ่านเห็นภาพขึ้นนะครับ
แหล่งอ้างอิง
- Explaining Digital Video: Formats, Codecs & Containers
https://www.youtube.com/watch?v=-4NXxY4maYc - Video Coding Basics — How is this so efficient?
https://www.youtube.com/watch?v=LDeL7-49qm4 - Video Coding Standards — from H.261 to MPEG1,2,4,7 — to H.265 MPEG-H
https://www.youtube.com/watch?v=dqxbBl-BGho - H.264 Compression Technology
https://www.youtube.com/watch?v=PmoEsPWEdOA - YUView
https://github.com/IENT/YUView - https://github.com/ChristianFeldmann/PresentationMaterial