ALT Linux Bugzilla
– Attachment 2275 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]
"mplayer" part of openchrome XvMC VLD patch
mplayer-svn-25029-my_xvmc-vld.patch (text/plain), 18.12 KB, created by
Andrey Liakhovets
on 2007-11-16 15:11:11 MSK
(
hide
)
Description:
"mplayer" part of openchrome XvMC VLD patch
Filename:
MIME Type:
Creator:
Andrey Liakhovets
Created:
2007-11-16 15:11:11 MSK
Size:
18.12 KB
patch
obsolete
>Index: codec-cfg.c >=================================================================== >--- codec-cfg.c (revision 24967) >+++ codec-cfg.c (working copy) >@@ -179,6 +179,7 @@ > {"ZRMJPEGIT", IMGFMT_ZRMJPEGIT}, > {"ZRMJPEGIB", IMGFMT_ZRMJPEGIB}, > >+ {"VLD_MPEG2",IMGFMT_XVMC_VLD_MPEG2}, > {"IDCT_MPEG2",IMGFMT_XVMC_IDCT_MPEG2}, > {"MOCO_MPEG2",IMGFMT_XVMC_MOCO_MPEG2}, > >Index: configure >=================================================================== >--- configure (revision 24967) >+++ configure (working copy) >@@ -527,6 +527,7 @@ > _dga2=auto > _xv=auto > _xvmc=no #auto when complete >+_xvmc_vld=auto > _sdl=auto > _directx=auto > _win32waveout=auto >@@ -3901,7 +3902,7 @@ > _novomodules="x11 $_novomodules" > _res_comment="check if the dev(el) packages are installed" > # disable stuff that depends on X >- _xv=no ; _xvmc=no ; _xinerama=no ; _vm=no ; _xf86keysym=no >+ _xv=no ; _xvmc=no ; _xvmc_vld=no ; _xinerama=no ; _vm=no ; _xf86keysym=no > fi > echores "$_x11" > >@@ -4001,6 +4002,31 @@ > echores "$_xvmc" > > >+echocheck "XvMC VLD" >+if test "$_xvmc" = yes ; then >+ _xvmc_vld=no >+ cat > $TMPC <<EOF >+#include <X11/Xlib.h> >+#include <X11/extensions/Xvlib.h> >+#include <X11/extensions/XvMClib.h> >+#include <X11/extensions/vldXvMC.h> >+int main(void) { >+ (void) XvMCQueryExtension(0,0,0); >+ (void) XvMCCreateContext(0,0,0,0,0,0,0); >+ return 0; } >+EOF >+ cc_check -lXvMC -l$_xvmclib && _xvmc_vld=yes >+ if test "$_xvmc_vld" = yes ; then >+ _def_xvmc_vld='#define HAVE_XVMC_VLD 1' >+ _libs_mencoder="$_libs_mencoder -l$_xvmclib" >+ else >+ _def_xvmc_vld='#undef HAVE_XVMC_VLD' >+ _libavdecoders=`echo $_libavdecoders | sed -e s/MPEG_XVMC_VLD_DECODER// ` >+ fi >+fi >+echores "$_xvmc_vld" >+ >+ > echocheck "Xinerama" > if test "$_xinerama" = auto ; then > cat > $TMPC <<EOF >@@ -8455,6 +8481,7 @@ > $_def_x11 > $_def_xv > $_def_xvmc >+$_def_xvmc_vld > $_def_vm > $_def_xf86keysym > $_def_xinerama >Index: etc/codecs.conf >=================================================================== >--- etc/codecs.conf (revision 24967) >+++ etc/codecs.conf (working copy) >@@ -128,6 +128,7 @@ > fourcc MMES,mmes ; matrox mpeg2 in avi > driver ffmpeg > dll "mpegvideo_xvmc" >+ out VLD_MPEG2 > out IDCT_MPEG2 > out MOCO_MPEG2 > >Index: help/help_mp-en.h >=================================================================== >--- help/help_mp-en.h (revision 24967) >+++ help/help_mp-en.h (working copy) >@@ -1645,6 +1645,7 @@ > #define MSGTR_MPCODECS_DRIFailure "[VD_FFMPEG] DRI failure.\n" > #define MSGTR_MPCODECS_CouldntAllocateImageForCodec "[VD_FFMPEG] Couldn't allocate image for codec.\n" > #define MSGTR_MPCODECS_XVMCAcceleratedMPEG2 "[VD_FFMPEG] XVMC-accelerated MPEG-2.\n" >+#define MSGTR_MPCODECS_XVMCVLDAcceleratedMPEG2 "[VD_FFMPEG] XVMC-VLD-accelerated MPEG-2.\n" > #define MSGTR_MPCODECS_TryingPixfmt "[VD_FFMPEG] Trying pixfmt=%d.\n" > #define MSGTR_MPCODECS_McGetBufferShouldWorkOnlyWithXVMC "[VD_FFMPEG] The mc_get_buffer should work only with XVMC acceleration!!" > #define MSGTR_MPCODECS_UnexpectedInitVoError "[VD_FFMPEG] Unexpected init_vo error.\n" >Index: libmpcodecs/vd_ffmpeg.c >=================================================================== >--- libmpcodecs/vd_ffmpeg.c (revision 24967) >+++ libmpcodecs/vd_ffmpeg.c (working copy) >@@ -12,6 +12,7 @@ > #include "mpbswap.h" > > #include "vd_internal.h" >+#include "libvo/video_out.h" > > static vd_info_t info = { > "FFmpeg's libavcodec codec family", >@@ -155,6 +156,8 @@ > case IMGFMT_XVMC_IDCT_MPEG2: > case IMGFMT_XVMC_MOCO_MPEG2: > if(avctx->pix_fmt==PIX_FMT_XVMC_MPEG2_IDCT) return CONTROL_TRUE; >+ case IMGFMT_XVMC_VLD_MPEG2: >+ if(avctx->pix_fmt==PIX_FMT_XVMC_MPEG2_VLD) return CONTROL_TRUE; > #endif > } > return CONTROL_FALSE; >@@ -225,6 +228,9 @@ > vd_ffmpeg_ctx *ctx; > AVCodec *lavc_codec; > int lowres_w=0; >+#ifdef HAVE_XVMC >+ char *voname = 0; >+#endif > int do_vis_debug= lavc_param_vismv || (lavc_param_debug&(FF_DEBUG_VIS_MB_TYPE|FF_DEBUG_VIS_QP)); > > if(!avcodec_inited){ >@@ -260,11 +266,23 @@ > > #ifdef HAVE_XVMC > >+ // Try and get the name of the selected vo system >+ // so that if its _not_ xvmc we can fail gracefully >+ // and mplayer can fall back to a sw decoder >+ if (sh->video_out) { >+ vo_info_t *voinfo; >+ vo_functions_t * shvoc=sh->video_out; >+ if (shvoc) { >+ voinfo = shvoc->info; >+ if (voinfo) voname=voinfo->short_name; >+ } >+ } > #ifdef CODEC_CAP_HWACCEL >- if(lavc_codec->capabilities & CODEC_CAP_HWACCEL){ >+ if((lavc_codec->capabilities & CODEC_CAP_HWACCEL) && > #else >- if(lavc_codec->id == CODEC_ID_MPEG2VIDEO_XVMC){ >+ if((lavc_codec->id == CODEC_ID_MPEG2VIDEO_XVMC) && > #endif /* CODEC_CAP_HWACCEL */ >+ voname && !strcmp(voname,"xvmc") ) { > mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_MPCODECS_XVMCAcceleratedCodec); > assert(ctx->do_dr1);//these are must to! > assert(ctx->do_slices); //it is (vo_)ffmpeg bug if this fails >@@ -535,6 +553,7 @@ > #ifdef HAVE_XVMC > case PIX_FMT_XVMC_MPEG2_MC:ctx->best_csp=IMGFMT_XVMC_MOCO_MPEG2;break; > case PIX_FMT_XVMC_MPEG2_IDCT:ctx->best_csp=IMGFMT_XVMC_IDCT_MPEG2;break; >+ case PIX_FMT_XVMC_MPEG2_VLD:ctx->best_csp=IMGFMT_XVMC_VLD_MPEG2;break; > #endif > default: > ctx->best_csp=0; >@@ -919,7 +938,11 @@ > avctx->get_buffer= mc_get_buffer; > avctx->release_buffer= mc_release_buffer; > avctx->draw_horiz_band = mc_render_slice; >+ if (avctx->xvmc_acceleration != 4) > mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_MPCODECS_XVMCAcceleratedMPEG2); >+ else >+ mp_msg(MSGT_DECVIDEO, MSGL_INFO, MSGTR_MPCODECS_XVMCVLDAcceleratedMPEG2); >+ > assert(ctx->do_dr1);//these are must to! > assert(ctx->do_slices); //it is (vo_)ffmpeg bug if this fails > avctx->flags|= CODEC_FLAG_EMU_EDGE;//do i need that??!! >Index: libmpcodecs/img_format.c >=================================================================== >--- libmpcodecs/img_format.c (revision 24967) >+++ libmpcodecs/img_format.c (working copy) >@@ -67,6 +67,7 @@ > case IMGFMT_ZRMJPEGIB: return("Zoran MJPEG bottom field first"); > case IMGFMT_XVMC_MOCO_MPEG2: return("MPEG1/2 Motion Compensation"); > case IMGFMT_XVMC_IDCT_MPEG2: return("MPEG1/2 Motion Compensation and IDCT"); >+ case IMGFMT_XVMC_VLD_MPEG2: return("MPEG1/2 Motion Compensation and VLD"); > } > snprintf(unknow_format,20,"Unknown 0x%04x",format); > return unknow_format; >Index: libmpcodecs/img_format.h >=================================================================== >--- libmpcodecs/img_format.h (revision 24967) >+++ libmpcodecs/img_format.h (working copy) >@@ -107,6 +107,7 @@ > //these are chroma420 > #define IMGFMT_XVMC_MOCO_MPEG2 (IMGFMT_XVMC|0x02) > #define IMGFMT_XVMC_IDCT_MPEG2 (IMGFMT_XVMC|0x82) >+#define IMGFMT_XVMC_VLD_MPEG2 (IMGFMT_XVMC|0x42) > > typedef struct { > void* data; >Index: libmpdemux/stheader.h >=================================================================== >--- libmpdemux/stheader.h (revision 24967) >+++ libmpdemux/stheader.h (working copy) >@@ -78,6 +78,7 @@ > int disp_w,disp_h; // display size (filled by fileformat parser) > // output driver/filters: (set by libmpcodecs core) > unsigned int outfmtidx; >+ void* video_out; // the video_out handle, used for this video stream > struct vf_instance_s *vfilter; // the video filter chain, used for this video stream > int vf_inited; > #ifdef DYNAMIC_PLUGINS >Index: libvo/vo_xvmc.c >=================================================================== >--- libvo/vo_xvmc.c (revision 24967) >+++ libvo/vo_xvmc.c (working copy) >@@ -23,6 +23,11 @@ > #include <X11/extensions/Xvlib.h> > #include <X11/extensions/XvMClib.h> > >+#ifdef HAVE_XVMC_VLD >+#include <X11/extensions/vldXvMC.h> >+extern int has_xvmc_vld; >+#endif >+ > #include "x11_common.h" > #include "xvmc_render.h" > >@@ -45,6 +50,7 @@ > > > #define UNUSED(x) ((void)(x)) >+extern unsigned int video_format; > > #include "libavcodec/avcodec.h" > #if LIBAVCODEC_BUILD < ((51<<16)+(40<<8)+2) >@@ -59,6 +65,8 @@ > static int xv_port_request = 0; > static int bob_deinterlace; > static int top_field_first; >+static int use_deint_one; >+static int use_tv_clip; > > static int image_width,image_height; > static int image_format; >@@ -123,7 +131,7 @@ > "XVideo Motion Compensation", > "xvmc", > "Ivan Kalvachev <iive@users.sf.net>", >- "" >+ "Ivor Hewitt <ivor@ivor.org> - VIA VLD support" > }; > > LIBVO_EXTERN(xvmc); >@@ -196,7 +204,23 @@ > } > //end of vo_xv shm/xvimage code > >+int hasVLDAcceleration() >+{ >+#ifdef HAVE_XVMC_VLD >+ return XVMC_VLD == (surface_info.mc_type & XVMC_VLD); >+#else >+ return 0; >+#endif >+} >+ > static int xvmc_check_surface_format(uint32_t format, XvMCSurfaceInfo * surf_info){ >+#ifdef HAVE_XVMC_VLD >+ if (format == IMGFMT_XVMC_VLD_MPEG2 ){ >+ if( surf_info->mc_type != (XVMC_VLD|XVMC_MPEG_2) ) return -1; >+ if( surf_info->chroma_format != XVMC_CHROMA_FORMAT_420 ) return -1; >+ return 0; >+ } >+#endif > if ( format == IMGFMT_XVMC_IDCT_MPEG2 ){ > if( surf_info->mc_type != (XVMC_IDCT|XVMC_MPEG_2) ) return -1; > if( surf_info->chroma_format != XVMC_CHROMA_FORMAT_420 ) return -1; >@@ -361,6 +385,59 @@ > return VO_TRUE; > } > >+ >+static int >+check_xvmc_vld() >+{ >+ int rez; >+ XvAdaptorInfo* ai; >+ XvMCSurfaceInfo* surf_info; >+ int max_adaptor; >+ int max_surf; >+ int i; >+ unsigned long p; >+ int s; >+ >+ rez = XvQueryAdaptors(mDisplay, DefaultRootWindow(mDisplay), >+ &max_adaptor,&ai); >+ if (rez != Success) return; >+ >+ if (mp_msg_test(MSGT_VO, MSGL_DBG3)) >+ printf("vo_xvmc: Querying %d adaptors for VLD\n", max_adaptor); >+ >+ for (i = 0; i < max_adaptor; i++) >+ { >+ if (mp_msg_test(MSGT_VO,MSGL_DBG3)) >+ printf("vo_xvmc: Quering adaptor #%d for VLD\n", i); >+ if (ai[i].type == 0) continue; >+ >+ // Probing every XV port >+ for (p = ai[i].base_id; p < ai[i].base_id + ai[i].num_ports; p++) >+ { >+ // Respect the users wish >+ if ((xv_port_request != 0) && (xv_port_request != p)) continue; >+ if (mp_msg_test(MSGT_VO,MSGL_DBG3)) >+ printf("vo_xvmc: Probing port #%ld for VLD\n", p); >+ surf_info = XvMCListSurfaceTypes(mDisplay, p, &max_surf); >+ if (surf_info == NULL || max_surf == 0) continue; >+ >+ // We have XvMC list! >+ for(s = 0; s < max_surf; s++) >+ { >+ // We have match! >+ if (XVMC_VLD == (surf_info[s].mc_type & XVMC_VLD)) >+ has_xvmc_vld = 1; >+ } >+ XFree(surf_info); >+ } >+ } >+ XvFreeAdaptorInfo(ai); >+ >+ if (mp_msg_test(MSGT_VO,MSGL_DBG3) && has_xvmc_vld) >+ printf("vo_xvmc: Found VLD support in XvMC\n"); >+} >+ >+ > static int preinit(const char *arg){ > int xv_version,xv_release,xv_request_base,xv_event_base,xv_error_base; > int mc_eventBase,mc_errorBase; >@@ -377,9 +454,16 @@ > { "sleep", OPT_ARG_BOOL, &use_sleep, NULL }, > { "queue", OPT_ARG_BOOL, &use_queue, NULL }, > { "bobdeint", OPT_ARG_BOOL, &bob_deinterlace, NULL }, >+ { "onedeint", OPT_ARG_BOOL, &use_deint_one, NULL }, >+ { "tv-clip", OPT_ARG_BOOL, &use_tv_clip, NULL }, > { NULL } > }; > >+ // If the video is not MPEG1 or MPEG2, we can't decode it, so >+ // fail cleanly to allow mplayer to fallback to another vo system >+ if (video_format != 0x10000001 && video_format != 0x10000002) return -1; >+ >+ > //Obtain display handler > if (!vo_init()) return -1;//vo_xv > >@@ -415,6 +499,8 @@ > use_sleep = 0; > use_queue = 0; > bob_deinterlace = 0; >+ use_deint_one = 0; >+ use_tv_clip = 0; > > /* parse suboptions */ > if ( subopt_parse( arg, subopts ) != 0 ) >@@ -424,6 +510,9 @@ > > xv_setup_colorkeyhandling( ck_method_arg.str, ck_src_arg.str ); > >+ // Check whether XvMC supports VLD >+ check_xvmc_vld(); >+ > return 0; > } > >@@ -505,6 +594,8 @@ > if(surface_info.chroma_format == XVMC_CHROMA_FORMAT_444) > blocks_per_macroblock = 12; > >+if (!hasVLDAcceleration()) >+{ > rez = XvMCCreateBlocks(mDisplay,&ctx,numblocks*blocks_per_macroblock,&data_blocks); > if( rez != Success ){ > XvMCDestroyContext(mDisplay,&ctx); >@@ -520,6 +611,8 @@ > } > printf("vo_xvmc: mv_blocks allocated\n"); > >+} >+ > if(surface_render==NULL) > surface_render=malloc(MAX_SURFACES*sizeof(xvmc_render_state_t));//easy mem debug > memset(surface_render,0,MAX_SURFACES*sizeof(xvmc_render_state_t)); >@@ -538,6 +631,11 @@ > surface_render[i].chroma_format = surface_info.chroma_format; > surface_render[i].unsigned_intra = (surface_info.flags & XVMC_INTRA_UNSIGNED) == XVMC_INTRA_UNSIGNED; > surface_render[i].p_surface = &surface_array[i]; >+ >+ surface_render[i].state = 0; >+ surface_render[i].disp = mDisplay; >+ surface_render[i].ctx = &ctx; >+ > if( mp_msg_test(MSGT_VO,MSGL_DBG4) ) > printf("vo_xvmc: surface[%d] = %p .rndr=%p\n",i,&surface_array[i], &surface_render[i]); > } >@@ -993,6 +1091,8 @@ > int rez; > int clipX,clipY,clipW,clipH; > int i; >+ int srcY=0, srcH=image_height; >+ int fieldnobob; > > if(p_render_surface == NULL) > return; >@@ -1002,22 +1102,38 @@ > clipW = vo_dwidth+vo_panscan_x; > clipH = vo_dheight+vo_panscan_y; > >+ if (use_tv_clip) { >+ /* >+ * Clip top few lines off to get rid of annoying flicker >+ * when using bob de-interlacing on TV sourced video. >+ */ >+ srcY+=4; >+ srcH-=4; >+ } >+ > if(draw_ck) > vo_xv_draw_colorkey(clipX,clipY,clipW,clipH); > > if(benchmark) > return; > >+ fieldnobob = XVMC_FRAME_PICTURE; >+ >+ if (use_deint_one) >+ fieldnobob = (top_field_first) ? XVMC_TOP_FIELD : XVMC_BOTTOM_FIELD; >+ > for (i = 1; i <= bob_deinterlace + 1; i++) { >- int field = top_field_first ? i : i ^ 3; >+ int field = top_field_first ? i : i ^ XVMC_FRAME_PICTURE; > rez = XvMCPutSurface(mDisplay, p_render_surface->p_surface, > vo_window, >- 0, 0, image_width, image_height, >+ 0, srcY, image_width, srcH, > clipX, clipY, clipW, clipH, >- bob_deinterlace ? field : 3); >- //p_render_surface_to_show->display_flags); >+ bob_deinterlace ? field : fieldnobob); >+ if (i == 1 && bob_deinterlace) { >+ usleep(10*1000); >+ } > if(rez != Success){ >- printf("vo_xvmc: PutSurface failer, critical error %d!\n",rez); >+ printf("vo_xvmc: PutSurface failure, critical error %d!\n",rez); > assert(0); > } > } >@@ -1109,9 +1225,11 @@ > > if( number_of_surfaces ){ > >+ if (!hasVLDAcceleration()) >+ { > XvMCDestroyMacroBlocks(mDisplay,&mv_blocks); > XvMCDestroyBlocks(mDisplay,&data_blocks); >- >+ } > for(i=0; i<number_of_surfaces; i++) > { > XvMCHideSurface(mDisplay,&surface_array[i]);//it doesn't hurt, I hope >@@ -1189,6 +1307,17 @@ > assert( rndr != NULL ); > assert( rndr->magic == MP_XVMC_RENDER_MAGIC ); > >+ if (hasVLDAcceleration()) >+ { >+ rez = XvMCPutSlice2(mDisplay,&ctx,(char*)rndr->slice_data, >+ rndr->slice_datalen, >+ rndr->slice_code); >+ if (rez) >+ printf("vo_xxmc::slice Error %d\n",rez); >+ >+ } >+ else >+ { > rez = XvMCRenderSurface(mDisplay,&ctx,rndr->picture_structure, > rndr->p_surface, > rndr->p_past_surface, >@@ -1200,7 +1329,7 @@ > if(rez != Success) > { > int i; >- printf("vo_xvmc::slice: RenderSirface returned %d\n",rez); >+ printf("vo_xvmc::slice: RenderSurface returned %d\n",rez); > > printf("vo_xvmc::slice: pict=%d,flags=%x,start_blocks=%d,num_blocks=%d\n", > rndr->picture_structure,rndr->flags,rndr->start_mv_blocks_num, >@@ -1228,6 +1357,7 @@ > rez = XvMCFlushSurface(mDisplay, rndr->p_surface); > assert(rez==Success); > >+} > // rndr->start_mv_blocks_num += rndr->filled_mv_blocks_num; > rndr->start_mv_blocks_num = 0; > rndr->filled_mv_blocks_num = 0; >@@ -1337,8 +1467,16 @@ > > // these are shared!! so watch out > // do call RenderSurface before overwriting >+if (!hasVLDAcceleration()) >+{ > mpi->planes[0] = (char*)data_blocks.blocks; > mpi->planes[1] = (char*)mv_blocks.macro_blocks; >+} >+else >+{ >+ mpi->planes[0] = 1; >+ mpi->planes[1] = 0; >+} > mpi->priv = > mpi->planes[2] = (char*)rndr; > >Index: mencoder.c >=================================================================== >--- mencoder.c (revision 24967) >+++ mencoder.c (working copy) >@@ -771,6 +771,7 @@ > mux_v->bih=NULL; > } > sh_video->codec=NULL; >+sh_video->video_out=NULL; > sh_video->vfilter=NULL; // fixme! > > switch(mux_v->codec){ >Index: mplayer.c >=================================================================== >--- mplayer.c (revision 24967) >+++ mplayer.c (working copy) >@@ -85,6 +85,8 @@ > int quiet=0; > int enable_mouse_movements=0; > >+unsigned int video_format=0; >+ > #ifdef WIN32 > char * proc_priority=NULL; > #endif >@@ -1897,10 +1899,16 @@ > //shouldn't we set dvideo->id=-2 when we fail? > vo_config_count=0; > //if((mpctx->video_out->preinit(vo_subdevice))!=0){ >+ >+ // let the video driver know what format the video is in so it can >+ // reject it if it wants - lets vo_xvmc fail if ffmpeg12mc codec not used >+ video_format=sh_video->format; >+ > if(!(mpctx->video_out=init_best_video_out(video_driver_list))){ > mp_msg(MSGT_CPLAYER,MSGL_FATAL,MSGTR_ErrorInitializingVODevice); > goto err_out; > } >+ sh_video->video_out=mpctx->video_out; > inited_flags|=INITED_VO; > } > >Index: xvmc_render.h >=================================================================== >--- xvmc_render.h (revision 24967) >+++ xvmc_render.h (working copy) >@@ -5,6 +5,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 manipulate this > #define MP_XVMC_STATE_DISPLAY_PENDING 1 >@@ -27,6 +30,15 @@ > int idct;//does 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
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