ALT Linux Bugzilla
– Attachment 2278 Details for
Bug 13452
openchrome XvMC mpeg2 decoding is not supported
New bug
|
Search
|
[?]
|
Help
Register
|
Log In
[x]
|
Forgot Password
Login:
[x]
|
EN
|
RU
[patch]
"ffmpeg" part of openchrome XvMC VLD patch
ffmpeg-10924-alt1-my_xvmc-vld.patch (text/plain), 15.10 KB, created by
Andrey Liakhovets
on 2007-11-16 15:15:21 MSK
(
hide
)
Description:
"ffmpeg" part of openchrome XvMC VLD patch
Filename:
MIME Type:
Creator:
Andrey Liakhovets
Created:
2007-11-16 15:15:21 MSK
Size:
15.10 KB
patch
obsolete
>diff -Naur ffmpeg-10924-alt1.rvrt/libavcodec/allcodecs.c ffmpeg-10924-alt1.xvmc/libavcodec/allcodecs.c >--- ffmpeg-10924-alt1.rvrt/libavcodec/allcodecs.c 2007-11-06 23:23:52 +0300 >+++ ffmpeg-10924-alt1.xvmc/libavcodec/allcodecs.c 2007-11-09 22:07:08 +0300 >@@ -104,6 +104,7 @@ > REGISTER_ENCDEC (MJPEG, mjpeg); > REGISTER_DECODER (MJPEGB, mjpegb); > REGISTER_DECODER (MMVIDEO, mmvideo); >+ REGISTER_DECODER (MPEG_XVMC_VLD, mpeg_xvmc_vld); > REGISTER_DECODER (MPEG_XVMC, mpeg_xvmc); > REGISTER_ENCDEC (MPEG1VIDEO, mpeg1video); > REGISTER_ENCDEC (MPEG2VIDEO, mpeg2video); >diff -Naur ffmpeg-10924-alt1.rvrt/libavcodec/mpeg12.c ffmpeg-10924-alt1.xvmc/libavcodec/mpeg12.c >--- ffmpeg-10924-alt1.rvrt/libavcodec/mpeg12.c 2007-11-06 23:23:52 +0300 >+++ ffmpeg-10924-alt1.xvmc/libavcodec/mpeg12.c 2007-11-09 22:07:08 +0300 >@@ -70,6 +70,13 @@ > extern void XVMC_pack_pblocks(MpegEncContext *s,int cbp); > extern void XVMC_init_block(MpegEncContext *s);//set s->block > >+ >+#ifdef HAVE_XVMC_VLD >+extern int XVMC_decode_slice(MpegEncContext *s, int start_code, >+ uint8_t *buffer, int buf_size); >+int has_xvmc_vld = 0; >+#endif >+ > static const enum PixelFormat pixfmt_yuv_420[]= {PIX_FMT_YUV420P,-1}; > static const enum PixelFormat pixfmt_yuv_422[]= {PIX_FMT_YUV422P,-1}; > static const enum PixelFormat pixfmt_yuv_444[]= {PIX_FMT_YUV444P,-1}; >@@ -77,6 +84,11 @@ > PIX_FMT_XVMC_MPEG2_IDCT, > PIX_FMT_XVMC_MPEG2_MC, > -1}; >+static const enum PixelFormat pixfmt_xvmc_vld_mpg2_420[] = { >+ PIX_FMT_XVMC_MPEG2_VLD, >+ PIX_FMT_XVMC_MPEG2_IDCT, >+ PIX_FMT_XVMC_MPEG2_MC, >+ -1}; > > uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; > >@@ -1313,6 +1325,9 @@ > }//mpeg2 > > if(avctx->xvmc_acceleration){ >+ if (has_xvmc_vld) >+ avctx->pix_fmt = avctx->get_format(avctx,pixfmt_xvmc_vld_mpg2_420); >+ else > avctx->pix_fmt = avctx->get_format(avctx,pixfmt_xvmc_mpg2_420); > }else{ > if(s->chroma_format < 2){ >@@ -1682,6 +1697,16 @@ > return -1; > } > >+#ifdef HAVE_XVMC_VLD >+ 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; >+ } >+#endif >+ > init_get_bits(&s->gb, *buf, buf_size*8); > > ff_mpeg1_clean_buffers(s); >@@ -2077,6 +2102,9 @@ > s->low_delay= 1; > > if(avctx->xvmc_acceleration){ >+ if (has_xvmc_vld) >+ avctx->pix_fmt = avctx->get_format(avctx,pixfmt_xvmc_vld_mpg2_420); >+ else > avctx->pix_fmt = avctx->get_format(avctx,pixfmt_xvmc_mpg2_420); > }else{ > avctx->pix_fmt = avctx->get_format(avctx,pixfmt_yuv_420); >@@ -2474,6 +2502,43 @@ > > #endif > >+#ifdef HAVE_XVMC_VLD >+static int mpeg_xxmc_decode_init(AVCodecContext *avctx){ >+ Mpeg1Context *s; >+ if (!has_xvmc_vld) >+ return mpeg_mc_decode_init(avctx); >+ 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_xvmc_vld_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, >+}; >+ >+#endif >+ >+ > /* this is ugly i know, but the alternative is too make > hundreds of vars global and prefix them with ff_mpeg1_ > which is far uglier. */ >diff -Naur ffmpeg-10924-alt1.rvrt/libavcodec/xvmc_render.h ffmpeg-10924-alt1.xvmc/libavcodec/xvmc_render.h >--- ffmpeg-10924-alt1.rvrt/libavcodec/xvmc_render.h 2007-11-06 23:23:52 +0300 >+++ ffmpeg-10924-alt1.xvmc/libavcodec/xvmc_render.h 2007-11-09 22:07:08 +0300 >@@ -28,6 +28,9 @@ > #include <X11/extensions/Xvlib.h> > #include <X11/extensions/XvMClib.h> > >+#ifdef HAVE_XVMC_VLD >+#include <X11/extensions/vldXvMC.h> >+#endif > > //the surface should be shown, video driver manipulates this > #define MP_XVMC_STATE_DISPLAY_PENDING 1 >@@ -50,6 +53,15 @@ > int idct;//Do we use IDCT acceleration? > int chroma_format;//420,422,444 > int unsigned_intra;//+-128 for intra pictures after clip >+#ifdef HAVE_XVMC_VLD >+ // 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; >+#endif > XvMCSurface* p_surface;//pointer to rendered surface, never changed > > //these are changed by decoder >diff -Naur ffmpeg-10924-alt1.rvrt/libavcodec/xvmcvideo.c ffmpeg-10924-alt1.xvmc/libavcodec/xvmcvideo.c >--- ffmpeg-10924-alt1.rvrt/libavcodec/xvmcvideo.c 2007-11-06 23:23:52 +0300 >+++ ffmpeg-10924-alt1.xvmc/libavcodec/xvmcvideo.c 2007-11-09 22:07:08 +0300 >@@ -68,11 +68,68 @@ > } > } > >+#ifdef HAVE_XVMC_VLD >+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 (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(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 (B_TYPE==next->pict_type) >+ av_log(s->avctx,AV_LOG_DEBUG, "Next frame is a B frame in findFutureSurface, thisis bad.\n"); >+ //assert(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; >+} >+#endif //HAVE_XVMC_VLD >+ > //these functions should be called on every new field or/and frame > //They should be safe if they are called few times for same field! > int XVMC_field_start(MpegEncContext*s, AVCodecContext *avctx){ > xvmc_render_state_t * render,* last, * next; > >+#ifdef HAVE_XVMC_VLD >+ XvMCMpegControl binfo; >+ XvMCQMatrix qmatrix; >+ int i; >+ Status status; >+ >+ memset(&binfo, 0, sizeof(binfo)); >+ memset(&qmatrix, 0, sizeof(qmatrix)); >+#endif >+ > assert(avctx != NULL); > > render = (xvmc_render_state_t*)s->current_picture.data[2]; >@@ -83,12 +140,53 @@ > render->picture_structure = s->picture_structure; > render->flags = (s->first_field)? 0: XVMC_SECOND_FIELD; > >+#ifdef HAVE_XVMC_VLD >+ 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 >+#endif >+ { > //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 >+ >+#ifdef HAVE_XVMC_VLD >+ if (s->avctx->xvmc_acceleration == 4) >+{ >+ switch(s->pict_type){ >+ case I_TYPE: >+ break; >+ case 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 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 >+#endif >+{ > switch(s->pict_type){ > case I_TYPE: > return 0;// no prediction from other frames >@@ -109,6 +207,94 @@ > render->p_past_surface = last->p_surface; > return 0; > } >+} >+ >+#ifdef HAVE_XVMC_VLD >+ 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 I_TYPE: binfo.picture_coding_type = XVMC_I_PICTURE; break; >+ case P_TYPE: binfo.picture_coding_type = XVMC_P_PICTURE; break; >+ case 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; >+ } >+#endif > > return -1; > } >@@ -118,11 +304,23 @@ > render = (xvmc_render_state_t*)s->current_picture.data[2]; > assert(render != NULL); > >+#ifdef HAVE_XVMC_VLD >+ if (s->avctx->xvmc_acceleration == 4) >+ { >+ XvMCFlushSurface(render->disp, render->p_surface); >+ XvMCSyncSurface(render->disp, render->p_surface); >+ >+ s->error_count = 0; >+ } >+ else >+#endif >+ { > 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){ > XvMCMacroBlock * mv_block; >@@ -311,4 +509,50 @@ > > } > >+#ifdef HAVE_XVMC_VLD >+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); >+} >+#endif >+ > #endif >+ >diff -Naur ffmpeg-10924-alt1.rvrt/libavutil/avutil.h ffmpeg-10924-alt1.xvmc/libavutil/avutil.h >--- ffmpeg-10924-alt1.rvrt/libavutil/avutil.h 2007-11-09 22:00:11 +0300 >+++ ffmpeg-10924-alt1.xvmc/libavutil/avutil.h 2007-11-09 22:07:08 +0300 >@@ -88,6 +88,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
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 13452
:
2275
|
2276
|
2277
| 2278 |
2279
|
2335
|
2338