SOURCES: mythtv-dshowserver_trunk.patch (NEW) - adds dshowserver support - ...
w.kier
w.kier at pld-linux.org
Sun Mar 8 21:03:14 CET 2009
Author: w.kier Date: Sun Mar 8 20:03:14 2009 GMT
Module: SOURCES Tag: HEAD
---- Log message:
- adds dshowserver support - win32 coreserve commercial codec server
not codec only possibility to use it
---- Files affected:
SOURCES:
mythtv-dshowserver_trunk.patch (NONE -> 1.1) (NEW)
---- Diffs:
================================================================
Index: SOURCES/mythtv-dshowserver_trunk.patch
diff -u /dev/null SOURCES/mythtv-dshowserver_trunk.patch:1.1
--- /dev/null Sun Mar 8 21:03:15 2009
+++ SOURCES/mythtv-dshowserver_trunk.patch Sun Mar 8 21:03:09 2009
@@ -0,0 +1,425 @@
+diff -urN mythtv-0.22.orig/libs/libmythtv/avformatdecoder.cpp mythtv-0.22/libs/libmythtv/avformatdecoder.cpp
+--- mythtv-0.22.orig/libs/libmythtv/avformatdecoder.cpp 2009-02-17 19:57:44.000000000 +0100
++++ mythtv-0.22/libs/libmythtv/avformatdecoder.cpp 2009-03-02 20:04:25.000000000 +0100
+@@ -2,12 +2,16 @@
+ #include <cassert>
+ #include <unistd.h>
+ #include <cmath>
++#include <fcntl.h>
+
+ // C++ headers
+ #include <algorithm>
+ #include <iostream>
+ using namespace std;
+
++// QT headers
++#include "qdir.h"
++
+ // MythTV headers
+ #include "mythconfig.h"
+ #include "avformatdecoder.h"
+@@ -53,6 +57,7 @@
+ #include "avio.h"
+ #include "../libmythmpeg2/mpeg2.h"
+ #include "ivtv_myth.h"
++#include "libavformat/riff.h"
+ }
+
+ #define LOC QString("AFD: ")
+@@ -149,21 +154,56 @@
+
+ typedef MythDeque<AVFrame*> avframe_q;
+
++struct vd_struct {
++ union {
++ uint32_t ret;
++ uint32_t cmd;
++ };
++ uint32_t buflen;
++ uint64_t pts;
++ uint32_t unused[8];
++} __attribute__((__packed__));
++
++enum {
++ VD_END = 1,
++ VD_DECODE = 2,
++ VD_SEEK = 3,
++ VD_HAS_BIH = 0x10000,
++ VD_VERSION_MASK = 0xFFFF,
++};
++
++#include <semaphore.h>
++#include <sys/mman.h>
++typedef struct {
++ int fd;
++ void *mem;
++ char *data;
++ char *picture;
++ int picsize;
++ sem_t *sem_rd;
++ sem_t *sem_wr;
++ struct vd_struct *vd;
++} ds_mpi_t;
++
+ /**
+ * Management of libmpeg2 decoding
+ */
+ class AvFormatDecoderPrivate
+ {
+ public:
+- AvFormatDecoderPrivate(bool allow_libmpeg2)
+- : mpeg2dec(NULL), dvdvdec(NULL), allow_mpeg2dec(allow_libmpeg2) { ; }
+- ~AvFormatDecoderPrivate() { DestroyMPEG2(); }
++ AvFormatDecoderPrivate(bool allow_libmpeg2, bool allow_directshow)
++ : mpeg2dec(NULL), dvdvdec(NULL), allow_mpeg2dec(allow_libmpeg2),
++ ds_mpi(NULL), allow_dshow(allow_directshow) { ; }
++ ~AvFormatDecoderPrivate() { DestroyMPEG2(); DestroyDirectShow();}
+
+ bool InitMPEG2(const QString &dec);
+ bool HasMPEG2Dec(void) const { return (bool)(mpeg2dec); }
+ bool HasDVDVDec(void) const { return (bool)(dvdvdec); }
+ bool HasDecoder(void) const { return HasMPEG2Dec() || HasDVDVDec(); }
+
++ bool InitDirectShow(AVCodecContext *enc);
++ bool HasDirectShow() const { return (bool)(ds_mpi); }
++
+ void DestroyMPEG2();
+ void ResetMPEG2();
+ int DecodeMPEG2Video(AVCodecContext *avctx, AVFrame *picture,
+@@ -173,13 +213,259 @@
+ bool SetVideoSize(const QSize &video_dim);
+ DVDV *GetDVDVDecoder(void) { return dvdvdec; }
+
++ void DestroyDirectShow();
++ void ResetDirectShow();
++ int DecodeDirectShowVideo(AVCodecContext *avctx, AVFrame *picture,
++ int *got_picture_ptr, uint8_t *buf, int buf_size,
++ long long *pts);
++
+ private:
+ mpeg2dec_t *mpeg2dec;
+ DVDV *dvdvdec;
+ bool allow_mpeg2dec;
++ ds_mpi_t *ds_mpi;
++ bool allow_dshow;
+ avframe_q partialFrames;
+ };
+
++static int sem_twait(sem_t *sem, int t) {
++ struct timespec ts;
++ clock_gettime(CLOCK_REALTIME, &ts);
++ ts.tv_sec += t;
++ return(sem_timedwait(sem, &ts));
++}
++bool AvFormatDecoderPrivate::InitDirectShow(AVCodecContext *enc)
++{
++ typedef struct {
++ uint32_t f1;
++ uint16_t f2;
++ uint16_t f3;
++ uint8_t f4[8];
++ } GUID;
++
++ const struct AVCodecTag *bmp_taglists[] = {codec_bmp_tags, 0};
++
++ if(enc->codec_tag == 0)
++ enc->codec_tag = av_codec_get_tag(bmp_taglists, enc->codec_id);
++ VERBOSE(VB_IMPORTANT, LOC + QString("Trying DirectShow for FOURCC 0x%1")
++ .arg(enc->codec_tag, 8, 16));
++ if (!allow_dshow)
++ return false;
++ DestroyDirectShow();
++ if (enc->codec_tag == 0) {
++ allow_dshow = false;
++ return false;
++ }
++// QString dec = gContext->GetSetting("UseDirectShowVideoDecoder", "no");
++ QString dec = "yes";
++
++ if (dec == "yes")
++ {
++ bool found = false;
++ QString codec;
++ GUID guid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};
++ QString codec_file = QDir::homePath() +
++ QString("/.mythtv/dshowcodecs");
++ if (! QFileInfo(codec_file).isFile()) {
++ allow_dshow = false;
++ return false;
++ }
++ QString videotype;
++ AVCodec *avc = avcodec_find_decoder(enc->codec_id);
++ if (! avc) {
++ allow_dshow = false;
++ return false;
++ }
++ videotype = avc->name;
++ QFile fh (codec_file);
++ QString line;
++ fh.open(QIODevice::ReadOnly);
++ while (! fh.atEnd() && ! found) {
++ QStringList fourc, guidlist;
++ line = fh.readLine(1024);
++ codec = line.section(':', 0, 0).simplified();
++ fourc = line.section(':', 1, 1).split(",");
++ guidlist = line.section(':', 2, 2).split(",");
++ if (guidlist.count() != 11)
++ continue;
++ for (QStringList::Iterator it = fourc.begin();
++ it != fourc.end(); it++)
++ {
++ if ((*it).simplified() == videotype)
++ {
++ guid.f1 = guidlist[0].toUInt(0, 0);
++ guid.f2 = guidlist[1].toUShort(0, 0);
++ guid.f3 = guidlist[2].toUShort(0, 0);
++ for (int i = 0; i < 8; i++)
++ guid.f4[i] = guidlist[i + 3].toUShort(0, 0);
++ found = true;
++ }
++ }
++ if (found)
++ break;
++ }
++ fh.close();
++ if (found) {
++ int ret;
++ char cmd[255], shm[80], sem1[80], sem2[80];
++ uint32_t out_fmt;
++ int bpp;
++ //out_fmt = 0x30323449; bpp = 12; //I420 12bpp
++ out_fmt = 0x32595559; bpp = 16; //YUY2 16bpp
++ snprintf(cmd, 255, "dshowserver -c %s -s %dx%d "
++ "-g %08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x "
++ "-f 0x%08x -b %d -o 0x%08x -p %d -i %x %s&",
++ codec.toAscii().constData(), enc->width, enc->height,
++ guid.f1, guid.f2, guid.f3,
++ guid.f4[0], guid.f4[1], guid.f4[2], guid.f4[3],
++ guid.f4[4], guid.f4[5], guid.f4[6], guid.f4[7],
++ enc->codec_tag, bpp, out_fmt, getpid(), *(int *)pthread_self(),
++ ((print_verbose_messages & VB_PLAYBACK) == VB_PLAYBACK ?
++ "-d" : ""));
++ ds_mpi = new ds_mpi_t;
++ snprintf(shm, 80, "/dshow_shm.%x", *(int *)pthread_self());
++ snprintf(sem1, 80, "/dshow_sem1.%x", *(int *)pthread_self());
++ snprintf(sem2, 80, "/dshow_sem2.%x", *(int *)pthread_self());
++ ds_mpi->fd = shm_open(shm, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
++ ds_mpi->picsize = enc->width * enc->height * bpp / 8;
++ int extra = 0;
++ if (enc->height % 16)
++ extra = (16 - enc->height % 16) * bpp / 8;
++ int memsize = sizeof(struct vd_struct) + enc->width * enc->height +
++ ds_mpi->picsize + extra;
++ ftruncate(ds_mpi->fd, memsize);
++ ds_mpi->mem = mmap(NULL, memsize, PROT_READ | PROT_WRITE,
++ MAP_SHARED, ds_mpi->fd, 0);
++ if(ds_mpi->mem == MAP_FAILED) {
++ perror("mmap");
++ allow_dshow = false;
++ return false;
++ }
++ memset((char *)ds_mpi->mem, 0, sizeof(struct vd_struct));
++
++ if (extra)
++ memset((char *)ds_mpi->mem + (memsize - extra), 0, extra);
++ ds_mpi->vd = (struct vd_struct *)ds_mpi->mem;
++ ds_mpi->data = ((char *)ds_mpi->mem) + sizeof(struct vd_struct);
++ ds_mpi->picture = ds_mpi->data + enc->width * enc->height;
++ //Create read/write semaphores in locked state
++ ds_mpi->sem_wr = sem_open(sem1, O_CREAT, 0644, 0);
++ ds_mpi->sem_rd = sem_open(sem2, O_CREAT, 0644, 0);
++ myth_system(cmd);
++ ret = sem_twait(ds_mpi->sem_rd, 10);
++ shm_unlink(shm);
++ sem_unlink(sem1);
++ sem_unlink(sem2);
++ if(ret != 0) {
++ VERBOSE(VB_IMPORTANT, LOC + "DirectShow filter failed");
++ } else {
++ VERBOSE(VB_IMPORTANT, LOC + "Found DirectShow filter");
++ return true;
++ }
++ }
++ }
++ allow_dshow = false;
++ return false;
++}
++
++void AvFormatDecoderPrivate::DestroyDirectShow()
++{
++ if (ds_mpi)
++ {
++ VERBOSE(VB_PLAYBACK, LOC + "Destroying filter");
++ ds_mpi->vd->cmd = VD_END; //'1' is cmd for terminating
++ sem_post(ds_mpi->sem_wr);
++ close(ds_mpi->fd);
++ sem_close(ds_mpi->sem_wr);
++ sem_close(ds_mpi->sem_rd);
++ delete ds_mpi;
++ ds_mpi = NULL;
++ }
++}
++
++void AvFormatDecoderPrivate::ResetDirectShow()
++{
++ if (ds_mpi) {
++ ds_mpi->vd->cmd = VD_SEEK; //'3' is cmd for seek
++ sem_post(ds_mpi->sem_wr);
++ sem_twait(ds_mpi->sem_rd, 10);
++ }
++}
++
++void yuy2i420(AVFrame *dst, char *src, int w, int l)
++{
++ uint8_t *y, *u, *v;
++ y = dst->data[0];
++ u = dst->data[1];
++ v = dst->data[2];
++ int i,j;
++ for(i=0; i < l; i++) {
++ for(j=0; j < w; j+=2) {
++ *(y++) = *(src++);
++ *(u++) = *(src++);
++ *(y++) = *(src++);
++ *(v++) = *(src++);
++ }
++ i++;
++ for(j=0; j < w; j+=2) {
++ *(y++) = *src;
++ src+=2;
++ *(y++) = *src;
++ src+=2;
++ }
++ }
++}
++
++int AvFormatDecoderPrivate::DecodeDirectShowVideo(AVCodecContext *avctx,
++ AVFrame *picture,
++ int *got_picture_ptr,
++ uint8_t *buf, int buf_size,
++ long long *pts)
++{
++ int ret;
++ ds_mpi->vd->cmd = VD_DECODE; //'1' is cmd for decoding
++ memcpy(ds_mpi->data, buf, buf_size);
++ ds_mpi->vd->buflen = buf_size;
++ ds_mpi->vd->pts = (uint64_t)*pts;
++ sem_post(ds_mpi->sem_wr);
++ ret = sem_twait(ds_mpi->sem_rd, 10);
++ if (ret == 0 && ds_mpi->vd->ret && ! (ds_mpi->vd->ret & (1<<31))) {
++ *got_picture_ptr = 1;
++ if (ds_mpi->vd->pts) {
++ *pts = (long long)ds_mpi->vd->pts;
++ }
++ picture->interlaced_frame = (ds_mpi->vd->ret & 10) ? true : false;
++ avctx->get_buffer(avctx, picture);
++#if 0 //Using YV12
++ if(avctx->height & 0x0f) {
++ unsigned long pos, pos1, siz = avctx->height * avctx->width;
++ memcpy(picture->data[0], ds_mpi->picture, siz);
++ pos = siz;
++ pos1 = siz + avctx->width * (16 - avctx->height % 16);
++ siz /= 4;
++ memcpy(picture->data[0]+pos1, ds_mpi->picture+pos, siz);
++ pos+=siz;
++ pos1+=siz + avctx->width * ( 16 - avctx->height % 16) / 4;
++ memcpy(picture->data[0]+pos1, ds_mpi->picture+pos, siz);
++ } else {
++ memcpy(picture->data[0], ds_mpi->picture, ds_mpi->picsize);
++ }
++#else //Using YUY2
++ //YUY2 is a packed format so padding is easier
++ //int extra = 0;
++ //if(avctx->height % 16)
++ //extra = (16 - avctx->height % 16);
++ yuy2i420(picture, ds_mpi->picture,
++ avctx->width, avctx->height);
++#endif
++ } else {
++ *got_picture_ptr = 0;
++ }
++ return buf_size;
++}
++
++/*************************************************/
++
+ /**
+ * \brief Initialise either libmpeg2, or DVDV (Mac HW accel), to do decoding
+ *
+@@ -401,7 +687,7 @@
+ bool use_null_videoout,
+ bool allow_libmpeg2)
+ : DecoderBase(parent, pginfo),
+- d(new AvFormatDecoderPrivate(allow_libmpeg2)),
++ d(new AvFormatDecoderPrivate(allow_libmpeg2, true)),
+ is_db_ignored(gContext->IsDatabaseIgnored()),
+ m_h264_parser(new H264Parser()),
+ ic(NULL),
+@@ -684,6 +970,7 @@
+ avcodec_flush_buffers(enc);
+ }
+ d->ResetMPEG2();
++ d->ResetDirectShow();
+ }
+
+ // Discard all the queued up decoded frames
+@@ -1584,6 +1871,9 @@
+ }
+ }
+
++ if (CODEC_ID_H264 == enc->codec_id)
++ force_xv = true;
++
+ MythCodecID mcid;
+ mcid = VideoOutputXv::GetBestSupportedCodec(
+ /* disp dim */ width, height,
+@@ -1593,6 +1883,7 @@
+ /* test surface */ kCodec_NORMAL_END > video_codec_id,
+ /* force_xv */ force_xv);
+ bool vcd, idct, mc, vdpau;
++
+ enc->codec_id = (CodecID)
+ myth2av_codecid(mcid, vcd, idct, mc, vdpau);
+
+@@ -1668,6 +1959,7 @@
+ }
+
+ // Initialize alternate decoders when needed...
++ if (! d->InitDirectShow(enc))
+ if (((dec == "libmpeg2") &&
+ (CODEC_ID_MPEG1VIDEO == enc->codec_id ||
+ CODEC_ID_MPEG2VIDEO == enc->codec_id)) ||
+@@ -3756,7 +4048,21 @@
+ int gotpicture = 0;
+
+ avcodeclock.lock();
+- if (d->HasDecoder())
++/* printf("Trying: %d\n",len);
++ if (0) {
++ static int fnum = 0;
++ char str[80];
++ int fh;
++ sprintf(str,"enc%d", fnum++);;
++ fh = open(str, 01101,00777);
++ write(fh, ptr, len);
++ close(fh);
++ }
++*/
++ if (d->HasDirectShow())
++ ret = d->DecodeDirectShowVideo(context, &mpa_pic,
++ &gotpicture, ptr, len, &pts);
++ else if (d->HasDecoder())
+ {
+ if (decodeStillFrame)
+ {
+diff -urN mythtv-0.22.orig/libs/libmythtv/libmythtv.pro mythtv-0.22/libs/libmythtv/libmythtv.pro
+--- mythtv-0.22.orig/libs/libmythtv/libmythtv.pro 2009-02-17 19:57:44.000000000 +0100
++++ mythtv-0.22/libs/libmythtv/libmythtv.pro 2009-03-02 19:54:23.000000000 +0100
+@@ -57,6 +57,7 @@
+ }
+ using_backend: LIBS += -lmp3lame
+ LIBS += -lz $$EXTRA_LIBS $$QMAKE_LIBS_DYNLOAD
++LIBS += -lrt
+
+ TARGETDEPS += ../libmyth/libmyth-$${MYTH_SHLIB_EXT}
+ TARGETDEPS += ../libavutil/libmythavutil-$${MYTH_SHLIB_EXT}
================================================================
More information about the pld-cvs-commit
mailing list