예제 #1
0
파일: frame.c 프로젝트: Chesnok2/FFmpeg
static void get_frame_defaults(AVFrame *frame)
{
    if (frame->extended_data != frame->data)
        av_freep(&frame->extended_data);

    memset(frame, 0, sizeof(*frame));

    frame->pts                   =
        frame->pkt_dts               =
            frame->pkt_pts               = AV_NOPTS_VALUE;
    av_frame_set_best_effort_timestamp(frame, AV_NOPTS_VALUE);
    av_frame_set_pkt_duration         (frame, 0);
    av_frame_set_pkt_pos              (frame, -1);
    av_frame_set_pkt_size             (frame, -1);
    frame->key_frame           = 1;
    frame->sample_aspect_ratio = (AVRational) {
        0, 1
    };
    frame->format              = -1; /* unknown */
    frame->extended_data       = frame->data;
    frame->color_primaries     = AVCOL_PRI_UNSPECIFIED;
    frame->color_trc           = AVCOL_TRC_UNSPECIFIED;
    frame->colorspace          = AVCOL_SPC_UNSPECIFIED;
    frame->color_range         = AVCOL_RANGE_UNSPECIFIED;
    frame->chroma_location     = AVCHROMA_LOC_UNSPECIFIED;
}
예제 #2
0
AVFrame* CFFmpegImage::ExtractFrame()
{
  if (!m_fctx || !m_fctx->streams[0])
  {
    CLog::LogFunction(LOGERROR, __FUNCTION__, "No valid format context or stream");
    return nullptr;
  }

  AVPacket pkt;
  AVFrame* frame = av_frame_alloc();
  int frame_decoded = 0;
  int ret = 0;
  ret = av_read_frame(m_fctx, &pkt);
  if (ret < 0)
  {
    CLog::Log(LOGDEBUG, "Error [%d] while reading frame: %s\n", ret, strerror(AVERROR(ret)));
    av_frame_free(&frame);
    av_packet_unref(&pkt);
    return nullptr;
  }

  ret = DecodeFFmpegFrame(m_codec_ctx, frame, &frame_decoded, &pkt);
  if (ret < 0 || frame_decoded == 0 || !frame)
  {
    CLog::Log(LOGDEBUG, "Error [%d] while decoding frame: %s\n", ret, strerror(AVERROR(ret)));
    av_frame_free(&frame);
    av_packet_unref(&pkt);
    return nullptr;
  }
  //we need milliseconds
  av_frame_set_pkt_duration(frame, av_rescale_q(frame->pkt_duration, m_fctx->streams[0]->time_base, AVRational{ 1, 1000 }));
  m_height = frame->height;
  m_width = frame->width;
  m_originalWidth = m_width;
  m_originalHeight = m_height;

  const AVPixFmtDescriptor* pixDescriptor = av_pix_fmt_desc_get(static_cast<AVPixelFormat>(frame->format));
  if (pixDescriptor && ((pixDescriptor->flags & (AV_PIX_FMT_FLAG_ALPHA | AV_PIX_FMT_FLAG_PAL)) != 0))
    m_hasAlpha = true;

  AVDictionary* dic = av_frame_get_metadata(frame);
  AVDictionaryEntry* entry = NULL;
  if (dic)
  {
    entry = av_dict_get(dic, "Orientation", NULL, AV_DICT_MATCH_CASE);
    if (entry && entry->value)
    {
      int orientation = atoi(entry->value);
      // only values between including 0 and including 8
      // http://sylvana.net/jpegcrop/exif_orientation.html
      if (orientation >= 0 && orientation <= 8)
        m_orientation = (unsigned int)orientation;
    }
  }
  av_packet_unref(&pkt);

  return frame;
}
예제 #3
0
파일: gifdec.c 프로젝트: Alcantor/FFmpeg
static int gif_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
{
    GifState *s = avctx->priv_data;
    int ret;

    bytestream2_init(&s->gb, avpkt->data, avpkt->size);

    s->frame->pts     = avpkt->pts;
    s->frame->pkt_pts = avpkt->pts;
    s->frame->pkt_dts = avpkt->dts;
    av_frame_set_pkt_duration(s->frame, avpkt->duration);

    if (avpkt->size >= 6) {
        s->keyframe = memcmp(avpkt->data, gif87a_sig, 6) == 0 ||
                      memcmp(avpkt->data, gif89a_sig, 6) == 0;
    } else {
        s->keyframe = 0;
    }

    if (s->keyframe) {
        s->keyframe_ok = 0;
        s->gce_prev_disposal = GCE_DISPOSAL_NONE;
        if ((ret = gif_read_header1(s)) < 0)
            return ret;

        if ((ret = ff_set_dimensions(avctx, s->screen_width, s->screen_height)) < 0)
            return ret;

        av_frame_unref(s->frame);
        if ((ret = ff_get_buffer(avctx, s->frame, 0)) < 0)
            return ret;

        av_fast_malloc(&s->idx_line, &s->idx_line_size, s->screen_width);
        if (!s->idx_line)
            return AVERROR(ENOMEM);

        s->frame->pict_type = AV_PICTURE_TYPE_I;
        s->frame->key_frame = 1;
        s->keyframe_ok = 1;
    } else {
        if (!s->keyframe_ok) {
            av_log(avctx, AV_LOG_ERROR, "cannot decode frame without keyframe\n");
            return AVERROR_INVALIDDATA;
        }

        if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
            return ret;

        s->frame->pict_type = AV_PICTURE_TYPE_P;
        s->frame->key_frame = 0;
    }

    ret = gif_parse_next_image(s, s->frame);
    if (ret < 0)
        return ret;

    if ((ret = av_frame_ref(data, s->frame)) < 0)
        return ret;
    *got_frame = 1;

    return bytestream2_tell(&s->gb);
}