Exemplo n.º 1
0
static int ffmpeg_GetFrameBuf( struct AVCodecContext *p_context,
                               AVFrame *p_ff_pic )
{
    decoder_t *p_dec = (decoder_t *)p_context->opaque;
    decoder_sys_t *p_sys = p_dec->p_sys;

    /* */
    p_ff_pic->opaque = NULL;
#if ! LIBAVCODEC_VERSION_CHECK(54, 34, 0, 79, 101)
    p_ff_pic->pkt_pts = p_context->pkt ? p_context->pkt->pts : AV_NOPTS_VALUE;
#endif
#if LIBAVCODEC_VERSION_MAJOR < 54
    p_ff_pic->age = 256*256*256*64;
#endif

    if( p_sys->p_va )
        return ffmpeg_va_GetFrameBuf(p_context, p_ff_pic);

    if( !p_sys->b_direct_rendering )
        return avcodec_default_get_buffer( p_context, p_ff_pic );

    wait_mt( p_sys );
    /* Some codecs set pix_fmt only after the 1st frame has been decoded,
     * so we need to check for direct rendering again. */

    picture_t *p_pic = ffmpeg_dr_GetFrameBuf(p_context);
    if (!p_pic) {
        if( p_sys->i_direct_rendering_used != 0 )
        {
            msg_Warn( p_dec, "disabling direct rendering" );
            p_sys->i_direct_rendering_used = 0;
        }

        post_mt( p_sys );
        return avcodec_default_get_buffer( p_context, p_ff_pic );
    }

    if( p_sys->i_direct_rendering_used != 1 ) {
        msg_Dbg( p_dec, "using direct rendering" );
        p_sys->i_direct_rendering_used = 1;
    }

    p_context->draw_horiz_band = NULL;
    post_mt( p_sys );

    p_ff_pic->opaque = (void*)p_pic;
    p_ff_pic->type = FF_BUFFER_TYPE_USER;
    p_ff_pic->data[0] = p_pic->p[0].p_pixels;
    p_ff_pic->data[1] = p_pic->p[1].p_pixels;
    p_ff_pic->data[2] = p_pic->p[2].p_pixels;
    p_ff_pic->data[3] = NULL; /* alpha channel but I'm not sure */

    p_ff_pic->linesize[0] = p_pic->p[0].i_pitch;
    p_ff_pic->linesize[1] = p_pic->p[1].i_pitch;
    p_ff_pic->linesize[2] = p_pic->p[2].i_pitch;
    p_ff_pic->linesize[3] = 0;

    return 0;
}
Exemplo n.º 2
0
int ac_get_buffer(struct AVCodecContext *c, AVFrame *pic) {
  int ret = avcodec_default_get_buffer(c, pic);
  uint64_t *pts = av_malloc(sizeof(uint64_t));
  *pts = AV_NOPTS_VALUE;
  pic->opaque = pts;
  return ret;
}
int our_get_buffer(struct AVCodecContext *c, AVFrame *pic, int flags) {
    int ret = avcodec_default_get_buffer(c, pic);
    uint64_t *pts = av_malloc(sizeof(uint64_t));
    *pts = global_video_pkt_pts;
    pic->opaque = pts;
    return ret;
}
Exemplo n.º 4
0
int get_buffer_with_pts(struct AVCodecContext *ctx, AVFrame *frame)
{
    int ret = avcodec_default_get_buffer(ctx, frame);
    uint64_t *pts = (uint64_t*)av_malloc(sizeof(uint64_t));
    *pts = AV_NOPTS_VALUE;
    frame->opaque = pts;
    return ret;
}
Exemplo n.º 5
0
int frame_storage_alloc(AVCodecContext *c, AVFrame *frame)
{
	/* round width and height to integer macroblock multiples */
	const int width  = (2 * (c->width  + ((1 << mb_size_log) - 1)) >> mb_size_log) << mb_size_log;
	const int height = (2 * (c->height + ((1 << mb_size_log) - 1)) >> mb_size_log) << mb_size_log;
	frame->opaque = av_malloc(avpicture_get_size(c->pix_fmt, width, height));
	return avcodec_default_get_buffer(c, frame);
}
Exemplo n.º 6
0
/* These are called whenever we allocate a frame
 * buffer. We use this to store the global_pts in
 * a frame at the time it is allocated.
 */
int our_get_buffer(struct AVCodecContext *c, AVFrame *pic) {
    int ret = avcodec_default_get_buffer(c, pic);
    uint64_t *pts = av_malloc(sizeof(uint64_t));
    // We set the wrong value here: global_video_pkt_pts
    *pts = global_video_pkt_pts;
    pic->opaque = pts;
    return ret;
}
Exemplo n.º 7
0
int our_get_buffer(struct AVCodecContext *c, AVFrame *pic) {
	int ret = avcodec_default_get_buffer(c, pic);
	uint64_t *pts = (uint64_t*)av_mallocz(sizeof(uint64_t));
	*pts = global_video_pkt_pts;
	pic->opaque = pts;
	//fprintf(stderr, "2: AVFrame.pkt_pts = %lld\n", pic->opaque);
	return ret;
}	
int our_get_buffer(struct AVCodecContext *c, AVFrame *pic)
{
    int ret = avcodec_default_get_buffer(c, pic);
    uint64_t *pts = new uint64_t;
    *pts = global_video_pkt_pts;
    pic->opaque = pts;
    return ret;
}
Exemplo n.º 9
0
int hack_get_buffer(struct AVCodecContext *c, AVFrame *pic) {
	PlayerCtx *ctx = (PlayerCtx*) c->opaque;

	int ret = avcodec_default_get_buffer(c, pic);
	uint64_t *pts = av_malloc(sizeof(uint64_t));
	*pts = ctx->v_pkt_pts;
	pic->opaque = pts;
	return ret;
}
Exemplo n.º 10
0
static int
vd_get_buffer(struct AVCodecContext *c, AVFrame *pic)
{
  int ret = avcodec_default_get_buffer(c, pic);
  media_buf_t *mb = malloc(sizeof(media_buf_t));
  memcpy(mb, c->opaque, sizeof(media_buf_t));
  pic->opaque = mb;
  return ret;
}
Exemplo n.º 11
0
static int flow_get_buffer(struct AVCodecContext *c, AVFrame *pic) {
  int ret = avcodec_default_get_buffer(c, pic);
  uint64_t *pts = (uint64_t*)av_malloc(sizeof(uint64_t));
  *pts = global_video_pkt_pts;
  pic->opaque = pts;

  //printf("Called malloc buffer\n");

  return ret;
}
Exemplo n.º 12
0
int FFMpegDecoder::my_get_buffer(struct AVCodecContext *c, AVFrame *pic) 
{
  int ret = avcodec_default_get_buffer(c, pic);
  if (ret)
	  errinfo("avcodec_default_get_buffer failed!\n");

  uint64_t *pts = (uint64_t*)av_malloc(sizeof(uint64_t));
  *pts = my_video_pkt_pts;
  pic->opaque = pts;
  return ret;
}
Exemplo n.º 13
0
FF_DISABLE_DEPRECATION_WARNINGS

static int I_AVGetBufferProc(struct AVCodecContext *c, AVFrame *pic)
{
    int ret = avcodec_default_get_buffer(c, pic);
    uint64_t *pts = av_malloc(sizeof(uint64_t));
    *pts = globalPts;

    pic->opaque = pts;
    return ret;
}
Exemplo n.º 14
0
int FFmpegDecoderVideo::getBuffer(AVCodecContext * const context, AVFrame * const picture)
{
    const FFmpegDecoderVideo * const this_ = reinterpret_cast<const FFmpegDecoderVideo*>(context->opaque);

    const int result = avcodec_default_get_buffer(context, picture);
    int64_t * p_pts = reinterpret_cast<int64_t*>( av_malloc(sizeof(int64_t)) );

    *p_pts = this_->m_packet_pts;
    picture->opaque = p_pts;

    return result;
}
Exemplo n.º 15
0
static int GetBuffer(struct AVCodecContext *Context, AVFrame *Frame)
{
    if (!Context->codec)
        return -1;

    if (!(Context->codec->capabilities & CODEC_CAP_DR1))
        return avcodec_default_get_buffer(Context, Frame);

    VideoDecoder *parent = static_cast<VideoDecoder*>(Context->opaque);
    if (parent)
        return parent->GetAVBuffer(Context, Frame);

    LOG(VB_GENERAL, LOG_ERR, "Invalid context");
    return -1;
}
Exemplo n.º 16
0
/* static */ int
FFmpegH264Decoder<LIBAV_VER>::AllocateBufferCb(AVCodecContext* aCodecContext,
                                               AVFrame* aFrame)
{
  MOZ_ASSERT(aCodecContext->codec_type == AVMEDIA_TYPE_VIDEO);

  FFmpegH264Decoder* self =
    static_cast<FFmpegH264Decoder*>(aCodecContext->opaque);

  switch (aCodecContext->pix_fmt) {
  case PIX_FMT_YUV420P:
    return self->AllocateYUV420PVideoBuffer(aCodecContext, aFrame);
  default:
    return avcodec_default_get_buffer(aCodecContext, aFrame);
  }
}
Exemplo n.º 17
0
static int
get_buffer(AVCodecContext *vcodec_ctx, AVFrame *vcodec_picture)
{
  VideoDecoder *vdec = (VideoDecoder *)vcodec_ctx->opaque;
  struct videodecoder_avcodec *vdm = (struct videodecoder_avcodec *)vdec->opaque;
  int width, height;
  Picture_buffer *buf;

  /* alignment */
  width  = (vcodec_ctx->width  + 15) & ~15;
  height = (vcodec_ctx->height + 15) & ~15;

  if (vcodec_ctx->pix_fmt != PIX_FMT_YUV420P ||
      width != vcodec_ctx->width || height != vcodec_ctx->height) {
    debug_message_fnc("avcodec: unsupported frame format, DR1 disabled.\n");
    vdm->vcodec_ctx->get_buffer = avcodec_default_get_buffer;
    vdm->vcodec_ctx->reget_buffer = avcodec_default_reget_buffer;
    vdm->vcodec_ctx->release_buffer = avcodec_default_release_buffer;
    return avcodec_default_get_buffer(vcodec_ctx, vcodec_picture);
  }

  buf = &vdm->picture_buffer[vdm->picture_buffer_count];
  if (buf->base == NULL) {
    int datasize = image_bpl(vdm->p) * image_height(vdm->p);
    int size = sizeof(struct pic_buf) + datasize;
    struct pic_buf *pb;

    if ((buf->base = memory_create()) == NULL) {
      err_message_fnc("No enough memory for Memory object buf->base.\n");
      return -1;
    }

    if ((pb = memory_alloc(buf->base, size)) == NULL) {
      err_message_fnc("Cannot allocate %d bytes.  No enough memory for pic_buf.\n", size);
      return -1;
    }
    pb->idx = vdm->picture_buffer_count;
    pb->mem = buf->base;
    memset(pb->data, 128, datasize);

    buf->pb = pb;
    buf->linesize[0] = image_width(vdm->p);
    buf->linesize[1] = image_width(vdm->p) >> 1;
    buf->linesize[2] = image_width(vdm->p) >> 1;
  }
Exemplo n.º 18
0
/* called when ffmpeg wants us to allocate a buffer to write the decoded frame
 * into. We try to give it memory from our pool */
static int
gst_ffmpegauddec_get_buffer (AVCodecContext * context, AVFrame * frame)
{
  GstFFMpegAudDec *ffmpegdec;
  GstAudioInfo *info;
  BufferInfo *buffer_info;

  ffmpegdec = (GstFFMpegAudDec *) context->opaque;
  if (G_UNLIKELY (!gst_ffmpegauddec_negotiate (ffmpegdec, FALSE)))
    goto negotiate_failed;

  /* Always use the default allocator for planar audio formats because
   * we will have to copy and deinterleave later anyway */
  if (av_sample_fmt_is_planar (ffmpegdec->context->sample_fmt))
    goto fallback;

  info = gst_audio_decoder_get_audio_info (GST_AUDIO_DECODER (ffmpegdec));

  buffer_info = g_slice_new (BufferInfo);
  buffer_info->buffer =
      gst_audio_decoder_allocate_output_buffer (GST_AUDIO_DECODER (ffmpegdec),
      frame->nb_samples * info->bpf);
  gst_buffer_map (buffer_info->buffer, &buffer_info->map, GST_MAP_WRITE);
  frame->opaque = buffer_info;
  frame->data[0] = buffer_info->map.data;
  frame->extended_data = frame->data;
  frame->linesize[0] = buffer_info->map.size;
  frame->type = FF_BUFFER_TYPE_USER;

  return 0;
  /* fallbacks */
negotiate_failed:
  {
    GST_DEBUG_OBJECT (ffmpegdec, "negotiate failed");
    goto fallback;
  }
fallback:
  {
    return avcodec_default_get_buffer (context, frame);
  }
}
Exemplo n.º 19
0
static int alloc_picture(MpegEncContext *s, Picture *pic, int shared)
{
    const int big_mb_num= s->mb_stride*(s->mb_height+1) + 1; //the +1 is needed so memset(,,stride*height) doesnt sig11
    const int mb_array_size= s->mb_stride*s->mb_height;
    const int b8_array_size= s->b8_stride*s->mb_height*2;
    const int b4_array_size= s->b4_stride*s->mb_height*4;
    int i;
    int r;
    r= avcodec_default_get_buffer(s->avctx, (AVFrame*)pic);

    if(r<0 || !pic->data[0])
        return -1;

    if(s->linesize && (s->linesize != pic->linesize[0] || s->uvlinesize != pic->linesize[1]))
        return -1;

    if(pic->linesize[1] != pic->linesize[2])
        return -1;

    s->linesize  = pic->linesize[0];
    s->uvlinesize= pic->linesize[1];

    if(pic->qscale_table==NULL)
	{
        CHECKED_ALLOCZ(pic->qscale_table , mb_array_size * sizeof(uint8_t));
        CHECKED_ALLOCZ(pic->mb_type_base , big_mb_num    * sizeof(uint32_t));
        pic->mb_type= pic->mb_type_base + s->mb_stride+1;

        for(i=0; i<2; i++)
		{
            CHECKED_ALLOCZ(pic->motion_val_base[i], 2 * (b4_array_size+2)  * sizeof(int16_t));
            pic->motion_val[i]= pic->motion_val_base[i]+2;
            CHECKED_ALLOCZ(pic->ref_index[i] , b8_array_size * sizeof(uint8_t));
        }
    }

    return 0;
fail: //for the CHECKED_ALLOCZ macro
    return -1;
}
Exemplo n.º 20
0
/** @internal @This is called by avcodec when allocating a new audio buffer
 * Used with audio decoders.
 * @param context current avcodec context
 * @param frame avframe handler entering avcodec black magic box
 */
static int upipe_avcdec_get_buffer_audio(struct AVCodecContext *context, AVFrame *frame)
{
    struct upipe *upipe = context->opaque;
    struct upipe_avcdec *upipe_avcdec = upipe_avcdec_from_upipe(upipe);
    struct ubuf *ubuf_samples;
    uint8_t *buf;
    int size;

    frame->opaque = uref_dup(upipe_avcdec->uref);

    /* direct rendering - allocate ubuf for audio */
    if (upipe_avcdec->context->codec->capabilities & CODEC_CAP_DR1) {
        
        ubuf_samples = ubuf_block_alloc(upipe_avcdec->ubuf_mgr,
                    av_samples_get_buffer_size(NULL, context->channels,
                        frame->nb_samples, context->sample_fmt, 1));

        if (likely(ubuf_samples)) {
            ubuf_block_write(ubuf_samples, 0, &size, &buf);
            uref_attach_ubuf(frame->opaque, ubuf_samples);

            av_samples_fill_arrays(frame->data, frame->linesize, buf,
                    context->channels, frame->nb_samples, context->sample_fmt, 1);

            frame->extended_data = frame->data;
            frame->type = FF_BUFFER_TYPE_USER;
            
            return 1; /* success */
        } else {
            upipe_dbg_va(upipe, "ubuf allocation failed, fallback");
        }
    }

    /* default : DR failed or not available */
    return avcodec_default_get_buffer(context, frame);
}
Exemplo n.º 21
0
bool AVIDump::CreateFile()
{
  AVCodec* codec = nullptr;

  s_format_context = avformat_alloc_context();
  std::stringstream s_file_index_str;
  s_file_index_str << s_file_index;
  snprintf(s_format_context->filename, sizeof(s_format_context->filename), "%s",
           (File::GetUserPath(D_DUMPFRAMES_IDX) + "framedump" + s_file_index_str.str() + ".avi")
               .c_str());
  File::CreateFullPath(s_format_context->filename);

  // Ask to delete file
  if (File::Exists(s_format_context->filename))
  {
    if (SConfig::GetInstance().m_DumpFramesSilent ||
        AskYesNoT("Delete the existing file '%s'?", s_format_context->filename))
    {
      File::Delete(s_format_context->filename);
    }
    else
    {
      // Stop and cancel dumping the video
      return false;
    }
  }

  if (!(s_format_context->oformat = av_guess_format("avi", nullptr, nullptr)) ||
      !(s_stream = avformat_new_stream(s_format_context, codec)))
  {
    return false;
  }

  s_stream->codec->codec_id =
      g_Config.bUseFFV1 ? AV_CODEC_ID_FFV1 : s_format_context->oformat->video_codec;
  if (!g_Config.bUseFFV1)
    s_stream->codec->codec_tag =
        MKTAG('X', 'V', 'I', 'D');  // Force XVID FourCC for better compatibility
  s_stream->codec->codec_type = AVMEDIA_TYPE_VIDEO;
  s_stream->codec->bit_rate = 400000;
  s_stream->codec->width = s_width;
  s_stream->codec->height = s_height;
  s_stream->codec->time_base.num = 1;
  s_stream->codec->time_base.den = VideoInterface::GetTargetRefreshRate();
  s_stream->codec->gop_size = 12;
  s_stream->codec->pix_fmt = g_Config.bUseFFV1 ? AV_PIX_FMT_BGRA : AV_PIX_FMT_YUV420P;

  if (!(codec = avcodec_find_encoder(s_stream->codec->codec_id)) ||
      (avcodec_open2(s_stream->codec, codec, nullptr) < 0))
  {
    return false;
  }

  s_src_frame = av_frame_alloc();
  s_scaled_frame = av_frame_alloc();

  s_scaled_frame->format = s_stream->codec->pix_fmt;
  s_scaled_frame->width = s_width;
  s_scaled_frame->height = s_height;

#if LIBAVCODEC_VERSION_MAJOR >= 55
  if (av_frame_get_buffer(s_scaled_frame, 1))
    return false;
#else
  if (avcodec_default_get_buffer(s_stream->codec, s_scaled_frame))
    return false;
#endif

  NOTICE_LOG(VIDEO, "Opening file %s for dumping", s_format_context->filename);
  if (avio_open(&s_format_context->pb, s_format_context->filename, AVIO_FLAG_WRITE) < 0 ||
      avformat_write_header(s_format_context, nullptr))
  {
    WARN_LOG(VIDEO, "Could not open %s", s_format_context->filename);
    return false;
  }

  OSD::AddMessage(StringFromFormat("Dumping Frames to \"%s\" (%dx%d)", s_format_context->filename,
                                   s_width, s_height));

  return true;
}
Exemplo n.º 22
0
bool AVIDump::CreateVideoFile()
{
  const std::string& format = g_Config.sDumpFormat;

  const std::string dump_path = GetDumpPath(format);

  if (dump_path.empty())
    return false;

  File::CreateFullPath(dump_path);

  AVOutputFormat* output_format = av_guess_format(format.c_str(), dump_path.c_str(), nullptr);
  if (!output_format)
  {
    ERROR_LOG(VIDEO, "Invalid format %s", format.c_str());
    return false;
  }

  if (avformat_alloc_output_context2(&s_format_context, output_format, nullptr, dump_path.c_str()) <
      0)
  {
    ERROR_LOG(VIDEO, "Could not allocate output context");
    return false;
  }

  const std::string& codec_name = g_Config.bUseFFV1 ? "ffv1" : g_Config.sDumpCodec;

  AVCodecID codec_id = output_format->video_codec;

  if (!codec_name.empty())
  {
    const AVCodecDescriptor* codec_desc = avcodec_descriptor_get_by_name(codec_name.c_str());
    if (codec_desc)
      codec_id = codec_desc->id;
    else
      WARN_LOG(VIDEO, "Invalid codec %s", codec_name.c_str());
  }

  const AVCodec* codec = nullptr;

  if (!g_Config.sDumpEncoder.empty())
  {
    codec = avcodec_find_encoder_by_name(g_Config.sDumpEncoder.c_str());
    if (!codec)
      WARN_LOG(VIDEO, "Invalid encoder %s", g_Config.sDumpEncoder.c_str());
  }
  if (!codec)
    codec = avcodec_find_encoder(codec_id);

  s_codec_context = avcodec_alloc_context3(codec);
  if (!codec || !s_codec_context)
  {
    ERROR_LOG(VIDEO, "Could not find encoder or allocate codec context");
    return false;
  }

  // Force XVID FourCC for better compatibility
  if (codec->id == AV_CODEC_ID_MPEG4)
    s_codec_context->codec_tag = MKTAG('X', 'V', 'I', 'D');

  s_codec_context->codec_type = AVMEDIA_TYPE_VIDEO;
  s_codec_context->bit_rate = g_Config.iBitrateKbps * 1000;
  s_codec_context->width = s_width;
  s_codec_context->height = s_height;
  s_codec_context->time_base.num = 1;
  s_codec_context->time_base.den = VideoInterface::GetTargetRefreshRate();
  s_codec_context->gop_size = 12;
  s_codec_context->pix_fmt = g_Config.bUseFFV1 ? AV_PIX_FMT_BGRA : AV_PIX_FMT_YUV420P;

  if (output_format->flags & AVFMT_GLOBALHEADER)
    s_codec_context->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;

  if (avcodec_open2(s_codec_context, codec, nullptr) < 0)
  {
    ERROR_LOG(VIDEO, "Could not open codec");
    return false;
  }

  s_src_frame = av_frame_alloc();
  s_scaled_frame = av_frame_alloc();

  s_scaled_frame->format = s_codec_context->pix_fmt;
  s_scaled_frame->width = s_width;
  s_scaled_frame->height = s_height;

#if LIBAVCODEC_VERSION_MAJOR >= 55
  if (av_frame_get_buffer(s_scaled_frame, 1))
    return false;
#else
  if (avcodec_default_get_buffer(s_codec_context, s_scaled_frame))
    return false;
#endif

  s_stream = avformat_new_stream(s_format_context, codec);
  if (!s_stream || !AVStreamCopyContext(s_stream, s_codec_context))
  {
    ERROR_LOG(VIDEO, "Could not create stream");
    return false;
  }

  NOTICE_LOG(VIDEO, "Opening file %s for dumping", s_format_context->filename);
  if (avio_open(&s_format_context->pb, s_format_context->filename, AVIO_FLAG_WRITE) < 0 ||
      avformat_write_header(s_format_context, nullptr))
  {
    ERROR_LOG(VIDEO, "Could not open %s", s_format_context->filename);
    return false;
  }

  OSD::AddMessage(StringFromFormat("Dumping Frames to \"%s\" (%dx%d)", s_format_context->filename,
                                   s_width, s_height));

  return true;
}
Exemplo n.º 23
0
static int ffmpeg_GetFrameBuf( struct AVCodecContext *p_context,
                               AVFrame *p_ff_pic )
{
    decoder_t *p_dec = (decoder_t *)p_context->opaque;
    decoder_sys_t *p_sys = p_dec->p_sys;
    picture_t *p_pic;

    /* Set picture PTS */
    ffmpeg_SetFrameBufferPts( p_dec, p_ff_pic );

    /* */
    p_ff_pic->opaque = NULL;

    if( p_sys->p_va )
    {
#ifdef HAVE_AVCODEC_VAAPI
        /* hwaccel_context is not present in old fffmpeg version */
        if( VaSetup( p_sys->p_va,
                     &p_sys->p_context->hwaccel_context, &p_dec->fmt_out.video.i_chroma,
                     p_sys->p_context->width, p_sys->p_context->height ) )
        {
            msg_Err( p_dec, "VaSetup failed" );
            return -1;
        }
#else
        assert(0);
#endif

        /* */
        p_ff_pic->type = FF_BUFFER_TYPE_USER;
        /* FIXME what is that, should give good value */
        p_ff_pic->age = 256*256*256*64; // FIXME FIXME from ffmpeg

        if( VaGrabSurface( p_sys->p_va, p_ff_pic ) )
        {
            msg_Err( p_dec, "VaGrabSurface failed" );
            return -1;
        }
        return 0;
    }
    else if( !p_sys->b_direct_rendering )
    {
        /* Not much to do in indirect rendering mode */
        return avcodec_default_get_buffer( p_context, p_ff_pic );
    }

    /* Some codecs set pix_fmt only after the 1st frame has been decoded,
     * so we need to check for direct rendering again. */

    int i_width = p_sys->p_context->width;
    int i_height = p_sys->p_context->height;
    avcodec_align_dimensions( p_sys->p_context, &i_width, &i_height );

    if( GetVlcChroma( &p_dec->fmt_out.video, p_context->pix_fmt ) != VLC_SUCCESS ||
        p_sys->p_context->width % 16 || p_sys->p_context->height % 16 ||
        /* We only pad picture up to 16 */
        PAD(p_sys->p_context->width,16) < i_width || PAD(p_sys->p_context->height,16) < i_height ||
        p_context->pix_fmt == PIX_FMT_PAL8 )
        return avcodec_default_get_buffer( p_context, p_ff_pic );

    p_dec->fmt_out.i_codec = p_dec->fmt_out.video.i_chroma;

    /* Get a new picture */
    p_pic = ffmpeg_NewPictBuf( p_dec, p_sys->p_context );
    if( !p_pic )
        return avcodec_default_get_buffer( p_context, p_ff_pic );

    p_sys->p_context->draw_horiz_band = NULL;

    p_ff_pic->opaque = (void*)p_pic;
    p_ff_pic->type = FF_BUFFER_TYPE_USER;
    p_ff_pic->data[0] = p_pic->p[0].p_pixels;
    p_ff_pic->data[1] = p_pic->p[1].p_pixels;
    p_ff_pic->data[2] = p_pic->p[2].p_pixels;
    p_ff_pic->data[3] = NULL; /* alpha channel but I'm not sure */

    p_ff_pic->linesize[0] = p_pic->p[0].i_pitch;
    p_ff_pic->linesize[1] = p_pic->p[1].i_pitch;
    p_ff_pic->linesize[2] = p_pic->p[2].i_pitch;
    p_ff_pic->linesize[3] = 0;

    decoder_LinkPicture( p_dec, p_pic );

    /* FIXME what is that, should give good value */
    p_ff_pic->age = 256*256*256*64; // FIXME FIXME from ffmpeg

    return 0;
}
Exemplo n.º 24
0
/** @internal @This is called by avcodec when allocating a new frame
 * @param context current avcodec context
 * @param frame avframe handler entering avcodec black magic box
 */
static int upipe_avcdec_get_buffer(struct AVCodecContext *context, AVFrame *frame)
{
    struct upipe *upipe = context->opaque;
    struct upipe_avcdec *upipe_avcdec = upipe_avcdec_from_upipe(upipe);
    struct ubuf *ubuf_pic;
    int width_aligned, height_aligned, i;
    const struct upipe_av_plane *planes = NULL;
    size_t stride = 0;

    frame->opaque = uref_dup(upipe_avcdec->uref);

    uint64_t framenum = 0;
    uref_pic_get_number(frame->opaque, &framenum);

    upipe_dbg_va(upipe, "Allocating frame for %u (%p) - %ux%u",
                 framenum, frame->opaque, frame->width, frame->height);

    if (unlikely(!upipe_avcdec->pixfmt)) {
        upipe_avcdec->pixfmt = upipe_av_pixfmt_from_ubuf_mgr(upipe_avcdec->ubuf_mgr);
        if (unlikely(!upipe_avcdec->pixfmt)) {
            upipe_err_va(upipe, "frame format of ubuf manager not recognized");
            return 0;
        }
    }
    if (context->pix_fmt != *upipe_avcdec->pixfmt->pixfmt) {
        upipe_err_va(upipe, "frame format not compatible (%s != %s",
                                       av_get_pix_fmt_name(context->pix_fmt),
                            av_get_pix_fmt_name(*upipe_avcdec->pixfmt->pixfmt));
        return 0;
    }
    planes = upipe_avcdec->pixfmt->planes;

    /* direct rendering - allocate ubuf pic */
    if (upipe_avcdec->context->codec->capabilities & CODEC_CAP_DR1) {
        width_aligned = context->width;
        height_aligned = context->height;

        /* use avcodec width/height alignement, then resize pic */
        avcodec_align_dimensions(context, &width_aligned, &height_aligned);
        ubuf_pic = ubuf_pic_alloc(upipe_avcdec->ubuf_mgr, width_aligned, height_aligned);

        if (likely(ubuf_pic)) {
            ubuf_pic_resize(ubuf_pic, 0, 0, context->width, context->height);
            uref_attach_ubuf(frame->opaque, ubuf_pic);

            for (i=0; i < 4 && planes[i].chroma; i++) {
                ubuf_pic_plane_write(ubuf_pic, planes[i].chroma,
                        0, 0, -1, -1, &frame->data[i]);
                ubuf_pic_plane_size(ubuf_pic, planes[i].chroma, &stride,
                        NULL, NULL, NULL);
                frame->linesize[i] = stride;
            }

            frame->extended_data = frame->data;
            frame->type = FF_BUFFER_TYPE_USER;
            
            return 1; /* success */
        } else {
            upipe_dbg_va(upipe, "ubuf_pic_alloc(%d, %d) failed, fallback", width_aligned, height_aligned);
        }
    }

    /* default : DR failed or not available */
    return avcodec_default_get_buffer(context, frame);
}
Exemplo n.º 25
0
/*****************************************************************************
 * ffmpeg_GetFrameBuf: callback used by ffmpeg to get a frame buffer.
 *****************************************************************************
 * It is used for direct rendering as well as to get the right PTS for each
 * decoded picture (even in indirect rendering mode).
 *****************************************************************************/
static int ffmpeg_GetFrameBuf( struct AVCodecContext *p_context,
                               AVFrame *p_ff_pic )
{
    decoder_t *p_dec = (decoder_t *)p_context->opaque;
    decoder_sys_t *p_sys = p_dec->p_sys;
    picture_t *p_pic;

    /* Set picture PTS */
    if( p_sys->input_pts )
    {
        p_ff_pic->pts = p_sys->input_pts;
    }
    else if( p_sys->input_dts )
    {
        /* Some demuxers only set the dts so let's try to find a useful
         * timestamp from this */
        if( !p_context->has_b_frames || !p_sys->b_has_b_frames ||
            !p_ff_pic->reference || !p_sys->i_pts )
        {
            p_ff_pic->pts = p_sys->input_dts;
        }
        else p_ff_pic->pts = 0;
    }
    else p_ff_pic->pts = 0;

    if( p_sys->i_pts ) /* make sure 1st frame has a pts > 0 */
    {
        p_sys->input_pts = p_sys->input_dts = 0;
    }

    p_ff_pic->opaque = 0;

    /* Not much to do in indirect rendering mode */
    if( !p_sys->b_direct_rendering || p_sys->b_pp )
    {
        return avcodec_default_get_buffer( p_context, p_ff_pic );
    }

    /* Some codecs set pix_fmt only after the 1st frame has been decoded,
     * so this check is necessary. */
    if( !ffmpeg_PixFmtToChroma( p_context->pix_fmt ) ||
        p_sys->p_context->width % 16 || p_sys->p_context->height % 16 )
    {
        msg_Dbg( p_dec, "disabling direct rendering" );
        p_sys->b_direct_rendering = 0;
        return avcodec_default_get_buffer( p_context, p_ff_pic );
    }

    /* Get a new picture */
    //p_sys->p_vout->render.b_allow_modify_pics = 0;
    p_pic = ffmpeg_NewPictBuf( p_dec, p_sys->p_context );
    if( !p_pic )
    {
        p_sys->b_direct_rendering = 0;
        return avcodec_default_get_buffer( p_context, p_ff_pic );
    }
    p_sys->p_context->draw_horiz_band = NULL;

    p_ff_pic->opaque = (void*)p_pic;
    p_ff_pic->type = FF_BUFFER_TYPE_USER;
    p_ff_pic->data[0] = p_pic->p[0].p_pixels;
    p_ff_pic->data[1] = p_pic->p[1].p_pixels;
    p_ff_pic->data[2] = p_pic->p[2].p_pixels;
    p_ff_pic->data[3] = NULL; /* alpha channel but I'm not sure */

    p_ff_pic->linesize[0] = p_pic->p[0].i_pitch;
    p_ff_pic->linesize[1] = p_pic->p[1].i_pitch;
    p_ff_pic->linesize[2] = p_pic->p[2].i_pitch;
    p_ff_pic->linesize[3] = 0;

    if( p_ff_pic->reference != 0 )
    {
        p_dec->pf_picture_link( p_dec, p_pic );
    }

    /* FIXME what is that, should give good value */
    p_ff_pic->age = 256*256*256*64; // FIXME FIXME from ffmpeg

    return 0;
}
Exemplo n.º 26
0
static int ffmpeg_GetFrameBuf( struct AVCodecContext *p_context,
                               AVFrame *p_ff_pic )
{
    decoder_t *p_dec = (decoder_t *)p_context->opaque;
    decoder_sys_t *p_sys = p_dec->p_sys;
    picture_t *p_pic;

    /* Set picture PTS */
    ffmpeg_SetFrameBufferPts( p_dec, p_ff_pic );

    /* */
    p_ff_pic->opaque = NULL;

    if( p_sys->p_va )
    {
#ifdef HAVE_AVCODEC_VA
        /* hwaccel_context is not present in old fffmpeg version */
        if( vlc_va_Setup( p_sys->p_va,
                          &p_sys->p_context->hwaccel_context, &p_dec->fmt_out.video.i_chroma,
                          p_sys->p_context->width, p_sys->p_context->height ) )
        {
            msg_Err( p_dec, "vlc_va_Setup failed" );
            return -1;
        }
#else
        assert(0);
#endif

        /* */
        p_ff_pic->type = FF_BUFFER_TYPE_USER;
        /* FIXME what is that, should give good value */
        p_ff_pic->age = 256*256*256*64; // FIXME FIXME from ffmpeg

        if( vlc_va_Get( p_sys->p_va, p_ff_pic ) )
        {
            msg_Err( p_dec, "VaGrabSurface failed" );
            return -1;
        }
        return 0;
    }
    else if( !p_sys->b_direct_rendering )
    {
        /* Not much to do in indirect rendering mode. */
        return avcodec_default_get_buffer( p_context, p_ff_pic );
    }

    /* Some codecs set pix_fmt only after the 1st frame has been decoded,
     * so we need to check for direct rendering again. */

    int i_width = p_sys->p_context->width;
    int i_height = p_sys->p_context->height;
    avcodec_align_dimensions( p_sys->p_context, &i_width, &i_height );

    if( GetVlcChroma( &p_dec->fmt_out.video, p_context->pix_fmt ) != VLC_SUCCESS ||
        p_context->pix_fmt == PIX_FMT_PAL8 )
        goto no_dr;

    p_dec->fmt_out.i_codec = p_dec->fmt_out.video.i_chroma;

    /* Get a new picture */
    p_pic = ffmpeg_NewPictBuf( p_dec, p_sys->p_context );
    if( !p_pic )
        goto no_dr;
    bool b_compatible = true;
    if( p_pic->p[0].i_pitch / p_pic->p[0].i_pixel_pitch < i_width ||
        p_pic->p[0].i_lines < i_height )
        b_compatible = false;
    for( int i = 0; i < p_pic->i_planes && b_compatible; i++ )
    {
        unsigned i_align;
        switch( p_sys->i_codec_id )
        {
        case CODEC_ID_SVQ1:
        case CODEC_ID_VP5:
        case CODEC_ID_VP6:
        case CODEC_ID_VP6F:
        case CODEC_ID_VP6A:
            i_align = 16;
            break;
        default:
            i_align = i == 0 ? 16 : 8;
            break;
        }
        if( p_pic->p[i].i_pitch % i_align )
            b_compatible = false;
        if( (intptr_t)p_pic->p[i].p_pixels % i_align )
            b_compatible = false;
    }
    if( p_context->pix_fmt == PIX_FMT_YUV422P && b_compatible )
    {
        if( 2 * p_pic->p[1].i_pitch != p_pic->p[0].i_pitch ||
            2 * p_pic->p[2].i_pitch != p_pic->p[0].i_pitch )
            b_compatible = false;
    }
    if( !b_compatible )
    {
        decoder_DeletePicture( p_dec, p_pic );
        goto no_dr;
    }

    if( p_sys->i_direct_rendering_used != 1 )
    {
        msg_Dbg( p_dec, "using direct rendering" );
        p_sys->i_direct_rendering_used = 1;
    }

    p_sys->p_context->draw_horiz_band = NULL;

    p_ff_pic->opaque = (void*)p_pic;
    p_ff_pic->type = FF_BUFFER_TYPE_USER;
    p_ff_pic->data[0] = p_pic->p[0].p_pixels;
    p_ff_pic->data[1] = p_pic->p[1].p_pixels;
    p_ff_pic->data[2] = p_pic->p[2].p_pixels;
    p_ff_pic->data[3] = NULL; /* alpha channel but I'm not sure */

    p_ff_pic->linesize[0] = p_pic->p[0].i_pitch;
    p_ff_pic->linesize[1] = p_pic->p[1].i_pitch;
    p_ff_pic->linesize[2] = p_pic->p[2].i_pitch;
    p_ff_pic->linesize[3] = 0;

    decoder_LinkPicture( p_dec, p_pic );

    /* FIXME what is that, should give good value */
    p_ff_pic->age = 256*256*256*64; // FIXME FIXME from ffmpeg

    return 0;

no_dr:
    if( p_sys->i_direct_rendering_used != 0 )
    {
        msg_Warn( p_dec, "disabling direct rendering" );
        p_sys->i_direct_rendering_used = 0;
    }
    return avcodec_default_get_buffer( p_context, p_ff_pic );
}