基于ffmpeg SDK build by ffmpepv2.4.3
闲言少述,直接上代码
/*
* \File
* yuv2h264.c
* \Desc
* 输入YUV420文件,编码生成h.264的文件
* \Author
* Hank
*/
-
#include <math.h>
-
-
-
#include <libavutil/opt.h>
-
#include <libavcodec/avcodec.h>
-
#include <libavutil/channel_layout.h>
-
#include <libavutil/common.h>
-
#include <libavutil/imgutils.h>
-
#include <libavutil/mathematics.h>
-
#include <libavutil/samplefmt.h>
-
-
-
#define INBUF_SIZE 4096
-
#define AUDIO_INBUF_SIZE 20480
-
#define AUDIO_REFILL_THRESH 4096
-
-
-
/*
-
* Video encoding example
-
*/
-
static void video_encode(const char *inputfilename, const char *outputfilename, int codec_id)
-
{
-
AVCodec *codec;
-
AVCodecContext *c= NULL;
-
int i, ret, got_output;
-
int in_size, picture_size;
-
uint8_t *picture_buf;
-
FILE *f_in, *f_out;
-
AVFrame *frame;
-
AVPacket pkt;
-
uint8_t endcode[] = { 0, 0, 1, 0xb7 };
-
-
-
printf("Encode video file %s\n", outputfilename);
-
-
-
/* find the mpeg1 video encoder */
-
codec = avcodec_find_encoder(codec_id);
-
if (!codec) {
-
fprintf(stderr, "Codec not found\n");
-
exit(1);
-
}
-
-
-
c = avcodec_alloc_context3(codec);
-
if (!c) {
-
fprintf(stderr, "Could not allocate video codec context\n");
-
exit(1);
-
}
-
-
-
/* put sample parameters */
-
c->bit_rate = 400000;
-
/* resolution must be a multiple of two */
-
c->width = 352;
-
c->height = 288;
-
/* frames per second */
-
c->time_base = (AVRational){1,25};
-
/* emit one intra frame every ten frames
-
* check frame pict_type before passing frame
-
* to encoder, if frame->pict_type is AV_PICTURE_TYPE_I
-
* then gop_size is ignored and the output of encoder
-
* will always be I frame irrespective to gop_size
-
*/
-
c->gop_size = 10;
-
c->max_b_frames = 1;
-
c->pix_fmt = AV_PIX_FMT_YUV420P;
-
-
-
if (codec_id == AV_CODEC_ID_H264)
-
av_opt_set(c->priv_data, "preset", "slow", 0);
-
-
-
/* open it */
-
if (avcodec_open2(c, codec, NULL) < 0) {
-
fprintf(stderr, "Could not open codec\n");
-
exit(1);
-
}
-
-
-
f_in = fopen(inputfilename, "rb+");
-
if (!f_in){
-
fprintf(stderr, "Could not open %s\n", inputfilename);
-
exit(1);
-
}
-
-
-
f_out = fopen(outputfilename, "wb");
-
if (!f_out) {
-
fprintf(stderr, "Could not open %s\n", outputfilename);
-
exit(1);
-
}
-
-
-
frame = av_frame_alloc();
-
if (!frame) {
-
fprintf(stderr, "Could not allocate video frame\n");
-
exit(1);
-
}
-
frame->format = c->pix_fmt;
-
frame->width = c->width;
-
frame->height = c->height;
-
frame->linesize[0] = c->width;
-
frame->linesize[1] = c->width / 2;
-
frame->linesize[2] = c->width / 2;
-
-
-
/* the image can be allocated by any means and av_image_alloc() is
-
* just the most convenient way if av_malloc() is to be used */
-
ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height,
-
c->pix_fmt, 12);
-
if (ret < 0) {
-
fprintf(stderr, "Could not allocate raw picture buffer\n");
-
exit(1);
-
}
-
picture_size = c->width * c->height;
-
picture_buf = (uint8_t *)malloc((picture_size * 3) / 2); //size for YUV420
-
frame->data[0] = picture_buf;
-
frame->data[1] = frame->data[0] + picture_size;
-
frame->data[2] = frame->data[1] + picture_size / 4;
-
-
-
/* encode 1 second of video */
-
for (;;) {
-
av_init_packet(&pkt);
-
pkt.data = NULL; // packet data will be allocated by the encoder
-
pkt.size = 0;
-
-
-
fflush(stdout);
-
-
-
-
-
/* prepare a dummy image */
-
memset(picture_buf, 0, sizeof(char)*(picture_size*3)/2);
-
in_size = fread(picture_buf, sizeof(char), (picture_size *3)/2, f_in);
-
-
-
/* End of the input file */
-
if (in_size != picture_size*3/2)
-
break;
-
-
-
av_log(NULL, AV_LOG_DEBUG, "Read %d bytes from inputfile\n", in_size);
-
frame->data[0] = picture_buf;
-
frame->data[1] = frame->data[0] + picture_size;
-
frame->data[2] = frame->data[1] + picture_size / 4;
-
-
-
frame->pts = i++;
-
-
-
/* encode the image */
-
ret = avcodec_encode_video2(c, &pkt, frame, &got_output);
-
if (ret < 0) {
-
fprintf(stderr, "Error encoding frame\n");
-
exit(1);
-
}
-
-
-
if (got_output) {
-
printf("Write frame %3d (size=%5d)\n", i, pkt.size);
-
fwrite(pkt.data, 1, pkt.size, f_out);
-
-
-
av_free_packet(&pkt);
-
}
-
}
-
-
-
/* get the delayed frames */
-
for (got_output = 1; got_output; i++) {
-
fflush(stdout);
-
-
-
ret = avcodec_encode_video2(c, &pkt, NULL, &got_output);
-
if (ret < 0) {
-
fprintf(stderr, "Error encoding frame\n");
-
exit(1);
-
}
-
if (got_output) {
-
printf("Write frame %3d (size=%5d)\n", i, pkt.size);
-
fwrite(pkt.data, 1, pkt.size, f_out);
-
av_free_packet(&pkt);
-
}
-
}
-
-
-
/* add sequence end code to have a real mpeg file */
-
fwrite(endcode, 1, sizeof(endcode), f_out);
-
fclose(f_in);
-
fclose(f_out);
-
-
-
avcodec_close(c);
-
av_free(c);
-
av_freep(&frame->data[0]);
-
av_frame_free(&frame);
-
printf("\n");
-
}
-
-
-
-
-
int main(int argc, char **argv)
-
{
-
/* register all the codecs */
-
avcodec_register_all();
-
-
-
if (argc != 3) {
-
av_log(NULL, AV_LOG_ERROR, "Usage: %s \n", argv[0]);
-
return 1;
-
}
-
-
-
video_encode(argv[1] ,argv[2], AV_CODEC_ID_H264);
-
-
-
return 0;
-
}
2. 动态链接库的编译命令
编译命令:
$ gcc yuv2h264.c -g -Wall -o yuv2h264 -I/opt/PJT_transcode_in_jdh/ffmpeg/install/include
-L/opt/PJT_transcode_in_jdh/ffmpeg/install/lib -lavformat -lavdevice -lavcodec -lavutil -lavfilter
-pthread -ldl -lswscale -lbz2 -lfaac -lx264 -lz -lm
3. 静态链接库的编码命令
$ gcc yuv2h264.c -static -g -Wall -o yuv2h264 -I/opt/PJT_transcode_in_jdh/ffmpeg/install/include
-L/opt/PJT_transcode_in_jdh/ffmpeg/install/lib -lavformat -lavdevice -lavcodec -lavutil -lavfilter
-pthread -ldl -lswscale -lbz2 -lfaac -lx264 -lz -lm
/opt/PJT_transcode_in_jdh/ffmpeg/install/lib/libavcodec.a(opusdec.o): In function `opus_decode_flush':
/opt/PJT_transcode_in_jdh/ffmpeg/ffmpeg-2.4.3/libavcodec/opusdec.c:557: undefined reference to `swr_close'
/opt/PJT_transcode_in_jdh/ffmpeg/install/lib/libavcodec.a(opusdec.o): In function `opus_decode_close':
/opt/PJT_transcode_in_jdh/ffmpeg/ffmpeg-2.4.3/libavcodec/opusdec.c:579: undefined reference to `swr_free'
/opt/PJT_transcode_in_jdh/ffmpeg/install/lib/libavcodec.a(opusdec.o): In function `opus_decode_init':
/opt/PJT_transcode_in_jdh/ffmpeg/ffmpeg-2.4.3/libavcodec/opusdec.c:629: undefined reference to `swr_alloc'
/opt/PJT_transcode_in_jdh/ffmpeg/install/lib/libavcodec.a(opusdec.o): In function `opus_decode_subpacket':
/opt/PJT_transcode_in_jdh/ffmpeg/ffmpeg-2.4.3/libavcodec/opusdec.c:376: undefined reference to `swr_is_initialized'
/opt/PJT_transcode_in_jdh/ffmpeg/install/lib/libavcodec.a(opusdec.o): In function `opus_decode_frame':
/opt/PJT_transcode_in_jdh/ffmpeg/ffmpeg-2.4.3/libavcodec/opusdec.c:222: undefined reference to `swr_is_initialized'
/opt/PJT_transcode_in_jdh/ffmpeg/install/lib/libavcodec.a(opusdec.o): In function `opus_init_resample':
/opt/PJT_transcode_in_jdh/ffmpeg/ffmpeg-2.4.3/libavcodec/opusdec.c:163: undefined reference to `swr_init'
/opt/PJT_transcode_in_jdh/ffmpeg/ffmpeg-2.4.3/libavcodec/opusdec.c:169: undefined reference to `swr_convert'
/opt/PJT_transcode_in_jdh/ffmpeg/install/lib/libavcodec.a(opusdec.o): In function `opus_decode_frame':
/opt/PJT_transcode_in_jdh/ffmpeg/ffmpeg-2.4.3/libavcodec/opusdec.c:236: undefined reference to `swr_convert'
/opt/PJT_transcode_in_jdh/ffmpeg/install/lib/libavcodec.a(opusdec.o): In function `opus_flush_resample':
/opt/PJT_transcode_in_jdh/ffmpeg/ffmpeg-2.4.3/libavcodec/opusdec.c:117: undefined reference to `swr_convert'
/opt/PJT_transcode_in_jdh/ffmpeg/install/lib/libavcodec.a(opusdec.o): In function `opus_decode_subpacket':
/opt/PJT_transcode_in_jdh/ffmpeg/ffmpeg-2.4.3/libavcodec/opusdec.c:408: undefined reference to `swr_close'
/opt/PJT_transcode_in_jdh/ffmpeg/install/lib/libavutil.a(time.o): In function `av_gettime_relative':
/opt/PJT_transcode_in_jdh/ffmpeg/ffmpeg-2.4.3/libavutil/time.c:60: undefined reference to `clock_gettime'
collect2: ld returned 1 exit status
需要添加libswresampe库:
$ gcc yuv2h264.c -static -g -Wall -o yuv2h264 -I/opt/PJT_transcode_in_jdh/ffmpeg/install/include
-L/opt/PJT_transcode_in_jdh/ffmpeg/install/lib -lavformat -lavdevice -lavcodec -lavutil -lavfilter
-pthread -ldl -lswscale -lbz2 -lfaac -lx264 -lz -lm -lswresample
/opt/PJT_transcode_in_jdh/ffmpeg/install/lib/libavutil.a(time.o): In function `av_gettime_relative':
/opt/PJT_transcode_in_jdh/ffmpeg/ffmpeg-2.4.3/libavutil/time.c:60: undefined reference to `clock_gettime'
collect2: ld returned 1 exit status
需要添加lrt
$ gcc yuv2h264.c -static -g -Wall -o yuv2h264 -I/opt/PJT_transcode_in_jdh/ffmpeg/install/include
-L/opt/PJT_transcode_in_jdh/ffmpeg/install/lib -lavformat -lavdevice -lavcodec -lavutil -lavfilter
-pthread -ldl -lswscale -lbz2 -lfaac -lx264 -lz -lm -lswresample -lrt
阅读(843) | 评论(0) | 转发(0) |