#include "stdafx.h"
#define IS_INTERLACED(a) ((a)&MB_TYPE_INTERLACED)
#define IS_16X16(a) ((a)&MB_TYPE_16x16)
#define IS_16X8(a) ((a)&MB_TYPE_16x8)
#define IS_8X16(a) ((a)&MB_TYPE_8x16)
#define IS_8X8(a) ((a)&MB_TYPE_8x8)
#define USES_LIST(a, list) ((a) & ((MB_TYPE_P0L0|MB_TYPE_P1L0)<<(2*(list))))
void print_vector(FILE *fp1, int frame, int code, int x, int y, int dx, int dy)
{
fprintf(fp1,"%d %d %d %d %d %d\n", frame, code, x, y, dx, dy);
}
void printMVMatrix(FILE *fp2, int index, AVFrame *pict, AVCodecContext *ctx)
{
const int mb_width = (ctx->width + 15) / 16;
const int mb_height = (ctx->height + 15) / 16;
const int mb_stride = mb_width + 1;
const int mv_sample_log2 = 4 - pict->motion_subsample_log2;
const int mv_stride = (mb_width << mv_sample_log2) + (ctx->codec_id == CODEC_ID_H264 ? 0 : 1);
const int quarter_sample = (ctx->flags & CODEC_FLAG_QPEL) != 0;
const int shift = 1 + quarter_sample;
for (int mb_y = 0; mb_y < mb_height; mb_y++) {
for (int mb_x = 0; mb_x < mb_width; mb_x++) {
const int mb_index = mb_x + mb_y * mb_stride;
if (pict->motion_val) {
for (int type = 0; type < 3; type++) {
int direction = 0;
switch (type) {
case 0:
if (pict->pict_type != AV_PICTURE_TYPE_P)
continue;
direction = 0;
break;
case 1:
if (pict->pict_type != AV_PICTURE_TYPE_B)
continue;
direction = 0;
break;
case 2:
if (pict->pict_type != AV_PICTURE_TYPE_B)
continue;
direction = 1;
break;
}
if (!USES_LIST(pict->mb_type[mb_index], direction)) {
#define NO_MV 0
if (IS_8X8(pict->mb_type[mb_index])) {
print_vector(fp2, index, 0, mb_x, mb_y, NO_MV, NO_MV);
print_vector(fp2, index, 1, mb_x, mb_y, NO_MV, NO_MV);
print_vector(fp2, index, 2, mb_x, mb_y, NO_MV, NO_MV);
print_vector(fp2, index, 3, mb_x, mb_y, NO_MV, NO_MV);
} else if (IS_16X8(pict->mb_type[mb_index])) {
print_vector(fp2, index, 0, mb_x, mb_y, NO_MV, NO_MV);
print_vector(fp2, index, 1, mb_x, mb_y, NO_MV, NO_MV);
print_vector(fp2, index, 2, mb_x, mb_y, NO_MV, NO_MV);
print_vector(fp2, index, 3, mb_x, mb_y, NO_MV, NO_MV);
} else if (IS_8X16(pict->mb_type[mb_index])) {
print_vector(fp2, index, 0, mb_x, mb_y, NO_MV, NO_MV);
print_vector(fp2, index, 1, mb_x, mb_y, NO_MV, NO_MV);
print_vector(fp2, index, 2, mb_x, mb_y, NO_MV, NO_MV);
print_vector(fp2, index, 3, mb_x, mb_y, NO_MV, NO_MV);
} else {
print_vector(fp2, index, 0, mb_x, mb_y, NO_MV, NO_MV);
print_vector(fp2, index, 1, mb_x, mb_y, NO_MV, NO_MV);
print_vector(fp2, index, 2, mb_x, mb_y, NO_MV, NO_MV);
print_vector(fp2, index, 3, mb_x, mb_y, NO_MV, NO_MV);
}
#undef NO_MV
continue;
}
if (IS_8X8(pict->mb_type[mb_index])) {
for (int i = 0; i < 4; i++) {
int xy = (mb_x*2 + (i&1) + (mb_y*2 + (i>>1))*mv_stride) << (mv_sample_log2-1);
int dx = (pict->motion_val[direction][xy][0]>>shift);
int dy = (pict->motion_val[direction][xy][1]>>shift);
print_vector(fp2, index, i, mb_x, mb_y, dx, dy);
}
} else if (IS_16X8(pict->mb_type[mb_index])) {
for (int i = 0; i < 2; i++) {
int xy = (mb_x*2 + (mb_y*2 + i)*mv_stride) << (mv_sample_log2-1);
int dx = (pict->motion_val[direction][xy][0]>>shift);
int dy = (pict->motion_val[direction][xy][1]>>shift);
if (IS_INTERLACED(pict->mb_type[mb_index]))
dy *= 2;
print_vector(fp2, index, i*2, mb_x, mb_y, dx, dy);
print_vector(fp2, index, i*2+1, mb_x, mb_y, dx, dy);
}
} else if (IS_8X16(pict->mb_type[mb_index])) {
for (int i = 0; i < 2; i++) {
int xy = (mb_x*2 + i + mb_y*2*mv_stride) << (mv_sample_log2-1);
int dx = (pict->motion_val[direction][xy][0]>>shift);
int dy = (pict->motion_val[direction][xy][1]>>shift);
if (IS_INTERLACED(pict->mb_type[mb_index]))
dy *= 2;
print_vector(fp2, index, i, mb_x, mb_y, dx, dy);
print_vector(fp2, index, i+2, mb_x, mb_y, dx, dy);
}
} else {
int xy = (mb_x + mb_y*mv_stride) << mv_sample_log2;
int dx = (pict->motion_val[direction][xy][0]>>shift);
int dy = (pict->motion_val[direction][xy][1]>>shift);
print_vector(fp2, index, 0, mb_x, mb_y, dx, dy);
print_vector(fp2, index, 1, mb_x, mb_y, dx, dy);
print_vector(fp2, index, 2, mb_x, mb_y, dx, dy);
print_vector(fp2, index, 3, mb_x, mb_y, dx, dy);
}
}
}
}
}
}
int _tmain(int argc, _TCHAR* argv[])
{
AVFormatContext *pFormatCtx;
int i, videoindex;
int q_number;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
FILE *fp;
for (q_number = 1; q_number < 2; q_number++){
int gindex=0;
char filepath[]="";
char querynumber[5];
itoa(q_number, querynumber, 10);
strcat(filepath, querynumber);
strcat(filepath, ".avi");
char motionname[] = "WZM";
strcat(motionname, querynumber);
strcat(motionname, ".txt");
fp = fopen(motionname, "w");
av_register_all();
avformat_network_init();
pFormatCtx = avformat_alloc_context();
if(avformat_open_input(&pFormatCtx,filepath,NULL,NULL)!=0){
printf("无法打开文件\n");
return -1;
}
if(av_find_stream_info(pFormatCtx)<0)
{
printf("Couldn't find stream information.\n");
return -1;
}
videoindex=-1;
for(i=0; inb_streams; i++)
if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
{
videoindex=i;
break;
}
if(videoindex==-1)
{
printf("Didn't find a video stream.\n");
return -1;
}
pCodecCtx=pFormatCtx->streams[videoindex]->codec;
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL)
{
printf("Codec not found.\n");
return -1;
}
if(avcodec_open(pCodecCtx, pCodec)<0)
{
printf("Could not open codec.\n");
return -1;
}
AVFrame *pFrame,*pFrameYUV;
pFrame=avcodec_alloc_frame();
pFrameYUV=avcodec_alloc_frame();
uint8_t *out_buffer;
out_buffer=new uint8_t[avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height)];
avpicture_fill((AVPicture *)pFrameYUV, out_buffer, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
//------------SDL----------------
/* if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
printf( "Could not initialize SDL - %s\n", SDL_GetError());
exit(1);
}
SDL_Surface *screen;
screen = SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->height, 0, 0);
if(!screen) { printf("SDL: could not set video mode - exiting\n");
exit(1);
}
SDL_Overlay *bmp;
bmp = SDL_CreateYUVOverlay(pCodecCtx->width, pCodecCtx->height,SDL_YV12_OVERLAY, screen);
SDL_Rect rect;*/
//---------------
int ret, got_picture;
static struct SwsContext *img_convert_ctx;
int y_size = pCodecCtx->width * pCodecCtx->height;
AVPacket *packet=(AVPacket *)malloc(sizeof(AVPacket));
av_new_packet(packet, y_size);
//输出一下信息-----------------------------
printf("文件信息-----------------------------------------\n");
av_dump_format(pFormatCtx,0,filepath,0);
printf("-------------------------------------------------\n");
//------------------------------
while(av_read_frame(pFormatCtx, packet)>=0)
{
if(packet->stream_index==videoindex)
{
ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
gindex++;
if(ret < 0)
{
printf("解码错误\n");
return -1;
}
if(got_picture)
{
printMVMatrix(fp, gindex, pFrame, pCodecCtx);
}
}
av_free_packet(packet);
}
fclose(fp);
delete[] out_buffer;
av_free(pFrameYUV);
avcodec_close(pCodecCtx);
avformat_close_input(&pFormatCtx);
}
return 0;
}