static int dvvideo_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { uint8_t *buf = avpkt->data; int buf_size = avpkt->size; DVVideoContext *s = avctx->priv_data; const uint8_t* vsc_pack; int apt, is16_9, ret; const DVprofile *sys; sys = avpriv_dv_frame_profile2(avctx, s->sys, buf, buf_size); if (!sys || buf_size < sys->frame_size) { av_log(avctx, AV_LOG_ERROR, "could not find dv frame profile\n"); return -1; /* NOTE: we only accept several full frames */ } if (sys != s->sys) { ret = ff_dv_init_dynamic_tables(s, sys); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Error initializing the work tables.\n"); return ret; } s->sys = sys; } s->frame = data; s->frame->key_frame = 1; s->frame->pict_type = AV_PICTURE_TYPE_I; avctx->pix_fmt = s->sys->pix_fmt; avctx->time_base = s->sys->time_base; ret = ff_set_dimensions(avctx, s->sys->width, s->sys->height); if (ret < 0) return ret; /* Determine the codec's sample_aspect ratio from the packet */ vsc_pack = buf + 80*5 + 48 + 5; if ( *vsc_pack == dv_video_control ) { apt = buf[4] & 0x07; is16_9 = (vsc_pack && ((vsc_pack[2] & 0x07) == 0x02 || (!apt && (vsc_pack[2] & 0x07) == 0x07))); ff_set_sar(avctx, s->sys->sar[is16_9]); } if ((ret = ff_get_buffer(avctx, s->frame, 0)) < 0) return ret; s->frame->interlaced_frame = 1; s->frame->top_field_first = 0; /* Determine the codec's field order from the packet */ if ( *vsc_pack == dv_video_control ) { s->frame->top_field_first = !(vsc_pack[3] & 0x40); } s->buf = buf; avctx->execute(avctx, dv_decode_video_segment, s->work_chunks, NULL, dv_work_pool_size(s->sys), sizeof(DVwork_chunk)); emms_c(); /* return image */ *got_frame = 1; return s->sys->frame_size; }