Ticket #4948: use_swscale_patch.diff

File use_swscale_patch.diff, 9.0 KB (added by stippi, 14 years ago)

Patch which fixes the problem by re-using libswscale as the Encoder already does.

  • AVCodecDecoder.h

     
    1414
    1515#include <MediaFormats.h>
    1616
     17extern "C" {
     18    #include "swscale.h"
     19}
     20
    1721#include "DecoderPlugin.h"
    1822#include "ReaderPlugin.h"
    1923
     
    8084            bool                fCodecInitDone;
    8185
    8286            gfx_convert_func    fFormatConversionFunc;
     87            SwsContext*         fSwsContext;
    8388
    8489            char*               fExtraData;
    8590            int                 fExtraDataSize;
  • gfx_util.h

     
    3030// will become:
    3131typedef void (*gfx_convert_func) (AVFrame *in, AVFrame *out, int width, int height);
    3232
    33 // this function will try to find the best colorspaces for both the ff-codec and
     33// this function will try to find the best colorspaces for both the ff-codec and
    3434// the Media Kit sides.
    3535gfx_convert_func resolve_colorspace(color_space cs, PixelFormat pixelFormat);
    3636
    37 const char *pixfmt_to_string(int p);
     37const char *pixfmt_to_string(int format);
    3838
    39 color_space pixfmt_to_colorspace(int p);
     39color_space pixfmt_to_colorspace(int format);
     40PixelFormat colorspace_to_pixfmt(color_space format);
    4041
    4142void dump_ffframe(AVFrame *frame, const char *name);
    4243
  • AVCodecDecoder.cpp

     
    7373    fCodecInitDone(false),
    7474
    7575    fFormatConversionFunc(NULL),
     76    fSwsContext(NULL),
    7677
    7778    fExtraData(NULL),
    7879    fExtraDataSize(0),
     
    115116    free(fInputPicture);
    116117    free(fContext);
    117118
     119    if (fSwsContext != NULL)
     120        sws_freeContext(fSwsContext);
     121
    118122    delete[] fExtraData;
    119123    delete[] fOutputBuffer;
    120124}
     
    453457    // time using another pixel-format that is supported by the decoder.
    454458    // But libavcodec doesn't seem to offer any way to tell the decoder
    455459    // which format it should use.
    456     fFormatConversionFunc = 0;
     460//  fFormatConversionFunc = 0;
     461    fSwsContext = NULL;
    457462    // Iterate over supported codec formats
    458463    for (int i = 0; i < 1; i++) {
    459464        // close any previous instance
     
    465470        if (avcodec_open(fContext, fCodec) >= 0) {
    466471            fCodecInitDone = true;
    467472
    468             fFormatConversionFunc = resolve_colorspace(
    469                 fOutputVideoFormat.display.format, fContext->pix_fmt);
     473//          fFormatConversionFunc = resolve_colorspace(
     474//              fOutputVideoFormat.display.format, fContext->pix_fmt);
     475            fSwsContext = sws_getContext(fContext->width, fContext->height,
     476                fContext->pix_fmt, fContext->width, fContext->height,
     477                colorspace_to_pixfmt(fOutputVideoFormat.display.format),
     478                SWS_FAST_BILINEAR, NULL, NULL, NULL);
    470479        }
    471         if (fFormatConversionFunc != NULL)
    472             break;
     480//      if (fFormatConversionFunc != NULL)
     481//          break;
    473482    }
    474483
    475484    if (!fCodecInitDone) {
     
    477486        return B_ERROR;
    478487    }
    479488
    480     if (fFormatConversionFunc == NULL) {
    481         TRACE("no pixel format conversion function found or decoder has "
    482             "not set the pixel format yet!\n");
     489//  if (fFormatConversionFunc == NULL) {
     490//      TRACE("no pixel format conversion function found or decoder has "
     491//          "not set the pixel format yet!\n");
     492//  }
     493    if (fSwsContext == NULL) {
     494        TRACE("No SWS Scale context or decoder has not set the pixel format "
     495            "yet!\n");
    483496    }
    484497
    485498    if (fOutputVideoFormat.display.format == B_YCbCr422) {
     
    707720//              pixfmt_to_string(fContext->pix_fmt));
    708721
    709722            // Some decoders do not set pix_fmt until they have decoded 1 frame
    710             if (fFormatConversionFunc == NULL) {
    711                 fFormatConversionFunc = resolve_colorspace(
    712                     fOutputVideoFormat.display.format, fContext->pix_fmt);
     723//          if (fFormatConversionFunc == NULL) {
     724//              fFormatConversionFunc = resolve_colorspace(
     725//                  fOutputVideoFormat.display.format, fContext->pix_fmt);
     726//          }
     727            if (fSwsContext == NULL) {
     728                fSwsContext = sws_getContext(fContext->width, fContext->height,
     729                    fContext->pix_fmt, fContext->width, fContext->height,
     730                    colorspace_to_pixfmt(fOutputVideoFormat.display.format),
     731                    SWS_FAST_BILINEAR, NULL, NULL, NULL);
    713732            }
     733
    714734            fOutputPicture->data[0] = (uint8_t*)outBuffer;
    715735            fOutputPicture->linesize[0]
    716736                = fOutputVideoFormat.display.bytes_per_row;
    717737
    718             if (fFormatConversionFunc != NULL) {
     738//          if (fFormatConversionFunc != NULL) {
     739            if (fSwsContext != NULL) {
    719740                if (useDeinterlacedPicture) {
    720741                    AVFrame inputFrame;
    721742                    inputFrame.data[0] = deinterlacedPicture.data[0];
     
    727748                    inputFrame.linesize[2] = deinterlacedPicture.linesize[2];
    728749                    inputFrame.linesize[3] = deinterlacedPicture.linesize[3];
    729750
    730                     (*fFormatConversionFunc)(&inputFrame,
    731                         fOutputPicture, width, height);
     751//                  (*fFormatConversionFunc)(&inputFrame,
     752//                      fOutputPicture, width, height);
     753                    sws_scale(fSwsContext, inputFrame.data,
     754                        inputFrame.linesize, 0, fContext->height,
     755                        fOutputPicture->data, fOutputPicture->linesize);
    732756                } else {
    733                     (*fFormatConversionFunc)(fInputPicture, fOutputPicture,
    734                         width, height);
     757//                  (*fFormatConversionFunc)(fInputPicture, fOutputPicture,
     758//                      width, height);
     759                    // Run the pixel format conversion
     760                    sws_scale(fSwsContext, fInputPicture->data,
     761                        fInputPicture->linesize, 0, fContext->height,
     762                        fOutputPicture->data, fOutputPicture->linesize);
    735763                }
    736764            }
    737765            if (fInputPicture->interlaced_frame)
  • gfx_util.cpp

     
    1616  #define TRACE(a...)
    1717#endif
    1818
    19 // this function will try to find the best colorspaces for both the ff-codec and
     19// this function will try to find the best colorspaces for both the ff-codec and
    2020// the Media Kit sides.
    2121gfx_convert_func resolve_colorspace(color_space colorSpace, PixelFormat pixelFormat)
    2222{
     
    3434                    return gfx_conv_yuv410p_rgb32_c;
    3535//              }
    3636            }
    37 
     37
    3838            if (pixelFormat == PIX_FMT_YUV411P) {
    3939//              if (cpu.HasMMX()) {
    4040//                  TRACE("resolve_colorspace: gfx_conv_yuv411p_rgb32_mmx\n");
     
    4444                    return gfx_conv_yuv411p_rgb32_c;
    4545//              }
    4646            }
    47 
     47
    4848            if (pixelFormat == PIX_FMT_YUV420P || pixelFormat == PIX_FMT_YUVJ420P) {
    4949                if (cpu.HasSSE2()) {
    5050                    TRACE("resolve_colorspace: gfx_conv_yuv420p_rgba32_sse2\n");
     
    5454                    return gfx_conv_YCbCr420p_RGB32_c;
    5555                }
    5656            }
    57 
     57
    5858            if (pixelFormat == PIX_FMT_YUV422P || pixelFormat == PIX_FMT_YUVJ422P) {
    5959                if (cpu.HasSSE2()) {
    6060                    return gfx_conv_yuv422p_rgba32_sse2;
     
    9595                    return gfx_conv_yuv411p_ycbcr422_c;
    9696//              }
    9797            }
    98 
     98
    9999            if (pixelFormat == PIX_FMT_YUV420P || pixelFormat == PIX_FMT_YUVJ420P) {
    100100//              if (cpu.HasMMX()) {
    101101//                  TRACE("resolve_colorspace: gfx_conv_yuv420p_ycbcr422_mmx\n");
     
    105105                    return gfx_conv_yuv420p_ycbcr422_c;
    106106//              }
    107107            }
    108 
     108
    109109            if (pixelFormat == PIX_FMT_YUYV422) {
    110110//              if (cpu.HasMMX()) {
    111111//                  TRACE("resolve_colorspace: PIX_FMT_YUV422 => B_YCbCr422: gfx_conv_null_mmx\n");
     
    115115                    return gfx_conv_null_c;
    116116//              }
    117117            }
    118 
     118
    119119            TRACE("resolve_colorspace: %s => B_YCbCr422: NULL\n", pixfmt_to_string(pixelFormat));
    120120            return gfx_conv_null_c;
    121 
     121
    122122        default:
    123123            TRACE("resolve_colorspace: default: NULL !!!\n");
    124124            return NULL;
     
    248248}
    249249
    250250
     251PixelFormat
     252colorspace_to_pixfmt(color_space format)
     253{
     254    switch(format) {
     255        default:
     256        case B_NO_COLOR_SPACE:
     257            return PIX_FMT_NONE;
     258
     259        // NOTE: See pixfmt_to_colorspace() for what these are.
     260        case B_YUV420:
     261            return PIX_FMT_YUV420P;
     262        case B_YUV422:
     263            return PIX_FMT_YUV422P;
     264        case B_RGB24_BIG:
     265            return PIX_FMT_RGB24;
     266        case B_RGB24:
     267            return PIX_FMT_BGR24;
     268        case B_YUV444:
     269            return PIX_FMT_YUV444P;
     270        case B_RGBA32_BIG:
     271        case B_RGB32_BIG:
     272            return PIX_FMT_BGR32;
     273        case B_YUV9:
     274            return PIX_FMT_YUV410P;
     275        case B_YUV12:
     276            return PIX_FMT_YUV411P;
     277        // TODO: YCbCr color spaces! These are not the same as YUV!
     278        case B_RGB16_BIG:
     279            return PIX_FMT_RGB565;
     280        case B_RGB15_BIG:
     281            return PIX_FMT_RGB555;
     282        case B_GRAY8:
     283            return PIX_FMT_GRAY8;
     284        case B_GRAY1:
     285            return PIX_FMT_MONOBLACK;
     286        case B_CMAP8:
     287            return PIX_FMT_PAL8;
     288        case B_RGBA32:
     289        case B_RGB32:
     290            return PIX_FMT_RGB32;
     291        case B_RGB16:
     292            return PIX_FMT_BGR565;
     293        case B_RGB15:
     294            return PIX_FMT_BGR555;
     295    }
     296}
     297
     298
    251299#define BEGIN_TAG "\033[31m"
    252300#define END_TAG "\033[0m"
    253301
    254302void dump_ffframe(AVFrame *frame, const char *name)
    255303{
    256304    const char *picttypes[] = {"no pict type", "intra", "predicted", "bidir pre", "s(gmc)-vop"};
    257     printf(BEGIN_TAG"AVFrame(%s) pts:%-10lld cnum:%-5d dnum:%-5d %s%s, ]\n"END_TAG,
    258         name,
    259         frame->pts,
    260         frame->coded_picture_number,
    261         frame->display_picture_number,
    262 //      frame->quality,
    263         frame->key_frame?"keyframe, ":"",
     305    printf(BEGIN_TAG"AVFrame(%s) pts:%-10lld cnum:%-5d dnum:%-5d %s%s, ]\n"END_TAG,
     306        name,
     307        frame->pts,
     308        frame->coded_picture_number,
     309        frame->display_picture_number,
     310//      frame->quality,
     311        frame->key_frame?"keyframe, ":"",
    264312        picttypes[frame->pict_type]);
    265313//  printf(BEGIN_TAG"\t\tlinesize[] = {%ld, %ld, %ld, %ld}\n"END_TAG, frame->linesize[0], frame->linesize[1], frame->linesize[2], frame->linesize[3]);
    266314}