doc/examples/extract_mvs: switch to new decoding API

This commit is contained in:
Matthieu Bouron 2017-04-03 15:25:09 +02:00
parent 6db36a0227
commit 82116bd8a4
1 changed files with 34 additions and 36 deletions

View File

@ -34,39 +34,46 @@ static AVFrame *frame = NULL;
static AVPacket pkt; static AVPacket pkt;
static int video_frame_count = 0; static int video_frame_count = 0;
static int decode_packet(int *got_frame, int cached) static int decode_packet(void)
{ {
int decoded = pkt.size;
*got_frame = 0;
if (pkt.stream_index == video_stream_idx) { if (pkt.stream_index == video_stream_idx) {
int ret = avcodec_decode_video2(video_dec_ctx, frame, got_frame, &pkt); int ret = avcodec_send_packet(video_dec_ctx, &pkt);
if (ret < 0) { if (ret < 0) {
fprintf(stderr, "Error decoding video frame (%s)\n", av_err2str(ret)); fprintf(stderr, "Error while sending a packet to the decoder: %s\n", av_err2str(ret));
return ret; return ret;
} }
if (*got_frame) { while (ret >= 0) {
int i; ret = avcodec_receive_frame(video_dec_ctx, frame);
AVFrameSideData *sd; if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
break;
} else if (ret < 0) {
fprintf(stderr, "Error while receiving a frame from the decoder: %s\n", av_err2str(ret));
return ret;
}
video_frame_count++; if (ret >= 0) {
sd = av_frame_get_side_data(frame, AV_FRAME_DATA_MOTION_VECTORS); int i;
if (sd) { AVFrameSideData *sd;
const AVMotionVector *mvs = (const AVMotionVector *)sd->data;
for (i = 0; i < sd->size / sizeof(*mvs); i++) { video_frame_count++;
const AVMotionVector *mv = &mvs[i]; sd = av_frame_get_side_data(frame, AV_FRAME_DATA_MOTION_VECTORS);
printf("%d,%2d,%2d,%2d,%4d,%4d,%4d,%4d,0x%"PRIx64"\n", if (sd) {
video_frame_count, mv->source, const AVMotionVector *mvs = (const AVMotionVector *)sd->data;
mv->w, mv->h, mv->src_x, mv->src_y, for (i = 0; i < sd->size / sizeof(*mvs); i++) {
mv->dst_x, mv->dst_y, mv->flags); const AVMotionVector *mv = &mvs[i];
printf("%d,%2d,%2d,%2d,%4d,%4d,%4d,%4d,0x%"PRIx64"\n",
video_frame_count, mv->source,
mv->w, mv->h, mv->src_x, mv->src_y,
mv->dst_x, mv->dst_y, mv->flags);
}
} }
av_frame_unref(frame);
} }
} }
} }
return decoded; return 0;
} }
static int open_codec_context(AVFormatContext *fmt_ctx, enum AVMediaType type) static int open_codec_context(AVFormatContext *fmt_ctx, enum AVMediaType type)
@ -116,7 +123,7 @@ static int open_codec_context(AVFormatContext *fmt_ctx, enum AVMediaType type)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int ret = 0, got_frame; int ret = 0;
if (argc != 2) { if (argc != 2) {
fprintf(stderr, "Usage: %s <video>\n", argv[0]); fprintf(stderr, "Usage: %s <video>\n", argv[0]);
@ -157,28 +164,19 @@ int main(int argc, char **argv)
/* initialize packet, set data to NULL, let the demuxer fill it */ /* initialize packet, set data to NULL, let the demuxer fill it */
av_init_packet(&pkt); av_init_packet(&pkt);
pkt.data = NULL;
pkt.size = 0;
/* read frames from the file */ /* read frames from the file */
while (av_read_frame(fmt_ctx, &pkt) >= 0) { while (av_read_frame(fmt_ctx, &pkt) >= 0) {
AVPacket orig_pkt = pkt; ret = decode_packet();
do { av_packet_unref(&pkt);
ret = decode_packet(&got_frame, 0); if (ret < 0)
if (ret < 0) break;
break;
pkt.data += ret;
pkt.size -= ret;
} while (pkt.size > 0);
av_packet_unref(&orig_pkt);
} }
/* flush cached frames */ /* flush cached frames */
pkt.data = NULL; pkt.data = NULL;
pkt.size = 0; pkt.size = 0;
do { decode_packet();
decode_packet(&got_frame, 1);
} while (got_frame);
end: end:
avcodec_free_context(&video_dec_ctx); avcodec_free_context(&video_dec_ctx);