Sisyphus repository
Last update: 1 october 2023 | SRPMs: 18631 | Visits: 37702239
en ru br
ALT Linux repos
S:1.5-alt1.38416.2
D:1.0-alt35.27330.1
5.0: 1.0-alt35.27654.3
4.1: 1.0-alt35.26470.1
4.0: 1.0-alt35.23722.M40.1

Group :: Video
RPM: mplayer

 Main   Changelog   Spec   Patches   Sources   Download   Gear   Bugs and FR  Repocop 

Patch: ffmpeg-svn-r14967-xvmc-vld.patch
Download


diff -urN ffmpeg-svn-r14967.orig/libavcodec/allcodecs.c ffmpeg-svn-r14967/libavcodec/allcodecs.c
--- ffmpeg-svn-r14967.orig/libavcodec/allcodecs.c	2008-08-25 22:37:27 +0300
+++ ffmpeg-svn-r14967/libavcodec/allcodecs.c	2008-08-25 22:47:31 +0300
@@ -113,6 +113,7 @@
     REGISTER_DECODER (MMVIDEO, mmvideo);
     REGISTER_DECODER (MOTIONPIXELS, motionpixels);
     REGISTER_DECODER (MPEG_XVMC, mpeg_xvmc);
+    REGISTER_DECODER (MPEG_XVMC, mpeg_xxmc);
     REGISTER_ENCDEC  (MPEG1VIDEO, mpeg1video);
     REGISTER_ENCDEC  (MPEG2VIDEO, mpeg2video);
     REGISTER_ENCDEC  (MPEG4, mpeg4);
diff -urN ffmpeg-svn-r14967.orig/libavcodec/mpeg12.c ffmpeg-svn-r14967/libavcodec/mpeg12.c
--- ffmpeg-svn-r14967.orig/libavcodec/mpeg12.c	2008-08-25 22:37:27 +0300
+++ ffmpeg-svn-r14967/libavcodec/mpeg12.c	2008-08-25 22:50:37 +0300
@@ -67,6 +67,7 @@
 extern int XVMC_field_end(MpegEncContext *s);
 extern void XVMC_pack_pblocks(MpegEncContext *s,int cbp);
 extern void XVMC_init_block(MpegEncContext *s);//set s->block
+extern int XVMC_decode_slice(MpegEncContext *s, int start_code, uint8_t *buffer, int buf_size);
 
 static const enum PixelFormat pixfmt_yuv_420[]= {PIX_FMT_YUV420P,PIX_FMT_NONE};
 static const enum PixelFormat pixfmt_yuv_422[]= {PIX_FMT_YUV422P,PIX_FMT_NONE};
@@ -1659,6 +1660,14 @@
         return -1;
     }
 
+    if (s->avctx->xvmc_acceleration == 4){
+        int used = XVMC_decode_slice(s, mb_y, *buf, buf_size);
+        if (used < 0)
+            return DECODE_SLICE_ERROR;
+        *buf += used - 1;
+        return DECODE_SLICE_OK;
+    }
+
     init_get_bits(&s->gb, *buf, buf_size*8);
 
     ff_mpeg1_clean_buffers(s);
@@ -2486,3 +2495,34 @@
 };
 
 #endif
+
+static int mpeg_xxmc_decode_init(AVCodecContext *avctx){
+    Mpeg1Context *s;
+    if( avctx->thread_count > 1)
+        return -1;
+    if( !(avctx->slice_flags & SLICE_FLAG_CODED_ORDER) )
+        return -1;
+    if( !(avctx->slice_flags & SLICE_FLAG_ALLOW_FIELD) )
+        dprintf("mpeg12.c: XVMC_VLD decoder will work better if SLICE_FLAG_ALLOW_FIELD is set\n");
+
+    mpeg_decode_init(avctx);
+    s = avctx->priv_data;
+
+    avctx->pix_fmt = PIX_FMT_XVMC_MPEG2_VLD;
+    avctx->xvmc_acceleration = 4;
+
+    return 0;
+}
+
+AVCodec mpeg_xxmc_decoder = {
+    "mpegvideo_xvmc",
+    CODEC_TYPE_VIDEO,
+    CODEC_ID_MPEG2VIDEO_XVMC,
+    sizeof(Mpeg1Context),
+    mpeg_xxmc_decode_init,
+    NULL,
+    mpeg_decode_end,
+    mpeg_decode_frame,
+    CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED| CODEC_CAP_HWACCEL,
+    .flush= ff_mpeg_flush,
+};
diff -urN ffmpeg-svn-r14967.orig/libavcodec/xvmc_render.h ffmpeg-svn-r14967/libavcodec/xvmc_render.h
--- ffmpeg-svn-r14967.orig/libavcodec/xvmc_render.h	2008-02-23 00:51:46 +0200
+++ ffmpeg-svn-r14967/libavcodec/xvmc_render.h	2008-08-25 22:47:31 +0300
@@ -27,6 +27,7 @@
 #include <X11/extensions/Xv.h>
 #include <X11/extensions/Xvlib.h>
 #include <X11/extensions/XvMClib.h>
+#include <X11/extensions/vldXvMC.h>
 
 
 //the surface should be shown, video driver manipulates this
@@ -69,6 +70,13 @@
   int next_free_data_block_num;//used in add_mv_block, pointer to next free block
 //extensions
   void * p_osd_target_surface_render;//pointer to the surface where subpicture is rendered
+  // These are for the XVMC VLD slice interface
+  int pict_type; //this is for skipping frames
+  int   slice_code; 
+  int   slice_datalen;
+  unsigned char *slice_data;
+  Display *disp;
+  XvMCContext *ctx;
 
 } xvmc_render_state_t;
 
diff -urN ffmpeg-svn-r14967.orig/libavcodec/xvmcvideo.c ffmpeg-svn-r14967/libavcodec/xvmcvideo.c
--- ffmpeg-svn-r14967.orig/libavcodec/xvmcvideo.c	2008-04-01 01:42:36 +0300
+++ ffmpeg-svn-r14967/libavcodec/xvmcvideo.c	2008-08-25 22:47:31 +0300
@@ -66,11 +66,63 @@
     }
 }
 
+static XvMCSurface* findPastSurface(MpegEncContext *s, xvmc_render_state_t *render)
+{
+    Picture *lastp = s->last_picture_ptr;
+    xvmc_render_state_t *last = NULL;
+
+    if (NULL!=lastp) {
+        last = (xvmc_render_state_t*)(lastp->data[2]);
+        if (FF_B_TYPE==last->pict_type)
+            av_log(s->avctx,AV_LOG_DEBUG, "Past frame is a B frame in findPastSurface, this is bad.\n");
+        //assert(FF_B_TYPE!=last->pict_type);
+    }
+
+    if (NULL==last)
+        if (!s->first_field)
+            last = render; // predict second field from the first
+        else
+            return 0;
+
+    if (last->magic != MP_XVMC_RENDER_MAGIC)
+        return 0;
+
+    return (last->state & MP_XVMC_STATE_PREDICTION) ? last->p_surface : 0;
+ }
+
+static XvMCSurface* findFutureSurface(MpegEncContext *s)
+{
+    Picture *nextp = s->next_picture_ptr;
+    xvmc_render_state_t *next = NULL;
+
+    if (NULL!=nextp) {
+        next = (xvmc_render_state_t*)(nextp->data[2]);
+        if (FF_B_TYPE==next->pict_type)
+            av_log(s->avctx,AV_LOG_DEBUG, "Next frame is a B frame in findFutureSurface, thisis bad.\n");
+        //assert(FF_B_TYPE!=next->pict_type);
+    }
+
+    assert(NULL!=next);
+
+    if (next->magic != MP_XVMC_RENDER_MAGIC)
+        return 0;
+
+    return (next->state & MP_XVMC_STATE_PREDICTION) ? next->p_surface : 0;
+}
+
 //These functions should be called on every new field and/or frame.
 //They should be safe if they are called a few times for the same field!
 int XVMC_field_start(MpegEncContext*s, AVCodecContext *avctx){
 xvmc_render_state_t * render,* last, * next;
 
+    XvMCMpegControl     binfo;
+    XvMCQMatrix         qmatrix;
+    int                 i;
+    Status              status;
+
+    memset(&binfo, 0, sizeof(binfo));
+    memset(&qmatrix, 0, sizeof(qmatrix));
+
     assert(avctx != NULL);
 
     render = (xvmc_render_state_t*)s->current_picture.data[2];
@@ -81,12 +133,49 @@
     render->picture_structure = s->picture_structure;
     render->flags = (s->first_field)? 0: XVMC_SECOND_FIELD;
 
+    if (s->avctx->xvmc_acceleration == 4)
+    {
+        if (render->picture_structure == PICT_FRAME)
+            render->flags |= XVMC_FRAME_PICTURE;
+        else if (render->picture_structure == PICT_TOP_FIELD)
+            render->flags |= XVMC_TOP_FIELD;
+        else if (render->picture_structure == PICT_BOTTOM_FIELD)
+            render->flags |= XVMC_BOTTOM_FIELD;
+    }
+    else
+    {
 //make sure that all data is drawn by XVMC_end_frame
     assert(render->filled_mv_blocks_num==0);
+    }
 
     render->p_future_surface = NULL;
     render->p_past_surface = NULL;
 
+    render->pict_type = s->pict_type; // for later frame dropping use
+
+    if (s->avctx->xvmc_acceleration == 4)
+{
+    switch(s->pict_type){
+        case  FF_I_TYPE:
+            break;
+        case  FF_B_TYPE:
+            render->p_past_surface = findPastSurface(s, render);
+            render->p_future_surface = findFutureSurface(s);
+            if (!render->p_past_surface)
+                av_log(avctx, AV_LOG_ERROR, "error: decoding B frame and past frame is null!");
+            else if (!render->p_future_surface)
+                av_log(avctx, AV_LOG_ERROR, "error: decoding B frame and future frame is null!");
+            break;
+            
+        case  FF_P_TYPE:
+            render->p_past_surface = findPastSurface(s, render);
+            render->p_future_surface = render->p_surface;
+            if (!render->p_past_surface)
+                av_log(avctx, AV_LOG_ERROR, "error: decoding P frame and past frame is null!");
+            break;
+    }
+} else
+{
     switch(s->pict_type){
         case  FF_I_TYPE:
             return 0;// no prediction from other frames
@@ -107,8 +196,94 @@
             render->p_past_surface = last->p_surface;
             return 0;
     }
+}
+
+    if (s->avctx->xvmc_acceleration == 4)
+    {
+        for (i = 0; i < 64; i++){
+        qmatrix.intra_quantiser_matrix[i] = s->intra_matrix[s->dsp.idct_permutation[i]];
+        qmatrix.non_intra_quantiser_matrix[i] = s->inter_matrix[s->dsp.idct_permutation[i]];
+        qmatrix.chroma_intra_quantiser_matrix[i] = s->chroma_intra_matrix[s->dsp.idct_permutation[i]];
+        qmatrix.chroma_non_intra_quantiser_matrix[i] = s->chroma_inter_matrix[s->dsp.idct_permutation[i]];
+        }
+
+    qmatrix.load_intra_quantiser_matrix = 1;
+    qmatrix.load_non_intra_quantiser_matrix = 1;
+    qmatrix.load_chroma_intra_quantiser_matrix = 1;
+    qmatrix.load_chroma_non_intra_quantiser_matrix = 1;
+
+
+    binfo.flags = 0;
+    if (s->alternate_scan)
+        binfo.flags |= XVMC_ALTERNATE_SCAN;
+    if (s->top_field_first)
+        binfo.flags |= XVMC_TOP_FIELD_FIRST;
+    if (s->frame_pred_frame_dct)
+        binfo.flags |= XVMC_PRED_DCT_FRAME;
+    else
+        binfo.flags |= XVMC_PRED_DCT_FIELD;
+
+    if (s->intra_vlc_format)
+        binfo.flags |= XVMC_INTRA_VLC_FORMAT;
+    if (!s->first_field && !s->progressive_sequence)
+        binfo.flags |= XVMC_SECOND_FIELD;
+    if (s->q_scale_type)
+        binfo.flags |= XVMC_Q_SCALE_TYPE;
+    if (s->concealment_motion_vectors)
+        binfo.flags |= XVMC_CONCEALMENT_MOTION_VECTORS;
+    if (s->progressive_sequence)
+        binfo.flags |= XVMC_PROGRESSIVE_SEQUENCE;
+
+    binfo.picture_structure = s->picture_structure;
+    switch (s->pict_type)
+    {
+    case FF_I_TYPE:    binfo.picture_coding_type = XVMC_I_PICTURE;     break;
+    case FF_P_TYPE:    binfo.picture_coding_type = XVMC_P_PICTURE;     break;
+    case FF_B_TYPE:    binfo.picture_coding_type = XVMC_B_PICTURE;     break;
+    default:    av_log(avctx, AV_LOG_ERROR, "%s: Unknown picture coding type: %d\n", __FUNCTION__, s->pict_type);
+    }
+
+    binfo.intra_dc_precision = s->intra_dc_precision;;
+
+    if (s->codec_id == CODEC_ID_MPEG2VIDEO)
+        binfo.mpeg_coding = 2;
+    else
+        binfo.mpeg_coding = 1;
+
+    s->mb_width = (s->width + 15) / 16;
+    s->mb_height = (s->codec_id == CODEC_ID_MPEG2VIDEO && !s->progressive_sequence) ?
+        2 * ((s->height + 31) / 32) : (s->height + 15) / 16;
+
+    if (s->codec_id == CODEC_ID_MPEG2VIDEO)
+{
+    binfo.FVMV_range = (s->mpeg_f_code[0][1] - 1);
+    binfo.FHMV_range = (s->mpeg_f_code[0][0] - 1);
+    binfo.BVMV_range = (s->mpeg_f_code[1][1] - 1);
+    binfo.BHMV_range = (s->mpeg_f_code[1][0] - 1);
+}
+else
+{
+    binfo.FVMV_range = (s->mpeg_f_code[0][0] - 1);
+    binfo.FHMV_range = (s->mpeg_f_code[0][0] - 1);
+    binfo.BVMV_range = (s->mpeg_f_code[1][1] - 1);
+    binfo.BHMV_range = (s->mpeg_f_code[1][1] - 1);
+}
+
+    status = XvMCLoadQMatrix(render->disp, render->ctx, &qmatrix);
+    if (status)
+        av_log(avctx,AV_LOG_ERROR, "XvMCLoadQMatrix: Error: %d\n", status);
+
+    status = XvMCBeginSurface(render->disp, render->ctx, render->p_surface,
+                              render->p_past_surface, render->p_future_surface,
+                              &binfo);
+    if (status)
+        av_log(avctx,AV_LOG_ERROR, "XvMCBeginSurface: Error: %d\n", status);
+
+    if (!status)
+        return 0;
+    }
 
-return -1;
+    return -1;
 }
 
 void XVMC_field_end(MpegEncContext *s){
@@ -116,10 +291,20 @@
     render = (xvmc_render_state_t*)s->current_picture.data[2];
     assert(render != NULL);
 
+    if (s->avctx->xvmc_acceleration == 4)
+    {
+        XvMCFlushSurface(render->disp, render->p_surface);
+        XvMCSyncSurface(render->disp, render->p_surface);
+
+    	s->error_count = 0;
+    }
+    else
+    {
     if(render->filled_mv_blocks_num > 0){
 //        printf("xvmcvideo.c: rendering %d left blocks after last slice!!!\n",render->filled_mv_blocks_num );
         ff_draw_horiz_band(s,0,0);
     }
+    }
 }
 
 void XVMC_decode_mb(MpegEncContext *s){
@@ -308,3 +493,46 @@
 // DumpMBlockInfo(mv_block);
 
 }
+
+static int length_to_next_start(uint8_t* pbuf_ptr, int buf_size)
+{
+    uint8_t*    buf_ptr;
+    unsigned int    state = 0xFFFFFFFF, v;
+
+    buf_ptr = pbuf_ptr;
+    while (buf_ptr < pbuf_ptr + buf_size)
+    {
+        v = *buf_ptr++;
+        if (state == 0x000001) {
+            return buf_ptr - pbuf_ptr - 4;
+        }
+        state = ((state << 8) | v) & 0xffffff;
+    }
+    return -1;
+}
+
+#define SLICE_MIN_START_CODE   0x00000101
+#define SLICE_MAX_START_CODE   0x000001af
+
+void XVMC_decode_slice(MpegEncContext *s, int mb_y, uint8_t* buffer, int buf_size)
+{
+    int slicelen = length_to_next_start(buffer, buf_size);
+    xvmc_render_state_t*    render;
+
+    if (slicelen < 0)
+    {
+        if ((mb_y == s->mb_height - 1) || 
+            (!s->progressive_sequence && mb_y == (s->mb_height >> 1) -1) ||
+            (s->codec_id != CODEC_ID_MPEG2VIDEO))
+            slicelen = buf_size;
+        else
+            return;
+    }
+
+    render = (xvmc_render_state_t*)s->current_picture.data[2];
+    render->slice_code = SLICE_MIN_START_CODE + mb_y;
+    render->slice_data = buffer;
+    render->slice_datalen = slicelen;
+
+    ff_draw_horiz_band(s, 0, 0);
+}
diff -urN ffmpeg-svn-r14967.orig/libavutil/avutil.h ffmpeg-svn-r14967/libavutil/avutil.h
--- ffmpeg-svn-r14967.orig/libavutil/avutil.h	2008-08-25 22:37:28 +0300
+++ ffmpeg-svn-r14967/libavutil/avutil.h	2008-08-25 22:47:31 +0300
@@ -99,6 +99,7 @@
     PIX_FMT_YUVJ444P,  ///< Planar YUV 4:4:4, 24bpp, full scale (jpeg)
     PIX_FMT_XVMC_MPEG2_MC,///< XVideo Motion Acceleration via common packet passing(xvmc_render.h)
     PIX_FMT_XVMC_MPEG2_IDCT,
+    PIX_FMT_XVMC_MPEG2_VLD,
     PIX_FMT_UYVY422,   ///< Packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
     PIX_FMT_UYYVYY411, ///< Packed YUV 4:1:1, 12bpp, Cb Y0 Y1 Cr Y2 Y3
     PIX_FMT_BGR32,     ///< Packed RGB 8:8:8, 32bpp, (msb)8A 8B 8G 8R(lsb), in cpu endianness
 
design & coding: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
current maintainer: Michael Shigorin