| @@ -34,39 +34,46 @@ static AVFrame *frame = NULL; | |||
| static AVPacket pkt; | |||
| 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) { | |||
| int ret = avcodec_decode_video2(video_dec_ctx, frame, got_frame, &pkt); | |||
| int ret = avcodec_send_packet(video_dec_ctx, &pkt); | |||
| 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; | |||
| } | |||
| if (*got_frame) { | |||
| int i; | |||
| AVFrameSideData *sd; | |||
| video_frame_count++; | |||
| sd = av_frame_get_side_data(frame, AV_FRAME_DATA_MOTION_VECTORS); | |||
| if (sd) { | |||
| const AVMotionVector *mvs = (const AVMotionVector *)sd->data; | |||
| for (i = 0; i < sd->size / sizeof(*mvs); i++) { | |||
| 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); | |||
| while (ret >= 0) { | |||
| ret = avcodec_receive_frame(video_dec_ctx, frame); | |||
| 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; | |||
| } | |||
| if (ret >= 0) { | |||
| int i; | |||
| AVFrameSideData *sd; | |||
| video_frame_count++; | |||
| sd = av_frame_get_side_data(frame, AV_FRAME_DATA_MOTION_VECTORS); | |||
| if (sd) { | |||
| const AVMotionVector *mvs = (const AVMotionVector *)sd->data; | |||
| for (i = 0; i < sd->size / sizeof(*mvs); i++) { | |||
| 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) | |||
| @@ -116,7 +123,7 @@ static int open_codec_context(AVFormatContext *fmt_ctx, enum AVMediaType type) | |||
| int main(int argc, char **argv) | |||
| { | |||
| int ret = 0, got_frame; | |||
| int ret = 0; | |||
| if (argc != 2) { | |||
| 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 */ | |||
| av_init_packet(&pkt); | |||
| pkt.data = NULL; | |||
| pkt.size = 0; | |||
| /* read frames from the file */ | |||
| while (av_read_frame(fmt_ctx, &pkt) >= 0) { | |||
| AVPacket orig_pkt = pkt; | |||
| do { | |||
| ret = decode_packet(&got_frame, 0); | |||
| if (ret < 0) | |||
| break; | |||
| pkt.data += ret; | |||
| pkt.size -= ret; | |||
| } while (pkt.size > 0); | |||
| av_packet_unref(&orig_pkt); | |||
| ret = decode_packet(); | |||
| av_packet_unref(&pkt); | |||
| if (ret < 0) | |||
| break; | |||
| } | |||
| /* flush cached frames */ | |||
| pkt.data = NULL; | |||
| pkt.size = 0; | |||
| do { | |||
| decode_packet(&got_frame, 1); | |||
| } while (got_frame); | |||
| decode_packet(); | |||
| end: | |||
| avcodec_free_context(&video_dec_ctx); | |||