diff options
Diffstat (limited to 'kfile-plugins/mpeg')
-rw-r--r-- | kfile-plugins/mpeg/Makefile.am | 22 | ||||
-rw-r--r-- | kfile-plugins/mpeg/kfile_mpeg.cpp | 582 | ||||
-rw-r--r-- | kfile-plugins/mpeg/kfile_mpeg.desktop | 55 | ||||
-rw-r--r-- | kfile-plugins/mpeg/kfile_mpeg.h | 71 |
4 files changed, 0 insertions, 730 deletions
diff --git a/kfile-plugins/mpeg/Makefile.am b/kfile-plugins/mpeg/Makefile.am deleted file mode 100644 index 00b40647..00000000 --- a/kfile-plugins/mpeg/Makefile.am +++ /dev/null @@ -1,22 +0,0 @@ -## Makefile.am for mpeg file meta info plugin - -# set the include path for X, qt and KDE -INCLUDES = $(all_includes) - -# these are the headers for your project -noinst_HEADERS = kfile_mpeg.h - -kde_module_LTLIBRARIES = kfile_mpeg.la - -kfile_mpeg_la_SOURCES = kfile_mpeg.cpp -kfile_mpeg_la_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_KIO) -ltdetexteditor -module $(KDE_PLUGIN) -kfile_mpeg_la_LIBADD = $(LIB_KIO) - -# let automoc handle all of the meta source files (moc) -METASOURCES = AUTO - -messages: rc.cpp - $(XGETTEXT) kfile_mpeg.cpp -o $(podir)/kfile_mpeg.pot - -services_DATA = kfile_mpeg.desktop -servicesdir = $(kde_servicesdir) diff --git a/kfile-plugins/mpeg/kfile_mpeg.cpp b/kfile-plugins/mpeg/kfile_mpeg.cpp deleted file mode 100644 index 4d51f64d..00000000 --- a/kfile-plugins/mpeg/kfile_mpeg.cpp +++ /dev/null @@ -1,582 +0,0 @@ -/* This file is part of the KDE project - * Copyright (C) 2005 Allan Sandfeld Jensen <kde@carewolf.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation version 2. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -// MPEG KFile plugin -// Based on reading sourcecode of mpeglib, xinelib and libmpeg3 -// and studying MPEG dumps. - -#include <config.h> -#include "kfile_mpeg.h" - -#include <kprocess.h> -#include <klocale.h> -#include <kgenericfactory.h> -#include <kstringvalidator.h> -#include <kdebug.h> - -#include <tqdict.h> -#include <tqvalidator.h> -#include <tqcstring.h> -#include <tqfile.h> -#include <tqdatetime.h> - -// #include <iostream> - -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; - -typedef KGenericFactory<KMpegPlugin> MpegFactory; - -K_EXPORT_COMPONENT_FACTORY(kfile_mpeg, MpegFactory( "kfile_mpeg" )) - -KMpegPlugin::KMpegPlugin(TQObject *parent, const char *name, - const TQStringList &args) - - : KFilePlugin(parent, name, args) -{ - KFileMimeTypeInfo* info = addMimeTypeInfo( "video/mpeg" ); - - KFileMimeTypeInfo::GroupInfo* group = 0L; - - group = addGroupInfo(info, "Technical", i18n("Technical Details")); - - KFileMimeTypeInfo::ItemInfo* item; - - item = addItemInfo(group, "Length", i18n("Length"), TQVariant::Int); - setUnit(item, KFileMimeTypeInfo::Seconds); - - item = addItemInfo(group, "Resolution", i18n("Resolution"), TQVariant::Size); - - item = addItemInfo(group, "Frame rate", i18n("Frame Rate"), TQVariant::Double); - setSuffix(item, i18n("fps")); - - item = addItemInfo(group, "Video codec", i18n("Video Codec"), TQVariant::String); - item = addItemInfo(group, "Audio codec", i18n("Audio Codec"), TQVariant::String); - - item = addItemInfo(group, "Aspect ratio", i18n("Aspect ratio"), TQVariant::String); -} - -// Frame-rate table from libmpeg3 -float frame_rate_table[16] = -{ - 0.0, /* Pad */ - (float)24000.0/1001.0, /* Official frame rates */ - (float)24.0, - (float)25.0, - (float)30000.0/1001.0, - (float)30.0, - (float)50.0, - (float)60000.0/1001.0, - (float)60.0, - - 1, /* Unofficial economy rates */ - 5, - 10, - 12, - 15, - 0, - 0, -}; - -/* Bitrate indexes */ -int bitrate_123[3][16] = - { {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,}, - {0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,}, - {0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,} }; - -static const uint16_t sequence_start = 0x01b3; -static const uint16_t ext_sequence_start = 0x01b5; -static const uint16_t gop_start = 0x01b8; -static const uint16_t audio1_packet = 0x01c0; -static const uint16_t audio2_packet = 0x01d0; -static const uint16_t private1_packet = 0x01bd; -static const uint16_t private2_packet = 0x01bf; - -int KMpegPlugin::parse_seq() { - uint32_t buf; - dstream >> buf; - - horizontal_size = (buf >> 20); - vertical_size = (buf >> 8) & ((1<<12)-1); - aspect_ratio = (buf >> 4) & ((1<<4)-1); - int framerate_code = buf & ((1<<4)-1); - frame_rate = frame_rate_table[framerate_code]; - - dstream >> buf; - - bitrate = (buf >> 14); -// kdDebug(7034) << "bitrate: " << bitrate << endl; - bool has_intra_matrix = buf & 2; - bool has_non_intra_matrix = buf & 1; - - int matrix = 0; - if (has_intra_matrix) matrix +=64; - if (has_non_intra_matrix) matrix +=64; - - mpeg = 1; - return matrix; -} - -void KMpegPlugin::parse_seq_ext() { - uint32_t buf; - dstream >> buf; - - uint8_t type = buf >> 28; - if (type == 1) - mpeg = 2; - - /* - else - if (type == 2) { - dstream >> buf; - // These are display-sizes. I let them override physical sizes. - horizontal_size = (buf >> 18); - vertical_size = (buf >> 1) & ((1<<14)-1); -} */ -} - -long KMpegPlugin::parse_gop() { - uint32_t buf; - dstream >> buf; - dstream >> buf; - - int gop_hour = (buf>>26) & ((1<<5)-1); - kdDebug(7034) << "gop_hour: " << gop_hour << endl; - int gop_minute = (buf>>20) & ((1<<6)-1); - kdDebug(7034) << "gop_minute: " << gop_minute << endl; - int gop_second = (buf>>13) & ((1<<6)-1); - kdDebug(7034) << "gop_second: " << gop_second << endl; - int gop_frame = (buf>>7) & ((1<<6)-1); - kdDebug(7034) << "gop_frame: " << gop_frame << endl; - - long seconds = gop_hour*60*60 + gop_minute*60 + gop_second; - return (long)seconds; -} - -int KMpegPlugin::parse_audio() { - uint16_t len; - dstream >> len; -// kdDebug(7034) << "Length of audio packet: " << len << endl; - - uint8_t buf; - int i = 0; - for(i=0; i<20; i++) { - dstream >> buf; - if (buf == 0xff) { - dstream >> buf; - if ((buf & 0xe0) == 0xe0) - goto found_sync; - } - } - kdDebug(7034) << "MPEG audio sync not found" << endl; - return len-i; - -found_sync: - - int layer = ((buf >> 1) & 0x3); - if (layer == 1) - audio_type = 3; - else if (layer == 2) - audio_type = 2; - else if (layer == 3) - audio_type = 1; - else - kdDebug(7034) << "Invalid MPEG audio layer" << endl; - - dstream >> buf; - int bitrate_index = (buf & 0xf0) >> 4; - audio_rate = bitrate_123[3-layer][bitrate_index]; - - return len-3-i; -} - -int KMpegPlugin::skip_packet() { - uint16_t len; - dstream >> len; -// kdDebug(7034) << "Length of skipped packet: " << len << endl; - - return len; -} - -int KMpegPlugin::skip_riff_chunk() { - dstream.setByteOrder(TQDataStream::LittleEndian); - uint32_t len; - dstream >> len; -// std::cerr << "Length of skipped chunk: " << len << std::endl; - - dstream.setByteOrder(TQDataStream::BigEndian); - return len; -} - -int KMpegPlugin::parse_private() { - uint16_t len; - dstream >> len; -// kdDebug(7034) << "Length of private packet: " << len << endl; - - // Match AC3 packets - uint8_t subtype; - dstream >> subtype; - subtype = subtype >> 4; - if (subtype == 8) // AC3 - audio_type = 5; - else - if (subtype == 10) // LPCM - audio_type = 7; - - return len-1; -} - -bool KMpegPlugin::find_mpeg_in_cdxa() -{ - int skip_len = 0; - uint32_t magic; - uint32_t data_len; - // search for data chunk - while (true) { - dstream >> magic; - if (magic != 0x64617461) { // "fmt " - skip_len = skip_riff_chunk(); - if (!file.at(file.at()+skip_len)) return false; - continue; - } else { - // size of chunk - dstream >> data_len; - int block = 0; - // search for mpeg part - while(block < 32) { - // check for CDXA sync thingy - dstream >> magic; - // 00 ff ff ff ff ff ff ff ff ff ff ff 00 - if (magic == 0x00ffffff) { -// std::cerr << "Found CD sync" << std::endl; - // skip 20 bytes - if (!file.at(file.at()+20)) return false; - dstream >> magic; - if (magic == 0x000001ba) { -// std::cerr << "Found CDXA mpeg" << std::endl; - return true; - } - else { -// std::cerr << "CDXA block: #" <<block << ": " << magic << std::endl; - if (!file.at(file.at()+2324)) return false; - block++; - continue; - } - } else { -// std::cerr << "Incorrect CDXA block" << std::endl; - // shouldn't happen - return true; - } - } - return false; - } - } -} - -bool KMpegPlugin::read_mpeg() -{ - mpeg = 0; - audio_type = 0; - audio_rate = 0; - - uint32_t magic; - dstream >> magic; - if (magic == 0x52494646) // == "RIFF" - { - dstream >> magic; - dstream >> magic; - if (magic != 0x43445841) { // 0x43445841 == "CDXA" - kdDebug(7034) << "Unknown RIFF file" << endl; - return false; - } else { - if (!find_mpeg_in_cdxa()) return false; - } - } - else - if (magic != 0x000001ba) { - kdDebug(7034) << "Not a MPEG-PS file" << endl; - return false; - } -// file.at(0); - - uint8_t byte; - int skip_len = 0; - int state = 0; - int skimmed = 0; - int video_len = 0; - int searched = 0; - bool video_found = false, audio_found = false, gop_found = false; - // Search for MPEG packets - for(int i=0; i < 2048; i++) { - dstream >> byte; - skimmed++; - searched++; - if (video_len > 0) video_len--; - // Use a fast state machine to find 00 00 01 sync code - switch (state) { - case 0: - if (byte == 0) - state = 1; - else - state = 0; - break; - case 1: - if (byte == 0) - state = 2; - else - state = 0; - break; - case 2: - if (byte == 0) - state = 2; - else - if (byte == 1) - state = 3; - else - state = 0; - break; - case 3: { - skimmed -= 4; - if (skimmed) { -// kdDebug(7034) << "Bytes skimmed:" << skimmed << endl; - skimmed = 0; - } -// kdDebug(7034) << "Packet of type:" << TQString::number(byte,16) << endl; - switch (byte) { - case 0xb3: - if (video_found) break; - skip_len = parse_seq(); - video_found = true; - video_len -= 8; - video_len -= skip_len; - break; - case 0xb5: - parse_seq_ext(); - video_len -= 4; - break; - case 0xb8: - /* - if (!gop_found) { - start_time = parse_gop(); - gop_found = true; - kdDebug(7034) << "start_time: " << start_time << endl; - } - */ - /* nobreak */ - case 0x00: - case 0x01: - // skip the rest of the video data - if (video_len > 0 && video_found) - skip_len = video_len; - break; - /* - case 0xb2: - skip_len = parse_user(); - break; - */ - case 0xba: - skip_len = 8; - break; - case 0xbe: - // padding - skip_len = skip_packet(); - break; - case 0xe0: - // video data - if (video_found) - skip_len = skip_packet(); - else - video_len = skip_packet(); - break; - case 0xbd: - case 0xbf: - skip_len = parse_private(); - break; - case 0xc0: - case 0xd0: - skip_len = parse_audio(); - audio_found = true; - break; - default: -// kdDebug(7034) << "Unhandled packet of type:" << TQString::number(byte,16) << endl; - break; - } - state = 0; - break; - } - } - - if (video_found && audio_found /*&& gop_found*/) break; - if (skip_len) { - if (!file.at(file.at()+skip_len)) - return false; - searched += skip_len; - skip_len = 0; - } - } - /* - if (skimmed) - kdDebug(7034) << "Bytes skimmed:" << skimmed << endl; - kdDebug(7034) << "Bytes searched:" << searched << endl; - */ - - if (mpeg == 0) { - kdDebug(7034) << "No sequence-start found" << endl; - return false; - } - return true; -} - -// Search for the last GOP packet and read the time field -void KMpegPlugin::read_length() -{ - end_time = 0; - uint8_t byte; - int state = 0; - // Search for the last gop - file.at(file.size()-1024); - for(int j=1; j<64; j++) { -// dstream.setDevice(&file); -// dstream.setByteOrder(TQDataStream::BigEndian); - for(int i=0; i<1024; i++) { - dstream >> byte; - switch (state) { - case 0: - if (byte == 0) - state = 1; - else - state = 0; - break; - case 1: - if (byte == 0) - state = 2; - else - state = 0; - case 2: - if (byte == 0) - state = 2; - else - if (byte == 1) - state = 3; - else - state = 0; - case 3: - if (byte == 0xb8) { - end_time = parse_gop(); - kdDebug(7034) << "end_time: " << end_time << endl; - return; - } - state = 0; - } - } - state = 0; - file.at(file.size()-j*1024); - } - kdDebug(7034) << "No end GOP found" << endl; -} - -bool KMpegPlugin::readInfo( KFileMetaInfo& info, uint /*what*/) -{ - if ( info.path().isEmpty() ) // remote file - return false; - - file.setName(info.path()); - - // open file, set up stream and set endianness - if (!file.open(IO_ReadOnly)) - { - kdDebug(7034) << "Couldn't open " << TQFile::encodeName(info.path()).data() << endl; - return false; - } - - dstream.setDevice(&file); - dstream.setByteOrder(TQDataStream::BigEndian); - - start_time = end_time = 0L; - - if (!read_mpeg()) { - kdDebug(7034) << "read_mpeg() failed!" << endl; - } - else { - KFileMetaInfoGroup group = appendGroup(info, "Technical"); - - appendItem(group, "Frame rate", double(frame_rate)); - - appendItem(group, "Resolution", TQSize(horizontal_size, vertical_size)); - /* The GOP timings are completely bogus - read_length(); - if (end_time != 0) { - //long total_frames = end_time-start_time + 1; - long total_time = end_time; - appendItem(group, "Length", int(total_time)); - } - // and so is bitrate - long total_time = file.size()/((bitrate+audio_rate)*50); - appendItem(group, "Length", int(total_time)); - */ - if (mpeg == 1) - appendItem(group, "Video codec", "MPEG-1"); - else - appendItem(group, "Video codec", "MPEG-2"); - - switch (audio_type) { - case 1: - appendItem(group, "Audio codec", "MP1"); - break; - case 2: - appendItem(group, "Audio codec", "MP2"); - break; - case 3: - appendItem(group, "Audio codec", "MP3"); - break; - case 5: - appendItem(group, "Audio codec", "AC3"); - break; - case 7: - appendItem(group, "Audio codec", "PCM"); - break; - default: - appendItem(group, "Audio codec", i18n("Unknown")); - } - // MPEG 1 also has an aspect ratio setting, but it works differently, - // and I am not sure if it is used. - if (mpeg == 2) { - switch (aspect_ratio) { - case 1: - appendItem(group, "Aspect ratio", i18n("default")); - break; - case 2: - appendItem(group, "Aspect ratio", "4/3"); - break; - case 3: - appendItem(group, "Aspect ratio", "16/9"); - break; - case 4: - appendItem(group, "Aspect ratio", "2.11/1"); - break; - } - } - } - - file.close(); - return true; -} - -#include "kfile_mpeg.moc" diff --git a/kfile-plugins/mpeg/kfile_mpeg.desktop b/kfile-plugins/mpeg/kfile_mpeg.desktop deleted file mode 100644 index 024f448d..00000000 --- a/kfile-plugins/mpeg/kfile_mpeg.desktop +++ /dev/null @@ -1,55 +0,0 @@ -[Desktop Entry] -Type=Service -Name=MPEG Info -Name[bg]=Информация за MPEG -Name[bn]=এম-পেগ তথ্য -Name[br]=Titouroù MPEG -Name[bs]=MPEG informacije -Name[ca]=Informació MPEG -Name[cs]=MPEG info -Name[da]=MPEG-info -Name[de]=MPEG-Info -Name[el]=Πληροφορίες MPEG -Name[eo]=MPEG-informo -Name[es]=Info MPEG -Name[et]=MPEG info -Name[eu]=MPEG informazioa -Name[fa]=اطلاعات MPEG -Name[fi]=MPEG-tiedot -Name[fr]=Informations MPEG -Name[ga]=Eolas MPEG -Name[gl]=Información MPEG -Name[he]=מידע MPEG -Name[hu]=MPEG-jellemzők -Name[is]=MPEG upplýsingar -Name[it]=Informazioni MPEG -Name[ja]=MPEG 情報 -Name[kk]=MPEG мәліметі -Name[km]=ព័ត៌មាន MPEG -Name[ko]=MPEG 정보 -Name[lt]=MPEG informacija -Name[nb]=MPEG informasjon -Name[nds]=MPEG-Info -Name[ne]=एमपीईजी सूचना -Name[nl]=MPEG-info -Name[nn]=MPEG-info -Name[pa]=MPEG ਜਾਣਕਾਰੀ -Name[pl]=Informacja o pliku MPEG -Name[pt]=Informação do MPEG -Name[pt_BR]=Informações sobre MPEG -Name[ru]=Сведения о MPEG -Name[sl]=Podatki o MPEG -Name[sr]=Информације о MPEG-у -Name[sr@Latn]=Informacije o MPEG-u -Name[sv]=MPEG-information -Name[th]=ข้อมูล MPEG -Name[tr]=MP3 Bilgisi -Name[uk]=Інформація про MPEG -Name[zh_CN]=MPEG 信息 -Name[zh_HK]=MPEG 資訊 -Name[zh_TW]=MPEG 資訊 -ServiceTypes=KFilePlugin -X-TDE-Library=kfile_mpeg -MimeType=video/mpeg -PreferredGrous=Technical -PreferredItems=Length,Resolution,Frame rate,Video codec,Audio codec diff --git a/kfile-plugins/mpeg/kfile_mpeg.h b/kfile-plugins/mpeg/kfile_mpeg.h deleted file mode 100644 index c81114bf..00000000 --- a/kfile-plugins/mpeg/kfile_mpeg.h +++ /dev/null @@ -1,71 +0,0 @@ -/* This file is part of the KDE project - * Copyright (C) 2005 Allan Sandfeld Jensen <kde@carewolf.com> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation version 2. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef __KFILE_MPEG_H__ -#define __KFILE_MPEG_H__ - -#include <kfilemetainfo.h> -#include <tqfile.h> - -class TQStringList; - -class KMpegPlugin: public KFilePlugin -{ - Q_OBJECT - - -public: - KMpegPlugin( TQObject *parent, const char *name, const TQStringList& args ); - - virtual bool readInfo( KFileMetaInfo& info, uint what); - -private: - int parse_seq(); - void parse_seq_ext(); - long parse_gop(); - int parse_audio(); - int parse_private(); - int skip_packet(); - int skip_riff_chunk(); - bool find_mpeg_in_cdxa(); - - bool read_mpeg(); - void read_length(); - - TQFile file; - TQDataStream dstream; - - // MPEG information - int horizontal_size; - int vertical_size; - int aspect_ratio; - int bitrate; - float frame_rate; - - int mpeg; - int audio_type; - int audio_rate; - - long start_time; - long end_time; - - -}; - -#endif |