⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mediapacketbuffer.h

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.10平台上编译为嵌入式图形界面操作系统。
💻 H
字号:
/************************************************************************ Copyright (C) 2000-2005 Trolltech AS and its licensors.** All rights reserved.**** This file is part of the Qtopia Environment.**** This file may be distributed and/or modified under the terms of the** GNU General Public License version 2 as published by the Free Software** Foundation and appearing in the file LICENSE.GPL included in the** packaging of this file.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.**** See http://www.trolltech.com/gpl/ for GPL licensing information.** See below for additional copyright and license information**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#ifndef MEDIA_PACKET_BUFFER_H#define MEDIA_PACKET_BUFFER_H#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <pthread.h>#include <sched.h>extern "C" {#include "avcodec.h"#include "avformat.h"};#include <qlist.h>#include <qstring.h>#include <qfile.h>#include "ffmutex.h"#include "mediapacket.h"//// Thread Safe QList of MediaPackets//// Contains a QList instead of inheriting from QList so that the API is restricted to only// these functions which have been made thread safe.//// thread safe, contention safeclass MediaPacketList {public:    MediaPacketList() {	FFAutoLockUnlockMutex lock(mutex);	list = new QList<MediaPacket>();	list->setAutoDelete(true);    }    ~MediaPacketList() {	FFAutoLockUnlockMutex lock(mutex);	qDebug("deleting list");	delete list;	qDebug("deleted list");    }    void append(MediaPacket *pkt) {	FFAutoLockUnlockMutex lock(mutex);	list->append(pkt);    }    long fileOffset() {	FFAutoLockUnlockMutex lock(mutex);	if ( !list->first() )	    return 0;	return list->first()->fileOffset;    }    MediaPacket *first() {	FFAutoLockUnlockMutex lock(mutex);	return list->first();    }    int count() {	FFAutoLockUnlockMutex lock(mutex);	return list->count();    }    void clear() {	FFAutoLockUnlockMutex lock(mutex);	list->clear();    }    MediaPacket *next() {	FFAutoLockUnlockMutex lock(mutex);	if ( list->count() )	    return list->take(0);	return 0;    }private:    FFMutex mutex;    QList<MediaPacket> *list;}; class MediaPacketBuffer {public:    // thread safe, contention safe    MediaPacketBuffer();    // thread ??, contention ??    virtual ~MediaPacketBuffer();    // thread safe, contention safe    bool open(const QString &fileName);    // thread safe, contention safe    void start(); // begins the buffering after a file has been opened    // thread safe, contention safe    long duration() {	FFAutoLockUnlockMutex streamLock(avFormatMutex);	if ( avFormatContext )	    return avFormatContext->duration / (AV_TIME_BASE/1000); // Convert to milliseconds	return 0;    }    // thread safe, contention safe    long bitRate() {	FFAutoLockUnlockMutex streamLock(avFormatMutex);	if ( avFormatContext )	    return avFormatContext->bit_rate;	return 0;    }    // thread safe, contention safe    long fileLength() {	FFAutoLockUnlockMutex streamLock(avFormatMutex);	if ( avFormatContext )	    return avFormatContext->file_size;	return 0;    }    // thread safe, contention safe    long pos() {	long audioFileOffset = waitingAudioPackets.fileOffset();	long videoFileOffset = waitingVideoPackets.fileOffset();	//FFAutoLockUnlockMutex streamLock(avFormatMutex);	if ( audioFileOffset > fileOffset )	    fileOffset.assign(audioFileOffset);	if ( videoFileOffset > fileOffset )	    fileOffset.assign(videoFileOffset);	return (int)fileOffset;    }    // thread safe, contention unsafe (accesses packet lists inside the mutex, probably okay)    bool seek(long pos) {	qDebug("MediaPacketBuffer::seek(%li)", pos);	if ( !isOpen() ) {	    qDebug("Can not seek, no file open");	    return false;	}	// Seek in to the file	FFAutoLockUnlockMutex streamLock(avFormatMutex);	url_fseek( &avFormatContext->pb, pos, SEEK_SET );	fileOffset.assign(pos);	waitingAudioPackets.clear();	waitingVideoPackets.clear();	//bufferMutex.signal();	//startBufferingPackets();	//qDebug("seek start I");	return true;    }    void flushAudioPackets() {	waitingAudioPackets.clear();    }    void flushVideoPackets() {	waitingVideoPackets.clear();    }    // thread safe, contention unsafe (accesses packet lists inside the mutex, probably okay)    void flush() {	FFAutoLockUnlockMutex streamLock(avFormatMutex);	waitingAudioPackets.clear();	waitingVideoPackets.clear();    }    // thread safe, contention safe    long distanceBetweenAudioAndVideo() {	long audioFileOffset = waitingAudioPackets.fileOffset();	long videoFileOffset = waitingVideoPackets.fileOffset();	if ( !audioFileOffset || !videoFileOffset )	    return 0;	return audioFileOffset - videoFileOffset;    }    // thread safe, contention safe    AVCodecContext *audioContext() {	FFAutoLockUnlockMutex streamLock(avFormatMutex);	return audioCodecContext;    }    // thread safe, contention safe    AVCodecContext *videoContext() {	FFAutoLockUnlockMutex streamLock(avFormatMutex);	return videoCodecContext;    }    // thread safe, contention safe    void init() {	FFAutoLockUnlockMutex streamLock(avFormatMutex);	fileOffset.assign(0);	audioCodecContext = 0;	videoCodecContext = 0;	audioStream.assign(-1);	videoStream.assign(-1);	avFormatContext = 0;	openFlag.assign(0);    }    bool isJoin() {	FFAutoLockUnlockMutex streamLock(bufferMutex);	return joined;    }    void setJoin(bool j) {	FFAutoLockUnlockMutex streamLock(bufferMutex);	joined = j;    }    void join() {	setJoin(true);	bufferMutex.signal();	pthread_yield();	bufferMutex.signal();	pthread_yield();	bufferMutex.signal();	pthread_join(threadId, 0);    }    // thread safe, contention safe    void close() {	{	    FFAutoLockUnlockMutex streamLock(avFormatMutex);	    audioCodecContext = 0;	    videoCodecContext = 0;	    if ( avFormatContext )		av_close_input_file( avFormatContext );	    avFormatContext = 0;	    openFlag.assign(0);	}	bufferMutex.signal();    }    // thread safe, contention safe    bool isOpen() {	return (bool)openFlag;    }/*    long getLastPacketTime() {	// Jump to near the end of the file	setPos(length() - 10000);	long lastTimeStamp = 0;	// Read packets till we get to the end to try and get the last timestamp available	MediaPacket *pkt;	while ( (pkt = getPacket()) ) {	    long long pktTime = pkt.msecOffset;	    if ( pktTime > lastTimeStamp )		lastTimeStamp = pktTime;	    delete pkt;	}	// Jump back to the beginning so we are ready to decode	setPos(0);	return lastTimeStamp;    }*/    // thread safe, contention safe    MediaPacket *getAnotherVideoPacket();    // thread safe, contention safe    MediaPacket *getAnotherAudioPacket();    // semi-thread safe, it reads the openFlag without locking    bool startBufferingPackets();private:    static void *startThreadLoop(void *arg);    MediaPacket *getPacket();    ThreadSafeInteger openFlag;    MediaPacketList waitingVideoPackets;    MediaPacketList waitingAudioPackets;    FFMutex avFormatMutex;    FFMutex bufferMutex;    AVFormatContext *avFormatContext;    AVCodecContext *audioCodecContext;    AVCodecContext *videoCodecContext;    ThreadSafeInteger videoStream;    ThreadSafeInteger audioStream;    ThreadSafeInteger fileOffset;    bool joined;    pthread_t threadId;};#endif // MEDIA_PACKET_BUFFER_H

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -