codec/packet: add Packet and packet::SideData

This commit is contained in:
meh 2015-05-12 03:44:45 +02:00
parent 496f3759ec
commit 42564d0d5e
4 changed files with 240 additions and 0 deletions

View File

@ -1,6 +1,8 @@
pub mod id;
pub use self::id::Id;
pub mod packet;
use std::ffi::CStr;
use std::str::from_utf8_unchecked;

142
src/codec/packet/mod.rs Normal file
View File

@ -0,0 +1,142 @@
mod side_data;
pub use self::side_data::SideData;
use std::marker::PhantomData;
use std::mem;
use libc::c_int;
use ffi::*;
bitflags! {
flags Flags: i32 {
const FLAG_KEY = AV_PKT_FLAG_KEY,
const FLAG_CORRUPT = AV_PKT_FLAG_CORRUPT,
}
}
pub struct Packet {
pub val: AVPacket,
}
impl Packet {
pub fn new() -> Self {
unsafe {
let mut pkt: AVPacket = mem::zeroed();
av_init_packet(&mut pkt);
Packet { val: pkt }
}
}
pub fn sized(size: usize) -> Self {
unsafe {
let mut pkt: AVPacket = mem::zeroed();
av_init_packet(&mut pkt);
av_new_packet(&mut pkt, size as c_int);
Packet { val: pkt }
}
}
pub fn shrink(&mut self, size: usize) {
unsafe {
av_shrink_packet(&mut self.val, size as c_int);
}
}
pub fn grow(&mut self, size: usize) {
unsafe {
av_grow_packet(&mut self.val, size as c_int);
}
}
pub fn flags(&self) -> Flags {
Flags::from_bits_truncate(self.val.flags)
}
pub fn set_flags(&mut self, value: Flags) {
self.val.flags = value.bits();
}
pub fn pts(&self) -> isize {
self.val.pts as isize
}
pub fn dts(&self) -> isize {
self.val.dts as isize
}
pub fn size(&self) -> usize {
self.val.size as usize
}
pub fn duration(&self) -> usize {
self.val.duration as usize
}
pub fn position(&self) -> isize {
self.val.pos as isize
}
pub fn convergence(&self) -> isize {
self.val.convergence_duration as isize
}
pub fn side_data<'a>(&'a self) -> SideDataIter<'a> {
SideDataIter::new(&self.val)
}
}
impl Clone for Packet {
fn clone(&self) -> Self {
let mut pkt = Packet::new();
pkt.clone_from(self);
pkt
}
fn clone_from(&mut self, source: &Self) {
unsafe {
av_copy_packet(&mut self.val, &source.val);
}
}
}
impl Drop for Packet {
fn drop(&mut self) {
unsafe {
av_free_packet(&mut self.val);
}
}
}
pub struct SideDataIter<'a> {
ptr: *const AVPacket,
cur: c_int,
_marker: PhantomData<&'a Packet>,
}
impl<'a> SideDataIter<'a> {
pub fn new(ptr: *const AVPacket) -> Self {
SideDataIter { ptr: ptr, cur: 0, _marker: PhantomData }
}
}
impl<'a> Iterator for SideDataIter<'a> {
type Item = SideData<'a>;
fn next(&mut self) -> Option<<Self as Iterator>::Item> {
unsafe {
if self.cur >= (*self.ptr).side_data_elems {
None
}
else {
self.cur += 1;
Some(SideData::wrap((*self.ptr).side_data.offset((self.cur - 1) as isize)))
}
}
}
}

View File

@ -0,0 +1,95 @@
use std::marker::PhantomData;
use std::slice;
use ffi::*;
use super::Packet;
#[derive(Eq, PartialEq, Copy, Clone, Debug)]
pub enum Type {
Palette,
NewExtraData,
ParamChange,
H263MbInfo,
ReplayGain,
DisplayMatrix,
Stereo3d,
AudioServiceType,
SkipSamples,
JpDualMono,
StringsMetadata,
SubtitlePosition,
MatroskaBlockAdditional,
WebVTTIdentifier,
WebVTTSettings,
MetadataUpdate,
}
impl From<AVPacketSideDataType> for Type {
fn from(value: AVPacketSideDataType) -> Self {
match value {
AV_PKT_DATA_PALETTE => Type::Palette,
AV_PKT_DATA_NEW_EXTRADATA => Type::NewExtraData,
AV_PKT_DATA_PARAM_CHANGE => Type::ParamChange,
AV_PKT_DATA_H263_MB_INFO => Type::H263MbInfo,
AV_PKT_DATA_REPLAYGAIN => Type::ReplayGain,
AV_PKT_DATA_DISPLAYMATRIX => Type::DisplayMatrix,
AV_PKT_DATA_STEREO3D => Type::Stereo3d,
AV_PKT_DATA_AUDIO_SERVICE_TYPE => Type::AudioServiceType,
AV_PKT_DATA_SKIP_SAMPLES => Type::SkipSamples,
AV_PKT_DATA_JP_DUALMONO => Type::JpDualMono,
AV_PKT_DATA_STRINGS_METADATA => Type::StringsMetadata,
AV_PKT_DATA_SUBTITLE_POSITION => Type::SubtitlePosition,
AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL => Type::MatroskaBlockAdditional,
AV_PKT_DATA_WEBVTT_IDENTIFIER => Type::WebVTTIdentifier,
AV_PKT_DATA_WEBVTT_SETTINGS => Type::WebVTTSettings,
AV_PKT_DATA_METADATA_UPDATE => Type::MetadataUpdate
}
}
}
impl Into<AVPacketSideDataType> for Type {
fn into(self) -> AVPacketSideDataType {
match self {
Type::Palette => AV_PKT_DATA_PALETTE,
Type::NewExtraData => AV_PKT_DATA_NEW_EXTRADATA,
Type::ParamChange => AV_PKT_DATA_PARAM_CHANGE,
Type::H263MbInfo => AV_PKT_DATA_H263_MB_INFO,
Type::ReplayGain => AV_PKT_DATA_REPLAYGAIN,
Type::DisplayMatrix => AV_PKT_DATA_DISPLAYMATRIX,
Type::Stereo3d => AV_PKT_DATA_STEREO3D,
Type::AudioServiceType => AV_PKT_DATA_AUDIO_SERVICE_TYPE,
Type::SkipSamples => AV_PKT_DATA_SKIP_SAMPLES,
Type::JpDualMono => AV_PKT_DATA_JP_DUALMONO,
Type::StringsMetadata => AV_PKT_DATA_STRINGS_METADATA,
Type::SubtitlePosition => AV_PKT_DATA_SUBTITLE_POSITION,
Type::MatroskaBlockAdditional => AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL,
Type::WebVTTIdentifier => AV_PKT_DATA_WEBVTT_IDENTIFIER,
Type::WebVTTSettings => AV_PKT_DATA_WEBVTT_SETTINGS,
Type::MetadataUpdate => AV_PKT_DATA_METADATA_UPDATE
}
}
}
pub struct SideData<'a> {
ptr: *mut AVPacketSideData,
_marker: PhantomData<&'a Packet>
}
impl<'a> SideData<'a> {
pub fn wrap(ptr: *mut AVPacketSideData) -> Self {
SideData { ptr: ptr, _marker: PhantomData }
}
pub fn kind(&self) -> Type {
unsafe {
Type::from((*self.ptr).kind)
}
}
pub fn data(&'a self) -> &'a [u8] {
unsafe {
slice::from_raw_parts((*self.ptr).data, (*self.ptr).size as usize)
}
}
}

View File

@ -15,3 +15,4 @@ pub use util::media;
pub use util::frame::{self, Frame};
pub mod codec;
pub use codec::packet::{self, Packet};