diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/combined/ffmpeg/ff_video_decoder.c | 54 | 
1 files changed, 40 insertions, 14 deletions
| diff --git a/src/combined/ffmpeg/ff_video_decoder.c b/src/combined/ffmpeg/ff_video_decoder.c index a1ab3696c..01635e1ab 100644 --- a/src/combined/ffmpeg/ff_video_decoder.c +++ b/src/combined/ffmpeg/ff_video_decoder.c @@ -58,6 +58,12 @@  #define ENABLE_DIRECT_RENDERING +/* reordered_opaque appeared in libavcodec 51.68.0 */ +#define AVCODEC_HAS_REORDERED_OPAQUE +#if LIBAVCODEC_VERSION_INT < 0x334400 +# undef AVCODEC_HAS_REORDERED_OPAQUE +#endif +  typedef struct ff_video_decoder_s ff_video_decoder_t;  typedef struct ff_video_class_s { @@ -78,9 +84,11 @@ struct ff_video_decoder_s {    xine_stream_t    *stream;    int64_t           pts; +#ifdef AVCODEC_HAS_REORDERED_OPAQUE    uint64_t          pts_tag_mask;    uint64_t          pts_tag;    int               pts_tag_counter; +#endif /* AVCODEC_HAS_REORDERED_OPAQUE */    int               video_step;    uint8_t           decoder_ok:1; @@ -609,10 +617,6 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {    su = this->av_frame->data[1];    sv = this->av_frame->data[2]; -  /* Some segfaults & heap corruption have been observed with img->height, -   * so we use this->bih.biHeight instead (which is the displayed height) -   */ -    if (this->context->pix_fmt == PIX_FMT_YUV410P) {      yuv9_to_yv12( @@ -633,7 +637,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {        img->pitches[2],       /* width x height */        img->width, -      this->bih.biHeight); +      img->height);    } else if (this->context->pix_fmt == PIX_FMT_YUV411P) { @@ -655,7 +659,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {        img->pitches[2],       /* width x height */        img->width, -      this->bih.biHeight); +      img->height);    } else if (this->context->pix_fmt == PIX_FMT_RGBA32) { @@ -663,7 +667,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {      uint32_t *argb_pixels;      uint32_t argb; -    for(y = 0; y < this->bih.biHeight; y++) { +    for(y = 0; y < img->height; y++) {        argb_pixels = (uint32_t *)sy;        for(x = 0; x < img->width; x++) {          uint8_t r, g, b; @@ -691,7 +695,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {      uint8_t *src;      uint16_t pixel16; -    for(y = 0; y < this->bih.biHeight; y++) { +    for(y = 0; y < img->height; y++) {        src = sy;        for(x = 0; x < img->width; x++) {          uint8_t r, g, b; @@ -720,7 +724,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {      uint8_t *src;      uint16_t pixel16; -    for(y = 0; y < this->bih.biHeight; y++) { +    for(y = 0; y < img->height; y++) {        src = sy;        for(x = 0; x < img->width; x++) {          uint8_t r, g, b; @@ -748,7 +752,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {      int x, plane_ptr = 0;      uint8_t *src; -    for(y = 0; y < this->bih.biHeight; y++) { +    for(y = 0; y < img->height; y++) {        src = sy;        for(x = 0; x < img->width; x++) {          uint8_t r, g, b; @@ -772,7 +776,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {      int x, plane_ptr = 0;      uint8_t *src; -    for(y = 0; y < this->bih.biHeight; y++) { +    for(y = 0; y < img->height; y++) {        src = sy;        for(x = 0; x < img->width; x++) {          uint8_t r, g, b; @@ -815,7 +819,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {        v_palette[x] = COMPUTE_V(r, g, b);      } -    for(y = 0; y < this->bih.biHeight; y++) { +    for(y = 0; y < img->height; y++) {        src = sy;        for(x = 0; x < img->width; x++) {          pixel = *src++; @@ -832,7 +836,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {    } else { -    for (y = 0; y < this->bih.biHeight; y++) { +    for (y=0; y<img->height; y++) {        xine_fast_memcpy (dy, sy, img->width);        dy += img->pitches[0]; @@ -840,7 +844,7 @@ static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img) {        sy += this->av_frame->linesize[0];      } -    for (y = 0; y < this->bih.biHeight / 2; y++) { +    for (y=0; y<(img->height/2); y++) {        if (this->context->pix_fmt != PIX_FMT_YUV444P) { @@ -1181,6 +1185,7 @@ static void ff_handle_mpeg12_buffer (ff_video_decoder_t *this, buf_element_t *bu    }  } +#ifdef AVCODEC_HAS_REORDERED_OPAQUE  static uint64_t ff_tag_pts(ff_video_decoder_t *this, uint64_t pts)  {    return pts | this->pts_tag; @@ -1217,6 +1222,7 @@ static void ff_check_pts_tagging(ff_video_decoder_t *this, uint64_t pts)    }  } +#endif /* AVCODEC_HAS_REORDERED_OPAQUE */  static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {    uint8_t *chunk_buf = this->buf;    AVRational avr00 = {0, 1}; @@ -1241,12 +1247,14 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {      this->size = 0;    } +#ifdef AVCODEC_HAS_REORDERED_OPAQUE    if (this->size == 0) {      /* take over pts when we are about to buffer a frame */      this->av_frame->reordered_opaque = ff_tag_pts(this, this->pts);      this->context->reordered_opaque = ff_tag_pts(this, this->pts);      this->pts = 0;    } +#endif /* AVCODEC_HAS_REORDERED_OPAQUE */    /* data accumulation */    if (buf->size > 0) { @@ -1301,8 +1309,10 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {                                      &got_picture, &chunk_buf[offset],                                      this->size); +#ifdef AVCODEC_HAS_REORDERED_OPAQUE          /* reset consumed pts value */          this->context->reordered_opaque = ff_tag_pts(this, 0); +#endif /* AVCODEC_HAS_REORDERED_OPAQUE */          lprintf("consumed size: %d, got_picture: %d\n", len, got_picture);          if ((len <= 0) || (len > this->size)) { @@ -1320,10 +1330,12 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {              memmove (this->buf, &chunk_buf[offset], this->size);              chunk_buf = this->buf; +#ifdef AVCODEC_HAS_REORDERED_OPAQUE              /* take over pts for next access unit */              this->av_frame->reordered_opaque = ff_tag_pts(this, this->pts);              this->context->reordered_opaque = ff_tag_pts(this, this->pts);              this->pts = 0; +#endif /* AVCODEC_HAS_REORDERED_OPAQUE */            }          }        } @@ -1418,9 +1430,14 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {            ff_convert_frame(this, img);          } +#ifndef AVCODEC_HAS_REORDERED_OPAQUE +        img->pts  = this->pts; +        this->pts = 0; +#else /* AVCODEC_HAS_REORDERED_OPAQUE */          img->pts  = ff_untag_pts(this, this->av_frame->reordered_opaque);          ff_check_pts_tagging(this, this->av_frame->reordered_opaque); /* only check for valid frames */          this->av_frame->reordered_opaque = 0; +#endif /* AVCODEC_HAS_REORDERED_OPAQUE */          /* workaround for weird 120fps streams */          if( video_step_to_use == 750 ) { @@ -1460,8 +1477,13 @@ static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) {                                                  this->output_format,                                                  VO_BOTH_FIELDS|this->frame_flags);        /* set PTS to allow early syncing */ +#ifndef AVCODEC_HAS_REORDERED_OPAQUE +      img->pts       = this->pts; +      this->pts      = 0; +#else /* AVCODEC_HAS_REORDERED_OPAQUE */        img->pts       = ff_untag_pts(this, this->av_frame->reordered_opaque);        this->av_frame->reordered_opaque = 0; +#endif /* AVCODEC_HAS_REORDERED_OPAQUE */        img->duration  = video_step_to_use; @@ -1547,9 +1569,11 @@ static void ff_reset (video_decoder_t *this_gen) {    if (this->is_mpeg12)      mpeg_parser_reset(this->mpeg_parser); +#ifdef AVCODEC_HAS_REORDERED_OPAQUE    this->pts_tag_mask = 0;    this->pts_tag = 0;    this->pts_tag_counter = 0; +#endif /* AVCODEC_HAS_REORDERED_OPAQUE */  }  static void ff_discontinuity (video_decoder_t *this_gen) { @@ -1558,6 +1582,7 @@ static void ff_discontinuity (video_decoder_t *this_gen) {    lprintf ("ff_discontinuity\n");    this->pts = 0; +#ifdef AVCODEC_HAS_REORDERED_OPAQUE    /*     * there is currently no way to reset all the pts which are stored in the decoder.     * therefore, we add a unique tag (generated from pts_tag_counter) to pts (see  @@ -1588,6 +1613,7 @@ static void ff_discontinuity (video_decoder_t *this_gen) {        counter_mask <<= 1;      }    } +#endif /* AVCODEC_HAS_REORDERED_OPAQUE */  }  static void ff_dispose (video_decoder_t *this_gen) { | 
