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