Using ffmpeg in your own MSVC projects
1. download dev build with headers and libs from http://ffmpeg.zeranoe.com/builds/
2. also download shared build because we will need those dll during run-time
3. make headers and libs visible to VC projects
4. add the following defines:
5. some functions that use newer C features are not supported by MS Visual C++ 2012, like the following function call in log_packet(). These are not critical and can be commented out.
printf("pts:%s pts_time:%s dts:%s dts_time:%s duration:%s duration_time:%s stream_index:%d\n",
buf1, av_ts2timestr(pkt->pts, time_base),
buf2, av_ts2timestr(pkt->dts, time_base),
buf3, av_ts2timestr(pkt->duration, time_base),
pkt->stream_index);
6. some ffmpeg code directly assigned structure values which also failed in MSVC. the workaround is that we define a temporary variable, and then assign values for each field, and then do the copy.
AVRational tmp;
tmp.den = 1; tmp.num = c->sample_rate;
ost->st->time_base = tmp;
7. remember to always call av_register_all(); otherwise, codec is not found.
8. in doc/example directory, check example code muxing. c for how to output video/audio samples with a container such as AVI.
9. a complete working code that generates MPEG4 AVI based on muxing.c example code is shown below:
OutputStream video_st = { 0 }, audio_st = { 0 };
char filename[] = "zz.avi";
AVOutputFormat *fmt;
AVFormatContext *oc;
AVCodec *audio_codec, *video_codec;
int ret;
int have_video = 0, have_audio = 0;
int encode_video = 0, encode_audio = 0;
AVDictionary *opt = NULL;
av_register_all();
avformat_alloc_output_context2(&oc, NULL, NULL, filename);
if (!oc) {
printf("Could not deduce output format from file extension.\n");
exit(1);
}
fmt = oc->oformat;
if (fmt->video_codec != AV_CODEC_ID_NONE) {
add_stream(&video_st, oc, &video_codec, fmt->video_codec);
have_video = 1;
encode_video = 1;
}
if (have_video)
open_video(oc, video_codec, &video_st, opt);
av_dump_format(oc, 0, filename, 1);
/* open the output file, if needed */
if (!(fmt->flags & AVFMT_NOFILE)) {
ret = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE);
if (ret < 0) {
fprintf(stderr, "Could not open '%s'\n", filename);
exit(1);
}
}
/* Write the stream header, if any. */
ret = avformat_write_header(oc, &opt);
if (ret < 0) {
fprintf(stderr, "Error occurred when opening output file.\n");
exit(1);
}
while (encode_video) {
/* select the stream to encode */
if (encode_video &&
(!encode_audio || av_compare_ts(video_st.next_pts, video_st.st->codec->time_base,
audio_st.next_pts, audio_st.st->codec->time_base) <= 0)) {
encode_video = !write_video_frame(oc, &video_st);
}
}
/* Write the trailer, if any. The trailer must be written before you
* close the CodecContexts open when you wrote the header; otherwise
* av_write_trailer() may try to use memory that was freed on
* av_codec_close(). */
av_write_trailer(oc);
/* Close each codec. */
if (have_video)
close_stream(oc, &video_st);
if (!(fmt->flags & AVFMT_NOFILE))
/* Close the output file. */
avio_closep(&oc->pb);
/* free the stream */
avformat_free_context(oc);
2. also download shared build because we will need those dll during run-time
3. make headers and libs visible to VC projects
4. add the following defines:
#define __STDC_CONSTANT_MACROS
#define __STDC_FORMAT_MACROS5. some functions that use newer C features are not supported by MS Visual C++ 2012, like the following function call in log_packet(). These are not critical and can be commented out.
printf("pts:%s pts_time:%s dts:%s dts_time:%s duration:%s duration_time:%s stream_index:%d\n",
buf1, av_ts2timestr(pkt->pts, time_base),
buf2, av_ts2timestr(pkt->dts, time_base),
buf3, av_ts2timestr(pkt->duration, time_base),
pkt->stream_index);
6. some ffmpeg code directly assigned structure values which also failed in MSVC. the workaround is that we define a temporary variable, and then assign values for each field, and then do the copy.
AVRational tmp;
tmp.den = 1; tmp.num = c->sample_rate;
ost->st->time_base = tmp;
7. remember to always call av_register_all(); otherwise, codec is not found.
8. in doc/example directory, check example code muxing. c for how to output video/audio samples with a container such as AVI.
9. a complete working code that generates MPEG4 AVI based on muxing.c example code is shown below:
OutputStream video_st = { 0 }, audio_st = { 0 };
char filename[] = "zz.avi";
AVOutputFormat *fmt;
AVFormatContext *oc;
AVCodec *audio_codec, *video_codec;
int ret;
int have_video = 0, have_audio = 0;
int encode_video = 0, encode_audio = 0;
AVDictionary *opt = NULL;
av_register_all();
avformat_alloc_output_context2(&oc, NULL, NULL, filename);
if (!oc) {
printf("Could not deduce output format from file extension.\n");
exit(1);
}
fmt = oc->oformat;
if (fmt->video_codec != AV_CODEC_ID_NONE) {
add_stream(&video_st, oc, &video_codec, fmt->video_codec);
have_video = 1;
encode_video = 1;
}
if (have_video)
open_video(oc, video_codec, &video_st, opt);
av_dump_format(oc, 0, filename, 1);
/* open the output file, if needed */
if (!(fmt->flags & AVFMT_NOFILE)) {
ret = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE);
if (ret < 0) {
fprintf(stderr, "Could not open '%s'\n", filename);
exit(1);
}
}
/* Write the stream header, if any. */
ret = avformat_write_header(oc, &opt);
if (ret < 0) {
fprintf(stderr, "Error occurred when opening output file.\n");
exit(1);
}
while (encode_video) {
/* select the stream to encode */
if (encode_video &&
(!encode_audio || av_compare_ts(video_st.next_pts, video_st.st->codec->time_base,
audio_st.next_pts, audio_st.st->codec->time_base) <= 0)) {
encode_video = !write_video_frame(oc, &video_st);
}
}
/* Write the trailer, if any. The trailer must be written before you
* close the CodecContexts open when you wrote the header; otherwise
* av_write_trailer() may try to use memory that was freed on
* av_codec_close(). */
av_write_trailer(oc);
/* Close each codec. */
if (have_video)
close_stream(oc, &video_st);
if (!(fmt->flags & AVFMT_NOFILE))
/* Close the output file. */
avio_closep(&oc->pb);
/* free the stream */
avformat_free_context(oc);

0 Comments:
Post a Comment
<< Home