int FrameQueue::get(AVFrame *frame) { AVFrameList *frame1; int ret; pthread_mutex_lock(&mutex); for(;;) { frame1 = first_frame; if (frame1) { first_frame = frame1->next; if (!first_frame){ last_frame = NULL; } node_count --; av_frame_ref(frame, frame1->frame); // set frame av_frame_unref(frame1->frame); av_frame_free(&frame1->frame); av_free(frame1); ret = 1; break; } else { pthread_cond_wait(&cond, &mutex); } } pthread_mutex_unlock(&mutex); return ret; }
MediaPictureImpl* MediaPictureImpl::make(MediaPictureImpl* src, bool copy) { RefPointer<MediaPictureImpl> retval; if (!src) VS_THROW(HumbleInvalidArgument("no src object to copy from")); if (copy) { // first create a new mediaaudio object to copy into retval = make(src->getWidth(), src->getHeight(), src->getFormat()); retval->mComplete = src->mComplete; // then copy the data into retval int32_t n = src->getNumDataPlanes(); for(int32_t i = 0; i < n; i++ ) { AVBufferRef* dstBuf = av_frame_get_plane_buffer(retval->mFrame, i); AVBufferRef* srcBuf = av_frame_get_plane_buffer(src->mFrame, i); VS_ASSERT(dstBuf, "should always have buffer"); VS_ASSERT(srcBuf, "should always have buffer"); memcpy(dstBuf->data, srcBuf->data, srcBuf->size); } } else { // first create a new media audio object to reference into retval = make(); // then do the reference retval->mComplete = src->mComplete; av_frame_ref(retval->mFrame, src->mFrame); } // set the timebase retval->setComplete(src->isComplete()); RefPointer<Rational> timeBase = src->getTimeBase(); retval->setTimeBase(timeBase.value()); return retval.get(); }
static int mp_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; MotionPixelsContext *mp = avctx->priv_data; GetBitContext gb; int i, count1, count2, sz, ret; if ((ret = ff_reget_buffer(avctx, mp->frame)) < 0) return ret; /* le32 bitstream msb first */ av_fast_padded_malloc(&mp->bswapbuf, &mp->bswapbuf_size, buf_size); if (!mp->bswapbuf) return AVERROR(ENOMEM); mp->dsp.bswap_buf((uint32_t *)mp->bswapbuf, (const uint32_t *)buf, buf_size / 4); if (buf_size & 3) memcpy(mp->bswapbuf + (buf_size & ~3), buf + (buf_size & ~3), buf_size & 3); init_get_bits(&gb, mp->bswapbuf, buf_size * 8); memset(mp->changes_map, 0, avctx->width * avctx->height); for (i = !(avctx->extradata[1] & 2); i < 2; ++i) { count1 = get_bits(&gb, 12); count2 = get_bits(&gb, 12); mp_read_changes_map(mp, &gb, count1, 8, i); mp_read_changes_map(mp, &gb, count2, 4, i); } mp->codes_count = get_bits(&gb, 4); if (mp->codes_count == 0) goto end; if (mp->changes_map[0] == 0) { *(uint16_t *)mp->frame->data[0] = get_bits(&gb, 15); mp->changes_map[0] = 1; } if (mp_read_codes_table(mp, &gb) < 0) goto end; sz = get_bits(&gb, 18); if (avctx->extradata[0] != 5) sz += get_bits(&gb, 18); if (sz == 0) goto end; if (mp->max_codes_bits <= 0) goto end; if (init_vlc(&mp->vlc, mp->max_codes_bits, mp->codes_count, &mp->codes[0].size, sizeof(HuffCode), 1, &mp->codes[0].code, sizeof(HuffCode), 4, 0)) goto end; mp_decode_frame_helper(mp, &gb); ff_free_vlc(&mp->vlc); end: if ((ret = av_frame_ref(data, mp->frame)) < 0) return ret; *got_frame = 1; return buf_size; }
static int truemotion1_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int ret, buf_size = avpkt->size; TrueMotion1Context *s = avctx->priv_data; s->buf = buf; s->size = buf_size; if ((ret = truemotion1_decode_header(s)) < 0) return ret; if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) return ret; if (compression_types[s->compression].algorithm == ALGO_RGB24H) { truemotion1_decode_24bit(s); } else if (compression_types[s->compression].algorithm != ALGO_NOP) { truemotion1_decode_16bit(s); } if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; *got_frame = 1; /* report that the buffer was completely consumed */ return buf_size; }
int attribute_align_arg av_buffersink_get_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags) { BufferSinkContext *buf = ctx->priv; AVFilterLink *inlink = ctx->inputs[0]; int ret; AVFrame *cur_frame; /* no picref available, fetch it from the filterchain */ if (!av_fifo_size(buf->fifo)) { if (flags & AV_BUFFERSINK_FLAG_NO_REQUEST) return AVERROR(EAGAIN); if ((ret = ff_request_frame(inlink)) < 0) return ret; } if (!av_fifo_size(buf->fifo)) return AVERROR(EINVAL); if (flags & AV_BUFFERSINK_FLAG_PEEK) { cur_frame = *((AVFrame **)av_fifo_peek2(buf->fifo, 0)); av_frame_ref(frame, cur_frame); /* TODO check failure */ } else { av_fifo_generic_read(buf->fifo, &cur_frame, sizeof(cur_frame), NULL); av_frame_move_ref(frame, cur_frame); av_frame_free(&cur_frame); } return 0; }
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; CamStudioContext *c = avctx->priv_data; int ret; if (buf_size < 2) { av_log(avctx, AV_LOG_ERROR, "coded frame too small\n"); return AVERROR_INVALIDDATA; } if ((ret = ff_reget_buffer(avctx, c->pic)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } // decompress data switch ((buf[0] >> 1) & 7) { case 0: { // lzo compression int outlen = c->decomp_size, inlen = buf_size - 2; if (av_lzo1x_decode(c->decomp_buf, &outlen, &buf[2], &inlen)) av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n"); break; } case 1: { // zlib compression #if CONFIG_ZLIB unsigned long dlen = c->decomp_size; if (uncompress(c->decomp_buf, &dlen, &buf[2], buf_size - 2) != Z_OK) av_log(avctx, AV_LOG_ERROR, "error during zlib decompression\n"); break; #else av_log(avctx, AV_LOG_ERROR, "compiled without zlib support\n"); return AVERROR(ENOSYS); #endif } default: av_log(avctx, AV_LOG_ERROR, "unknown compression\n"); return AVERROR_INVALIDDATA; } // flip upside down, add difference frame if (buf[0] & 1) { // keyframe c->pic->pict_type = AV_PICTURE_TYPE_I; c->pic->key_frame = 1; copy_frame_default(c->pic, c->decomp_buf, c->linelen, c->height); } else { c->pic->pict_type = AV_PICTURE_TYPE_P; c->pic->key_frame = 0; add_frame_default(c->pic, c->decomp_buf, c->linelen, c->height); } *got_frame = 1; if ((ret = av_frame_ref(data, c->pic)) < 0) return ret; return buf_size; }
int SDL_VoutFFmpeg_ConvertFrame( SDL_VoutOverlay *overlay, AVFrame *frame, struct SwsContext **p_sws_ctx, int sws_flags) { assert(overlay); assert(p_sws_ctx); SDL_VoutOverlay_Opaque *opaque = overlay->opaque; AVPicture dest_pic = { { 0 } }; for (int i = 0; i < overlay->planes; ++i) { dest_pic.data[i] = overlay->pixels[i]; dest_pic.linesize[i] = overlay->pitches[i]; } av_frame_unref(opaque->linked_frame); int use_linked_frame = 0; enum AVPixelFormat dst_format = AV_PIX_FMT_NONE; switch (overlay->format) { case SDL_FCC_YV12: if (frame->format == AV_PIX_FMT_YUV420P || frame->format == AV_PIX_FMT_YUVJ420P) { // ALOGE("direct draw frame"); use_linked_frame = 1; av_frame_ref(opaque->linked_frame, frame); overlay_fill(overlay, opaque->linked_frame, opaque->planes); FFSWAP(Uint8*, overlay->pixels[1], overlay->pixels[2]); } else {
static int smvjpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const AVPixFmtDescriptor *desc; SMVJpegDecodeContext *s = avctx->priv_data; AVFrame* mjpeg_data = s->picture[0]; int i, cur_frame = 0, ret = 0; cur_frame = avpkt->pts % s->frames_per_jpeg; /* Are we at the start of a block? */ if (!cur_frame) { av_frame_unref(mjpeg_data); ret = avcodec_decode_video2(s->avctx, mjpeg_data, &s->mjpeg_data_size, avpkt); if (ret < 0) { s->mjpeg_data_size = 0; return ret; } } else if (!s->mjpeg_data_size) return AVERROR(EINVAL); desc = av_pix_fmt_desc_get(s->avctx->pix_fmt); av_assert0(desc); if (mjpeg_data->height % (s->frames_per_jpeg << desc->log2_chroma_h)) { av_log(avctx, AV_LOG_ERROR, "Invalid height\n"); return AVERROR_INVALIDDATA; } /*use the last lot... */ *data_size = s->mjpeg_data_size; avctx->pix_fmt = s->avctx->pix_fmt; /* We shouldn't get here if frames_per_jpeg <= 0 because this was rejected in init */ ret = ff_set_dimensions(avctx, mjpeg_data->width, mjpeg_data->height / s->frames_per_jpeg); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Failed to set dimensions\n"); return ret; } if (*data_size) { s->picture[1]->extended_data = NULL; s->picture[1]->width = avctx->width; s->picture[1]->height = avctx->height; s->picture[1]->format = avctx->pix_fmt; /* ff_init_buffer_info(avctx, &s->picture[1]); */ smv_img_pnt(s->picture[1]->data, mjpeg_data->data, mjpeg_data->linesize, avctx->pix_fmt, avctx->width, avctx->height, cur_frame); for (i = 0; i < AV_NUM_DATA_POINTERS; i++) s->picture[1]->linesize[i] = mjpeg_data->linesize[i]; ret = av_frame_ref(data, s->picture[1]); } return ret; }
int av_hwframe_map(AVFrame *dst, const AVFrame *src, int flags) { AVHWFramesContext *src_frames, *dst_frames; HWMapDescriptor *hwmap; int ret; if (src->hw_frames_ctx && dst->hw_frames_ctx) { src_frames = (AVHWFramesContext*)src->hw_frames_ctx->data; dst_frames = (AVHWFramesContext*)dst->hw_frames_ctx->data; if ((src_frames == dst_frames && src->format == dst_frames->sw_format && dst->format == dst_frames->format) || (src_frames->internal->source_frames && src_frames->internal->source_frames->data == (uint8_t*)dst_frames)) { // This is an unmap operation. We don't need to directly // do anything here other than fill in the original frame, // because the real unmap will be invoked when the last // reference to the mapped frame disappears. if (!src->buf[0]) { av_log(src_frames, AV_LOG_ERROR, "Invalid mapping " "found when attempting unmap.\n"); return AVERROR(EINVAL); } hwmap = (HWMapDescriptor*)src->buf[0]->data; av_frame_unref(dst); return av_frame_ref(dst, hwmap->source); } } if (src->hw_frames_ctx) { src_frames = (AVHWFramesContext*)src->hw_frames_ctx->data; if (src_frames->format == src->format && src_frames->internal->hw_type->map_from) { ret = src_frames->internal->hw_type->map_from(src_frames, dst, src, flags); if (ret != AVERROR(ENOSYS)) return ret; } } if (dst->hw_frames_ctx) { dst_frames = (AVHWFramesContext*)dst->hw_frames_ctx->data; if (dst_frames->format == dst->format && dst_frames->internal->hw_type->map_to) { ret = dst_frames->internal->hw_type->map_to(dst_frames, dst, src, flags); if (ret != AVERROR(ENOSYS)) return ret; } } return AVERROR(ENOSYS); }
int attribute_align_arg av_buffersrc_add_frame(AVFilterContext *ctx, AVFrame *frame) { BufferSourceContext *s = ctx->priv; AVFrame *copy; int refcounted, ret; if (!frame) { s->eof = 1; return 0; } else if (s->eof) return AVERROR(EINVAL); refcounted = !!frame->buf[0]; switch (ctx->outputs[0]->type) { case AVMEDIA_TYPE_VIDEO: CHECK_VIDEO_PARAM_CHANGE(ctx, s, frame->width, frame->height, frame->format); break; case AVMEDIA_TYPE_AUDIO: CHECK_AUDIO_PARAM_CHANGE(ctx, s, frame->sample_rate, frame->channel_layout, frame->format); break; default: return AVERROR(EINVAL); } if (!av_fifo_space(s->fifo) && (ret = av_fifo_realloc2(s->fifo, av_fifo_size(s->fifo) + sizeof(copy))) < 0) return ret; if (!(copy = av_frame_alloc())) return AVERROR(ENOMEM); if (refcounted) { av_frame_move_ref(copy, frame); } else { ret = av_frame_ref(copy, frame); if (ret < 0) { av_frame_free(©); return ret; } } if ((ret = av_fifo_generic_write(s->fifo, ©, sizeof(copy), NULL)) < 0) { if (refcounted) av_frame_move_ref(frame, copy); av_frame_free(©); return ret; } return 0; }
static AVFrame *do_vmaf(AVFilterContext *ctx, AVFrame *main, const AVFrame *ref) { LIBVMAFContext *s = ctx->priv; pthread_mutex_lock(&s->lock); while (s->frame_set != 0) { pthread_cond_wait(&s->cond, &s->lock); } av_frame_ref(s->gref, ref); av_frame_ref(s->gmain, main); s->frame_set = 1; pthread_cond_signal(&s->cond); pthread_mutex_unlock(&s->lock); return main; }
AVFrame *av_frame_clone(const AVFrame *src) { AVFrame *ret = av_frame_alloc(); if (!ret) return NULL; if (av_frame_ref(ret, src) < 0) av_frame_free(&ret); return ret; }
void MediaPictureImpl::copy(AVFrame* src, bool complete) { if (!src) VS_THROW(HumbleInvalidArgument("no src")); // release any memory we have av_frame_unref(mFrame); // and copy any data in. av_frame_ref(mFrame, src); RefPointer<Rational> timeBase = getTimeBase(); setTimeBase(timeBase.value()); mComplete=complete; }
static inline int copy_last_frame ( lwlibav_video_decode_handler_t *vdhp, AVFrame *picture ) { /* Copy the last decoded and output frame. */ assert( vdhp->last_frame_buffer ); if( picture == vdhp->last_frame_buffer ) return 0; av_frame_unref( picture ); return av_frame_ref( picture, vdhp->last_frame_buffer ); }
int ff_hwframe_map_create(AVBufferRef *hwframe_ref, AVFrame *dst, const AVFrame *src, void (*unmap)(AVHWFramesContext *ctx, HWMapDescriptor *hwmap), void *priv) { AVHWFramesContext *ctx = (AVHWFramesContext*)hwframe_ref->data; HWMapDescriptor *hwmap; int ret; hwmap = av_mallocz(sizeof(*hwmap)); if (!hwmap) { ret = AVERROR(ENOMEM); goto fail; } hwmap->source = av_frame_alloc(); if (!hwmap->source) { ret = AVERROR(ENOMEM); goto fail; } ret = av_frame_ref(hwmap->source, src); if (ret < 0) goto fail; hwmap->hw_frames_ctx = av_buffer_ref(hwframe_ref); if (!hwmap->hw_frames_ctx) { ret = AVERROR(ENOMEM); goto fail; } hwmap->unmap = unmap; hwmap->priv = priv; dst->buf[0] = av_buffer_create((uint8_t*)hwmap, sizeof(*hwmap), &ff_hwframe_unmap, ctx, 0); if (!dst->buf[0]) { ret = AVERROR(ENOMEM); goto fail; } return 0; fail: if (hwmap) { av_buffer_unref(&hwmap->hw_frames_ctx); av_frame_free(&hwmap->source); } av_free(hwmap); return ret; }
static inline int copy_field ( lw_log_handler_t *lhp, AVFrame *dst, AVFrame *src, int line_offset ) { /* Check if the destination is writable. */ if( av_frame_is_writable( dst ) == 0 ) { /* The destination is NOT writable, so allocate new buffers and copy the data. */ av_frame_unref( dst ); if( av_frame_ref( dst, src ) < 0 ) { if( lhp->show_log ) lhp->show_log( lhp, LW_LOG_ERROR, "Failed to reference a video frame.\n" ); return -1; } if( av_frame_make_writable( dst ) < 0 ) { if( lhp->show_log ) lhp->show_log( lhp, LW_LOG_ERROR, "Failed to make a video frame writable.\n" ); return -1; } /* For direct rendering, the destination can not know * whether the value at the address held by the opaque pointer is valid or not. * Anyway, the opaque pointer for direct rendering shall be set to NULL. */ dst->opaque = NULL; } else { /* The destination is writable. Copy field data from the source. */ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get( (enum AVPixelFormat)dst->format ); int number_of_planes = av_pix_fmt_count_planes( (enum AVPixelFormat)dst->format ); int height = MIN( dst->height, src->height ); for( int i = 0; i < number_of_planes; i++ ) { int r_shift = 1 + ((i == 1 || i == 2) ? desc->log2_chroma_h : 0); int field_height = (height >> r_shift) + (line_offset == 0 && (height & 1) ? 1 : 0); av_image_copy_plane( dst->data[i] + dst->linesize[i] * line_offset, 2 * dst->linesize[i], src->data[i] + src->linesize[i] * line_offset, 2 * src->linesize[i], MIN( dst->linesize[i], src->linesize[i] ), field_height ); } } /* Treat this frame as interlaced. */ dst->interlaced_frame = 1; return 0; }
int attribute_align_arg av_buffersrc_write_frame(AVFilterContext *ctx, const AVFrame *frame) { AVFrame *copy; int ret = 0; if (!(copy = av_frame_alloc())) return AVERROR(ENOMEM); ret = av_frame_ref(copy, frame); if (ret >= 0) ret = av_buffersrc_add_frame(ctx, copy); av_frame_free(©); return ret; }
static int do_vmaf(FFFrameSync *fs) { AVFilterContext *ctx = fs->parent; LIBVMAFContext *s = ctx->priv; AVFrame *master, *ref; int ret; ret = ff_framesync_dualinput_get(fs, &master, &ref); if (ret < 0) return ret; if (!ref) return ff_filter_frame(ctx->outputs[0], master); pthread_mutex_lock(&s->lock); while (s->frame_set && !s->error) { pthread_cond_wait(&s->cond, &s->lock); } if (s->error) { av_log(ctx, AV_LOG_ERROR, "libvmaf encountered an error, check log for details\n"); pthread_mutex_unlock(&s->lock); return AVERROR(EINVAL); } av_frame_ref(s->gref, ref); av_frame_ref(s->gmain, master); s->frame_set = 1; pthread_cond_signal(&s->cond); pthread_mutex_unlock(&s->lock); return ff_filter_frame(ctx->outputs[0], master); }
static int mss1_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { MSS1Context *ctx = avctx->priv_data; MSS12Context *c = &ctx->ctx; GetBitContext gb; ArithCoder acoder; int pal_changed = 0; int ret; if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0) return ret; arith_init(&acoder, &gb); if ((ret = ff_reget_buffer(avctx, ctx->pic)) < 0) return ret; c->pal_pic = ctx->pic->data[0] + ctx->pic->linesize[0] * (avctx->height - 1); c->pal_stride = -ctx->pic->linesize[0]; c->keyframe = !arith_get_bit(&acoder); if (c->keyframe) { c->corrupted = 0; ff_mss12_slicecontext_reset(&ctx->sc); pal_changed = decode_pal(c, &acoder); ctx->pic->key_frame = 1; ctx->pic->pict_type = AV_PICTURE_TYPE_I; } else { if (c->corrupted) return AVERROR_INVALIDDATA; ctx->pic->key_frame = 0; ctx->pic->pict_type = AV_PICTURE_TYPE_P; } c->corrupted = ff_mss12_decode_rect(&ctx->sc, &acoder, 0, 0, avctx->width, avctx->height); if (c->corrupted) return AVERROR_INVALIDDATA; memcpy(ctx->pic->data[1], c->pal, AVPALETTE_SIZE); ctx->pic->palette_has_changed = pal_changed; if ((ret = av_frame_ref(data, ctx->pic)) < 0) return ret; *got_frame = 1; /* always report that the buffer was completely consumed */ return avpkt->size; }
static int aasc_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; AascContext *s = avctx->priv_data; int compr, i, stride, ret; if (buf_size < 4) return AVERROR_INVALIDDATA; if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } compr = AV_RL32(buf); buf += 4; buf_size -= 4; switch (compr) { case 0: stride = (avctx->width * 3 + 3) & ~3; if (buf_size < stride * avctx->height) return AVERROR_INVALIDDATA; for (i = avctx->height - 1; i >= 0; i--) { memcpy(s->frame->data[0] + i * s->frame->linesize[0], buf, avctx->width * 3); buf += stride; } break; case 1: bytestream2_init(&s->gb, buf, buf_size); ff_msrle_decode(avctx, (AVPicture*)s->frame, 8, &s->gb); break; default: av_log(avctx, AV_LOG_ERROR, "Unknown compression type %d\n", compr); return AVERROR_INVALIDDATA; } *got_frame = 1; if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; /* report that the buffer was completely consumed */ return avpkt->size; }
static int mm_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; MmContext *s = avctx->priv_data; int type, res; if (buf_size < MM_PREAMBLE_SIZE) return AVERROR_INVALIDDATA; type = AV_RL16(&buf[0]); buf += MM_PREAMBLE_SIZE; buf_size -= MM_PREAMBLE_SIZE; bytestream2_init(&s->gb, buf, buf_size); if ((res = ff_reget_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return res; } switch(type) { case MM_TYPE_PALETTE : res = mm_decode_pal(s); return buf_size; case MM_TYPE_INTRA : res = mm_decode_intra(s, 0, 0); break; case MM_TYPE_INTRA_HH : res = mm_decode_intra(s, 1, 0); break; case MM_TYPE_INTRA_HHV : res = mm_decode_intra(s, 1, 1); break; case MM_TYPE_INTER : res = mm_decode_inter(s, 0, 0); break; case MM_TYPE_INTER_HH : res = mm_decode_inter(s, 1, 0); break; case MM_TYPE_INTER_HHV : res = mm_decode_inter(s, 1, 1); break; default: res = AVERROR_INVALIDDATA; break; } if (res < 0) return res; memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE); if ((res = av_frame_ref(data, &s->frame)) < 0) return res; *got_frame = 1; return buf_size; }
static inline int copy_frame ( lw_log_handler_t *lhp, AVFrame *dst, AVFrame *src ) { av_frame_unref( dst ); if( av_frame_ref( dst, src ) < 0 ) { if( lhp->show_log ) lhp->show_log( lhp, LW_LOG_ERROR, "Failed to reference a video frame.\n" ); return -1; } /* Treat this frame as interlaced. */ dst->interlaced_frame = 1; return 0; }
int FrameQueue::put(AVFrame *frame) { AVFrameList *frame1; int ret; frame1 = (AVFrameList *) av_malloc(sizeof(AVFrameList)); frame1->frame = av_frame_alloc(); if (!frame1 || !frame1->frame){ XLog::e(TAG ,"==>av_malloc failed.\n"); return AVERROR(ENOMEM); } if ( (ret = av_frame_ref(frame1->frame, frame) ) < 0) { //// copy frame data (only copy meta data .//TODO) av_free(frame1); XLog::e(TAG ,"==>av_frame_ref failed.\n"); return ret; } av_frame_unref(frame); //*(frame1->frame) = *frame; frame1->next = NULL; pthread_mutex_lock(&mutex); if (!last_frame) { first_frame = frame1; } else { last_frame->next = frame1; } last_frame = frame1; node_count ++; if(node_count > X_MIN_FRAME_VIDEO_Q_NODE_CNT){ // TODO notify_buffering_end(); } pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); return 0; }
static int sgirle_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { SGIRLEContext *s = avctx->priv_data; int ret; if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) return ret; ret = decode_sgirle8(avctx, s->frame->data[0], avpkt->data, avpkt->size, avctx->width, avctx->height, s->frame->linesize[0]); if (ret < 0) return ret; *got_frame = 1; if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; return avpkt->size; }
static int qtrle_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { QtrleEncContext * const s = avctx->priv_data; int ret; if ((ret = ff_alloc_packet2(avctx, pkt, s->max_buf_size, 0)) < 0) return ret; if (avctx->gop_size == 0 || (s->avctx->frame_number % avctx->gop_size) == 0) { /* I-Frame */ s->key_frame = 1; } else { /* P-Frame */ s->key_frame = 0; } pkt->size = encode_frame(s, pict, pkt->data); /* save the current frame */ av_frame_unref(s->previous_frame); ret = av_frame_ref(s->previous_frame, pict); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "cannot add reference\n"); return ret; } #if FF_API_CODED_FRAME FF_DISABLE_DEPRECATION_WARNINGS avctx->coded_frame->key_frame = s->key_frame; avctx->coded_frame->pict_type = s->key_frame ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; FF_ENABLE_DEPRECATION_WARNINGS #endif if (s->key_frame) pkt->flags |= AV_PKT_FLAG_KEY; *got_packet = 1; return 0; }
int attribute_align_arg av_buffersrc_add_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags) { AVFrame *copy = NULL; int ret = 0; if (frame && frame->channel_layout && av_get_channel_layout_nb_channels(frame->channel_layout) != av_frame_get_channels(frame)) { av_log(ctx, AV_LOG_ERROR, "Layout indicates a different number of channels than actually present\n"); return AVERROR(EINVAL); } if (!(flags & AV_BUFFERSRC_FLAG_KEEP_REF) || !frame) return av_buffersrc_add_frame_internal(ctx, frame, flags); if (!(copy = av_frame_alloc())) return AVERROR(ENOMEM); ret = av_frame_ref(copy, frame); if (ret >= 0) ret = av_buffersrc_add_frame_internal(ctx, copy, flags); av_frame_free(©); return ret; }
static int mjpegb_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; MJpegDecodeContext *s = avctx->priv_data; const uint8_t *buf_end, *buf_ptr; GetBitContext hgb; /* for the header */ uint32_t dqt_offs, dht_offs, sof_offs, sos_offs, second_field_offs; uint32_t field_size, sod_offs; int ret; buf_ptr = buf; buf_end = buf + buf_size; s->got_picture = 0; read_header: /* reset on every SOI */ s->restart_interval = 0; s->restart_count = 0; s->mjpb_skiptosod = 0; if (buf_end - buf_ptr >= 1 << 28) return AVERROR_INVALIDDATA; init_get_bits(&hgb, buf_ptr, /*buf_size*/(buf_end - buf_ptr)*8); skip_bits(&hgb, 32); /* reserved zeros */ if (get_bits_long(&hgb, 32) != MKBETAG('m','j','p','g')) { av_log(avctx, AV_LOG_WARNING, "not mjpeg-b (bad fourcc)\n"); return AVERROR_INVALIDDATA; } field_size = get_bits_long(&hgb, 32); /* field size */ av_log(avctx, AV_LOG_DEBUG, "field size: 0x%"PRIx32"\n", field_size); skip_bits(&hgb, 32); /* padded field size */ second_field_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "second_field_offs is %d and size is %d\n"); av_log(avctx, AV_LOG_DEBUG, "second field offs: 0x%"PRIx32"\n", second_field_offs); dqt_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "dqt is %d and size is %d\n"); av_log(avctx, AV_LOG_DEBUG, "dqt offs: 0x%"PRIx32"\n", dqt_offs); if (dqt_offs) { init_get_bits(&s->gb, buf_ptr+dqt_offs, (buf_end - (buf_ptr+dqt_offs))*8); s->start_code = DQT; ret = ff_mjpeg_decode_dqt(s); if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) return ret; } dht_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "dht is %d and size is %d\n"); av_log(avctx, AV_LOG_DEBUG, "dht offs: 0x%"PRIx32"\n", dht_offs); if (dht_offs) { init_get_bits(&s->gb, buf_ptr+dht_offs, (buf_end - (buf_ptr+dht_offs))*8); s->start_code = DHT; ff_mjpeg_decode_dht(s); } sof_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "sof is %d and size is %d\n"); av_log(avctx, AV_LOG_DEBUG, "sof offs: 0x%"PRIx32"\n", sof_offs); if (sof_offs) { init_get_bits(&s->gb, buf_ptr+sof_offs, (buf_end - (buf_ptr+sof_offs))*8); s->start_code = SOF0; if ((ret = ff_mjpeg_decode_sof(s)) < 0) return ret; } sos_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "sos is %d and size is %d\n"); av_log(avctx, AV_LOG_DEBUG, "sos offs: 0x%"PRIx32"\n", sos_offs); sod_offs = read_offs(avctx, &hgb, buf_end - buf_ptr, "sof is %d and size is %d\n"); av_log(avctx, AV_LOG_DEBUG, "sod offs: 0x%"PRIx32"\n", sod_offs); if (sos_offs) { init_get_bits(&s->gb, buf_ptr + sos_offs, 8 * FFMIN(field_size, buf_end - buf_ptr - sos_offs)); s->mjpb_skiptosod = (sod_offs - sos_offs - show_bits(&s->gb, 16)); s->start_code = SOS; ret = ff_mjpeg_decode_sos(s, NULL, 0, NULL); if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) return ret; } if (s->interlaced) { s->bottom_field ^= 1; /* if not bottom field, do not output image yet */ if (s->bottom_field != s->interlace_polarity && second_field_offs) { buf_ptr = buf + second_field_offs; goto read_header; } } //XXX FIXME factorize, this looks very similar to the EOI code if(!s->got_picture) { av_log(avctx, AV_LOG_WARNING, "no picture\n"); return buf_size; } if ((ret = av_frame_ref(data, s->picture_ptr)) < 0) return ret; *got_frame = 1; if (!s->lossless && avctx->debug & FF_DEBUG_QP) { av_log(avctx, AV_LOG_DEBUG, "QP: %d\n", FFMAX3(s->qscale[0], s->qscale[1], s->qscale[2])); } return buf_size; }
static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, void *data, int *got_frame, const uint8_t *buf, int buf_size) { /* Note, the only difference between the 15Bpp and 16Bpp */ /* Format is the pixel format, the packets are processed the same. */ FlicDecodeContext *s = avctx->priv_data; GetByteContext g2; int pixel_ptr; unsigned char palette_idx1; unsigned int frame_size; int num_chunks; unsigned int chunk_size; int chunk_type; int i, j, ret; int lines; int compressed_lines; signed short line_packets; int y_ptr; int byte_run; int pixel_skip; int pixel_countdown; unsigned char *pixels; int pixel; unsigned int pixel_limit; bytestream2_init(&g2, buf, buf_size); if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } pixels = s->frame->data[0]; pixel_limit = s->avctx->height * s->frame->linesize[0]; frame_size = bytestream2_get_le32(&g2); bytestream2_skip(&g2, 2); /* skip the magic number */ num_chunks = bytestream2_get_le16(&g2); bytestream2_skip(&g2, 8); /* skip padding */ frame_size -= 16; /* iterate through the chunks */ while ((frame_size > 0) && (num_chunks > 0)) { chunk_size = bytestream2_get_le32(&g2); chunk_type = bytestream2_get_le16(&g2); switch (chunk_type) { case FLI_256_COLOR: case FLI_COLOR: /* For some reason, it seems that non-palettized flics do * include one of these chunks in their first frame. * Why I do not know, it seems rather extraneous. */ ff_dlog(avctx, "Unexpected Palette chunk %d in non-palettized FLC\n", chunk_type); bytestream2_skip(&g2, chunk_size - 6); break; case FLI_DELTA: case FLI_DTA_LC: y_ptr = 0; compressed_lines = bytestream2_get_le16(&g2); while (compressed_lines > 0) { line_packets = bytestream2_get_le16(&g2); if (line_packets < 0) { line_packets = -line_packets; y_ptr += line_packets * s->frame->linesize[0]; } else { compressed_lines--; pixel_ptr = y_ptr; CHECK_PIXEL_PTR(0); pixel_countdown = s->avctx->width; for (i = 0; i < line_packets; i++) { /* account for the skip bytes */ pixel_skip = bytestream2_get_byte(&g2); pixel_ptr += (pixel_skip*2); /* Pixel is 2 bytes wide */ pixel_countdown -= pixel_skip; byte_run = sign_extend(bytestream2_get_byte(&g2), 8); if (byte_run < 0) { byte_run = -byte_run; pixel = bytestream2_get_le16(&g2); CHECK_PIXEL_PTR(2 * byte_run); for (j = 0; j < byte_run; j++, pixel_countdown -= 2) { *((signed short*)(&pixels[pixel_ptr])) = pixel; pixel_ptr += 2; } } else { CHECK_PIXEL_PTR(2 * byte_run); for (j = 0; j < byte_run; j++, pixel_countdown--) { *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2); pixel_ptr += 2; } } } y_ptr += s->frame->linesize[0]; } } break; case FLI_LC: av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-palettized FLC\n"); bytestream2_skip(&g2, chunk_size - 6); break; case FLI_BLACK: /* set the whole frame to 0x0000 which is black in both 15Bpp and 16Bpp modes. */ memset(pixels, 0x0000, s->frame->linesize[0] * s->avctx->height); break; case FLI_BRUN: y_ptr = 0; for (lines = 0; lines < s->avctx->height; lines++) { pixel_ptr = y_ptr; /* disregard the line packets; instead, iterate through all * pixels on a row */ bytestream2_skip(&g2, 1); pixel_countdown = (s->avctx->width * 2); while (pixel_countdown > 0) { byte_run = sign_extend(bytestream2_get_byte(&g2), 8); if (byte_run > 0) { palette_idx1 = bytestream2_get_byte(&g2); CHECK_PIXEL_PTR(byte_run); for (j = 0; j < byte_run; j++) { pixels[pixel_ptr++] = palette_idx1; pixel_countdown--; if (pixel_countdown < 0) av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) (linea%d)\n", pixel_countdown, lines); } } else { /* copy bytes if byte_run < 0 */ byte_run = -byte_run; CHECK_PIXEL_PTR(byte_run); for (j = 0; j < byte_run; j++) { palette_idx1 = bytestream2_get_byte(&g2); pixels[pixel_ptr++] = palette_idx1; pixel_countdown--; if (pixel_countdown < 0) av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n", pixel_countdown, lines); } } } /* Now FLX is strange, in that it is "byte" as opposed to "pixel" run length compressed. * This does not give us any good opportunity to perform word endian conversion * during decompression. So if it is required (i.e., this is not a LE target, we do * a second pass over the line here, swapping the bytes. */ #if HAVE_BIGENDIAN pixel_ptr = y_ptr; pixel_countdown = s->avctx->width; while (pixel_countdown > 0) { *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[pixel_ptr]); pixel_ptr += 2; } #endif y_ptr += s->frame->linesize[0]; } break; case FLI_DTA_BRUN: y_ptr = 0; for (lines = 0; lines < s->avctx->height; lines++) { pixel_ptr = y_ptr; /* disregard the line packets; instead, iterate through all * pixels on a row */ bytestream2_skip(&g2, 1); pixel_countdown = s->avctx->width; /* Width is in pixels, not bytes */ while (pixel_countdown > 0) { byte_run = sign_extend(bytestream2_get_byte(&g2), 8); if (byte_run > 0) { pixel = bytestream2_get_le16(&g2); CHECK_PIXEL_PTR(2 * byte_run); for (j = 0; j < byte_run; j++) { *((signed short*)(&pixels[pixel_ptr])) = pixel; pixel_ptr += 2; pixel_countdown--; if (pixel_countdown < 0) av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n", pixel_countdown); } } else { /* copy pixels if byte_run < 0 */ byte_run = -byte_run; CHECK_PIXEL_PTR(2 * byte_run); for (j = 0; j < byte_run; j++) { *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2); pixel_ptr += 2; pixel_countdown--; if (pixel_countdown < 0) av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n", pixel_countdown); } } } y_ptr += s->frame->linesize[0]; } break; case FLI_COPY: case FLI_DTA_COPY: /* copy the chunk (uncompressed frame) */ if (chunk_size - 6 > (unsigned int)(s->avctx->width * s->avctx->height)*2) { av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \ "bigger than image, skipping chunk\n", chunk_size - 6); bytestream2_skip(&g2, chunk_size - 6); } else { for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height; y_ptr += s->frame->linesize[0]) { pixel_countdown = s->avctx->width; pixel_ptr = 0; while (pixel_countdown > 0) { *((signed short*)(&pixels[y_ptr + pixel_ptr])) = bytestream2_get_le16(&g2); pixel_ptr += 2; pixel_countdown--; } } } break; case FLI_MINI: /* some sort of a thumbnail? disregard this chunk... */ bytestream2_skip(&g2, chunk_size - 6); break; default: av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type); break; } frame_size -= chunk_size; num_chunks--; } /* by the end of the chunk, the stream ptr should equal the frame * size (minus 1, possibly); if it doesn't, issue a warning */ if ((bytestream2_get_bytes_left(&g2) != 0) && (bytestream2_get_bytes_left(&g2) != 1)) av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \ "and final chunk ptr = %d\n", buf_size, bytestream2_tell(&g2)); if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; *got_frame = 1; return buf_size; }
static int flic_decode_frame_8BPP(AVCodecContext *avctx, void *data, int *got_frame, const uint8_t *buf, int buf_size) { FlicDecodeContext *s = avctx->priv_data; GetByteContext g2; int stream_ptr_after_color_chunk; int pixel_ptr; int palette_ptr; unsigned char palette_idx1; unsigned char palette_idx2; unsigned int frame_size; int num_chunks; unsigned int chunk_size; int chunk_type; int i, j, ret; int color_packets; int color_changes; int color_shift; unsigned char r, g, b; int lines; int compressed_lines; int starting_line; signed short line_packets; int y_ptr; int byte_run; int pixel_skip; int pixel_countdown; unsigned char *pixels; unsigned int pixel_limit; bytestream2_init(&g2, buf, buf_size); if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return ret; } pixels = s->frame->data[0]; pixel_limit = s->avctx->height * s->frame->linesize[0]; frame_size = bytestream2_get_le32(&g2); bytestream2_skip(&g2, 2); /* skip the magic number */ num_chunks = bytestream2_get_le16(&g2); bytestream2_skip(&g2, 8); /* skip padding */ frame_size -= 16; /* iterate through the chunks */ while ((frame_size > 0) && (num_chunks > 0)) { chunk_size = bytestream2_get_le32(&g2); chunk_type = bytestream2_get_le16(&g2); switch (chunk_type) { case FLI_256_COLOR: case FLI_COLOR: stream_ptr_after_color_chunk = bytestream2_tell(&g2) + chunk_size - 6; /* check special case: If this file is from the Magic Carpet * game and uses 6-bit colors even though it reports 256-color * chunks in a 0xAF12-type file (fli_type is set to 0xAF13 during * initialization) */ if ((chunk_type == FLI_256_COLOR) && (s->fli_type != FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE)) color_shift = 0; else color_shift = 2; /* set up the palette */ color_packets = bytestream2_get_le16(&g2); palette_ptr = 0; for (i = 0; i < color_packets; i++) { /* first byte is how many colors to skip */ palette_ptr += bytestream2_get_byte(&g2); /* next byte indicates how many entries to change */ color_changes = bytestream2_get_byte(&g2); /* if there are 0 color changes, there are actually 256 */ if (color_changes == 0) color_changes = 256; for (j = 0; j < color_changes; j++) { unsigned int entry; /* wrap around, for good measure */ if ((unsigned)palette_ptr >= 256) palette_ptr = 0; r = bytestream2_get_byte(&g2) << color_shift; g = bytestream2_get_byte(&g2) << color_shift; b = bytestream2_get_byte(&g2) << color_shift; entry = (r << 16) | (g << 8) | b; if (s->palette[palette_ptr] != entry) s->new_palette = 1; s->palette[palette_ptr++] = entry; } } /* color chunks sometimes have weird 16-bit alignment issues; * therefore, take the hardline approach and skip * to the value calculated w.r.t. the size specified by the color * chunk header */ if (stream_ptr_after_color_chunk - bytestream2_tell(&g2) > 0) bytestream2_skip(&g2, stream_ptr_after_color_chunk - bytestream2_tell(&g2)); break; case FLI_DELTA: y_ptr = 0; compressed_lines = bytestream2_get_le16(&g2); while (compressed_lines > 0) { line_packets = bytestream2_get_le16(&g2); if ((line_packets & 0xC000) == 0xC000) { // line skip opcode line_packets = -line_packets; y_ptr += line_packets * s->frame->linesize[0]; } else if ((line_packets & 0xC000) == 0x4000) { av_log(avctx, AV_LOG_ERROR, "Undefined opcode (%x) in DELTA_FLI\n", line_packets); } else if ((line_packets & 0xC000) == 0x8000) { // "last byte" opcode pixel_ptr= y_ptr + s->frame->linesize[0] - 1; CHECK_PIXEL_PTR(0); pixels[pixel_ptr] = line_packets & 0xff; } else { compressed_lines--; pixel_ptr = y_ptr; CHECK_PIXEL_PTR(0); pixel_countdown = s->avctx->width; for (i = 0; i < line_packets; i++) { /* account for the skip bytes */ pixel_skip = bytestream2_get_byte(&g2); pixel_ptr += pixel_skip; pixel_countdown -= pixel_skip; byte_run = sign_extend(bytestream2_get_byte(&g2), 8); if (byte_run < 0) { byte_run = -byte_run; palette_idx1 = bytestream2_get_byte(&g2); palette_idx2 = bytestream2_get_byte(&g2); CHECK_PIXEL_PTR(byte_run * 2); for (j = 0; j < byte_run; j++, pixel_countdown -= 2) { pixels[pixel_ptr++] = palette_idx1; pixels[pixel_ptr++] = palette_idx2; } } else { CHECK_PIXEL_PTR(byte_run * 2); for (j = 0; j < byte_run * 2; j++, pixel_countdown--) { pixels[pixel_ptr++] = bytestream2_get_byte(&g2); } } } y_ptr += s->frame->linesize[0]; } } break; case FLI_LC: /* line compressed */ starting_line = bytestream2_get_le16(&g2); y_ptr = 0; y_ptr += starting_line * s->frame->linesize[0]; compressed_lines = bytestream2_get_le16(&g2); while (compressed_lines > 0) { pixel_ptr = y_ptr; CHECK_PIXEL_PTR(0); pixel_countdown = s->avctx->width; line_packets = bytestream2_get_byte(&g2); if (line_packets > 0) { for (i = 0; i < line_packets; i++) { /* account for the skip bytes */ pixel_skip = bytestream2_get_byte(&g2); pixel_ptr += pixel_skip; pixel_countdown -= pixel_skip; byte_run = sign_extend(bytestream2_get_byte(&g2),8); if (byte_run > 0) { CHECK_PIXEL_PTR(byte_run); for (j = 0; j < byte_run; j++, pixel_countdown--) { pixels[pixel_ptr++] = bytestream2_get_byte(&g2); } } else if (byte_run < 0) { byte_run = -byte_run; palette_idx1 = bytestream2_get_byte(&g2); CHECK_PIXEL_PTR(byte_run); for (j = 0; j < byte_run; j++, pixel_countdown--) { pixels[pixel_ptr++] = palette_idx1; } } } } y_ptr += s->frame->linesize[0]; compressed_lines--; } break; case FLI_BLACK: /* set the whole frame to color 0 (which is usually black) */ memset(pixels, 0, s->frame->linesize[0] * s->avctx->height); break; case FLI_BRUN: /* Byte run compression: This chunk type only occurs in the first * FLI frame and it will update the entire frame. */ y_ptr = 0; for (lines = 0; lines < s->avctx->height; lines++) { pixel_ptr = y_ptr; /* disregard the line packets; instead, iterate through all * pixels on a row */ bytestream2_skip(&g2, 1); pixel_countdown = s->avctx->width; while (pixel_countdown > 0) { byte_run = sign_extend(bytestream2_get_byte(&g2), 8); if (!byte_run) { av_log(avctx, AV_LOG_ERROR, "Invalid byte run value.\n"); return AVERROR_INVALIDDATA; } if (byte_run > 0) { palette_idx1 = bytestream2_get_byte(&g2); CHECK_PIXEL_PTR(byte_run); for (j = 0; j < byte_run; j++) { pixels[pixel_ptr++] = palette_idx1; pixel_countdown--; if (pixel_countdown < 0) av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n", pixel_countdown, lines); } } else { /* copy bytes if byte_run < 0 */ byte_run = -byte_run; CHECK_PIXEL_PTR(byte_run); for (j = 0; j < byte_run; j++) { pixels[pixel_ptr++] = bytestream2_get_byte(&g2); pixel_countdown--; if (pixel_countdown < 0) av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n", pixel_countdown, lines); } } } y_ptr += s->frame->linesize[0]; } break; case FLI_COPY: /* copy the chunk (uncompressed frame) */ if (chunk_size - 6 > s->avctx->width * s->avctx->height) { av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \ "bigger than image, skipping chunk\n", chunk_size - 6); bytestream2_skip(&g2, chunk_size - 6); } else { for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height; y_ptr += s->frame->linesize[0]) { bytestream2_get_buffer(&g2, &pixels[y_ptr], s->avctx->width); } } break; case FLI_MINI: /* some sort of a thumbnail? disregard this chunk... */ bytestream2_skip(&g2, chunk_size - 6); break; default: av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type); break; } frame_size -= chunk_size; num_chunks--; } /* by the end of the chunk, the stream ptr should equal the frame * size (minus 1, possibly); if it doesn't, issue a warning */ if ((bytestream2_get_bytes_left(&g2) != 0) && (bytestream2_get_bytes_left(&g2) != 1)) av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \ "and final chunk ptr = %d\n", buf_size, buf_size - bytestream2_get_bytes_left(&g2)); /* make the palette available on the way out */ memcpy(s->frame->data[1], s->palette, AVPALETTE_SIZE); if (s->new_palette) { s->frame->palette_has_changed = 1; s->new_palette = 0; } if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; *got_frame = 1; return buf_size; }
static int qsv_decode(AVCodecContext *avctx, QSVContext *q, AVFrame *frame, int *got_frame, AVPacket *avpkt) { QSVFrame *out_frame; mfxFrameSurface1 *insurf; mfxFrameSurface1 *outsurf; mfxSyncPoint *sync; mfxBitstream bs = { { { 0 } } }; int ret; if (avpkt->size) { bs.Data = avpkt->data; bs.DataLength = avpkt->size; bs.MaxLength = bs.DataLength; bs.TimeStamp = avpkt->pts; } sync = av_mallocz(sizeof(*sync)); if (!sync) { av_freep(&sync); return AVERROR(ENOMEM); } do { ret = get_surface(avctx, q, &insurf); if (ret < 0) return ret; ret = MFXVideoDECODE_DecodeFrameAsync(q->session, avpkt->size ? &bs : NULL, insurf, &outsurf, sync); if (ret == MFX_WRN_DEVICE_BUSY) av_usleep(1); } while (ret == MFX_WRN_DEVICE_BUSY || ret == MFX_ERR_MORE_SURFACE); if (ret != MFX_ERR_NONE && ret != MFX_ERR_MORE_DATA && ret != MFX_WRN_VIDEO_PARAM_CHANGED && ret != MFX_ERR_MORE_SURFACE) { av_freep(&sync); return ff_qsv_print_error(avctx, ret, "Error during QSV decoding."); } /* make sure we do not enter an infinite loop if the SDK * did not consume any data and did not return anything */ if (!*sync && !bs.DataOffset) { ff_qsv_print_warning(avctx, ret, "A decode call did not consume any data"); bs.DataOffset = avpkt->size; } if (*sync) { QSVFrame *out_frame = find_frame(q, outsurf); if (!out_frame) { av_log(avctx, AV_LOG_ERROR, "The returned surface does not correspond to any frame\n"); av_freep(&sync); return AVERROR_BUG; } out_frame->queued = 1; av_fifo_generic_write(q->async_fifo, &out_frame, sizeof(out_frame), NULL); av_fifo_generic_write(q->async_fifo, &sync, sizeof(sync), NULL); } else { av_freep(&sync); } if (!av_fifo_space(q->async_fifo) || (!avpkt->size && av_fifo_size(q->async_fifo))) { AVFrame *src_frame; av_fifo_generic_read(q->async_fifo, &out_frame, sizeof(out_frame), NULL); av_fifo_generic_read(q->async_fifo, &sync, sizeof(sync), NULL); out_frame->queued = 0; do { ret = MFXVideoCORE_SyncOperation(q->session, *sync, 1000); } while (ret == MFX_WRN_IN_EXECUTION); av_freep(&sync); src_frame = out_frame->frame; ret = av_frame_ref(frame, src_frame); if (ret < 0) return ret; outsurf = &out_frame->surface; #if FF_API_PKT_PTS FF_DISABLE_DEPRECATION_WARNINGS frame->pkt_pts = outsurf->Data.TimeStamp; FF_ENABLE_DEPRECATION_WARNINGS #endif frame->pts = outsurf->Data.TimeStamp; frame->repeat_pict = outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_TRIPLING ? 4 : outsurf->Info.PicStruct & MFX_PICSTRUCT_FRAME_DOUBLING ? 2 : outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_REPEATED ? 1 : 0; frame->top_field_first = outsurf->Info.PicStruct & MFX_PICSTRUCT_FIELD_TFF; frame->interlaced_frame = !(outsurf->Info.PicStruct & MFX_PICSTRUCT_PROGRESSIVE); /* update the surface properties */ if (avctx->pix_fmt == AV_PIX_FMT_QSV) ((mfxFrameSurface1*)frame->data[3])->Info = outsurf->Info; *got_frame = 1; } return bs.DataOffset; }