MP4转YUV
- 代码如下
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libavformat/avfrmat.h>
const char* SRC_FILE = "1.mp4";
int main()
{
FILE *yuv_file = fopen("yuv_file","ab");
if (!yuv_file)
return 0;
av_register_all();
AVFormatContext* pFormat = NULL;
if (avformat_open_input(&pFormat, SRC_FILE, NULL, NULL) < 0)
{
return 0;
}
AVCodecContext* video_dec_ctx = NULL;
AVCodec* video_dec = NULL;
if (avformat_find_stream_info(pFormat, NULL) < 0)
{
return 0;
}
av_dump_format(pFormat,0,SRC_FILE,0);
video_dec_ctx = pFormat->streams[0]->codec;
video_dec = avcodec_find_decoder(video_dec_ctx->codec_id);
if (avcodec_open2(video_dec_ctx, video_dec, NULL) < 0)
{
return 0;
}
AVPacket *pkt = new AVPacket();
av_init_packet(pkt);
while (1)
{
if (av_read_frame(pFormat, pkt) < 0)
{
fclose(yuv_file);
delete pkt;
return 0;
}
if (pkt->stream_index == 0)
{
// AVFrame *pFrame = avcodec_alloc_frame();
AVFrame *pFrame = av_frame_alloc();
int got_picture = 0,ret = 0;
ret = avcodec_decode_video2(video_dec_ctx, pFrame, &got_picture, pkt);
if (ret < 0)
{
delete pkt;
return 0;
}
if (got_picture)
{
char* buf = new char[video_dec_ctx->height * video_dec_ctx->width * 3 / 2];
memset(buf, 0, video_dec_ctx->height * video_dec_ctx->width * 3 / 2);
int height = video_dec_ctx->height;
int width = video_dec_ctx->width;
printf("decode video ok\n");
int a = 0, i;
for (i = 0; i<height; i++)
{
memcpy(buf + a, pFrame->data[0] + i * pFrame->linesize[0], width);
a += width;
}
for (i = 0; i<height / 2; i++)
{
memcpy(buf + a, pFrame->data[1] + i * pFrame->linesize[1], width / 2);
a += width / 2;
}
for (i = 0; i<height / 2; i++)
{
memcpy(buf + a, pFrame->data[2] + i * pFrame->linesize[2], width / 2);
a += width / 2;
}
fwrite(buf, 1, video_dec_ctx->height * video_dec_ctx->width * 3 / 2, yuv_file);
buf = NULL;
}
avcodec_free_frame(&pFrame);
}
}
return 0;
}
编译出现如下:
- 解决:
在libavutil/common.h中添加
#ifndef UINT64_C(val)
#define UINT64_C(val) val##ULL
#endif
将 avcodec_alloc_frame() 替换为 av_frame_alloc()。
使用makefile工具
makefile如下:
#!/bin/bash
CC=gcc
CXX=g++
TARGET=mp4_TO_YUV
OBJS=mp4_TO_YUV.o
LDFLAGS+=-lavformat -lavcdec -lavfiler -lavdevice -lswscale -lavutil -ldl -lz -lpthread -lswresample
%.o: %.cpp
$(CXX) $(LDFAGS) -c $< -o aaa@qq.com
SOURCE = mp4_TO_YUV.cpp
$(TARGET):$(OBJS)
$(CXX) $(OBJS) $(LDFLAGS) -o $(TARGET)
clean:
rm -rf *.o mp4_TO_YUV
生成成功执行make
运行如下:
生成成功
执行后:
[aaa@qq.com test]# ./mp4_TO_YUV
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from ‘1.mp4’:
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: mp42isom
creation_time : 2016-09-10T01:13:22.000000Z
Duration: 00:04:19.18, start: 0.000000, bitrate: 2770 kb/s
Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 96000 Hz, stereo, fltp, 127 kb/s (default)
Metadata:
creation_time : 2016-09-10T01:13:22.000000Z
handler_name : GPAC ISO Audio Handler
Stream #0:1(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 1280x576 [SAR 1:1 DAR 20:9], 2635 kb/s, 25 fps, 25 tbr, 30k tbn, 20000k tbc (default)
Metadata:
creation_time : 2016-09-10T01:13:24.000000Z
handler_name : GPAC ISO Video Handler
[aac @ 0x269c700] Invalid media type for video
上一篇: [Multimedia]ffplay
下一篇: webm转mp4 python实现
推荐阅读