1 #define __STDC_CONSTANT_MACROS
6 #include <libavcodec/avcodec.h>
7 #include <libavformat/avformat.h>
10 AVOutputFormat *find_output_format(const char *name)
12 AVOutputFormat *output_fmt = NULL;
13 while ((output_fmt = av_oformat_next(output_fmt)) != NULL) {
14 if (strcmp(output_fmt->name, "flv") == 0) {
21 void copy_stream_settings(AVStream *stream, const AVStream *istream)
23 AVCodecContext *codec = stream->codec;
25 const AVCodecContext *icodec = istream->codec;
27 stream->disposition = istream->disposition;
28 codec->bits_per_raw_sample = icodec->bits_per_raw_sample;
29 codec->chroma_sample_location = icodec->chroma_sample_location;
31 codec->codec_id = icodec->codec_id;
32 codec->codec_type = icodec->codec_type;
34 if (codec->codec_tag == 0) {
35 if (output_ctx->oformat->codec_tag ||
36 av_codec_get_id (output_ctx->oformat->codec_tag, icodec->codec_tag) == codec->codec_id ||
37 av_codec_get_tag(output_ctx->oformat->codec_tag, icodec->codec_id) <= 0) {
38 codec->codec_tag = icodec->codec_tag;
43 codec->bit_rate = icodec->bit_rate;
44 codec->rc_max_rate = icodec->rc_max_rate;
45 codec->rc_buffer_size = icodec->rc_buffer_size;
46 codec->field_order = icodec->field_order;
48 uint64_t extra_size = (uint64_t)icodec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE;
49 codec->extradata = (uint8_t *)av_mallocz(extra_size);
50 memcpy(codec->extradata, icodec->extradata, icodec->extradata_size);
51 codec->extradata_size= icodec->extradata_size;
53 codec->bits_per_coded_sample = icodec->bits_per_coded_sample;
54 codec->time_base = istream->time_base;
56 if (av_q2d(icodec->time_base)*icodec->ticks_per_frame > av_q2d(istream->time_base)
57 && av_q2d(istream->time_base) < 1.0/500) {
58 codec->time_base = icodec->time_base;
59 codec->time_base.num *= icodec->ticks_per_frame;
62 av_reduce(&codec->time_base.num, &codec->time_base.den,
63 codec->time_base.num, codec->time_base.den, INT_MAX);
65 printf("time base: %d/%d\n", codec->time_base.num, codec->time_base.den);
67 switch (codec->codec_type) {
68 case AVMEDIA_TYPE_AUDIO:
69 printf("audio stream\n");
70 codec->channel_layout = icodec->channel_layout;
71 codec->sample_rate = icodec->sample_rate;
72 codec->channels = icodec->channels;
73 codec->frame_size = icodec->frame_size;
74 codec->audio_service_type = icodec->audio_service_type;
75 codec->block_align = icodec->block_align;
77 if((codec->block_align == 1 || codec->block_align == 1152) && codec->codec_id == AV_CODEC_ID_MP3)
78 codec->block_align= 0;
79 if(codec->codec_id == AV_CODEC_ID_AC3)
80 codec->block_align= 0;
83 case AVMEDIA_TYPE_VIDEO:
84 printf("video stream\n");
85 codec->pix_fmt = icodec->pix_fmt;
86 codec->width = icodec->width;
87 codec->height = icodec->height;
88 codec->has_b_frames = icodec->has_b_frames;
89 if (codec->sample_aspect_ratio.num == 0) {
90 if (istream->sample_aspect_ratio.num != 0) {
91 stream->sample_aspect_ratio = istream->sample_aspect_ratio;
92 } else if (istream->codec->sample_aspect_ratio.num != 0) {
93 stream->sample_aspect_ratio = istream->codec->sample_aspect_ratio;
95 stream->sample_aspect_ratio = (AVRational){0, 1};
97 codec->sample_aspect_ratio = stream->sample_aspect_ratio;
99 stream->avg_frame_rate = istream->avg_frame_rate;
101 case AVMEDIA_TYPE_SUBTITLE:
102 codec->width = icodec->width;
103 codec->height = icodec->height;
105 case AVMEDIA_TYPE_DATA:
106 case AVMEDIA_TYPE_ATTACHMENT:
113 int main(int argc, char *argv[])
116 avformat_network_init();
119 AVFormatContext *input_ctx = NULL;
120 if (avformat_open_input(&input_ctx, argv[1], NULL, NULL) != 0) {
123 if (avformat_find_stream_info(input_ctx, NULL) < 0) {
126 av_dump_format(input_ctx, 0, argv[1], 0);
129 AVFormatContext *output_ctx = avformat_alloc_context();
130 if (output_ctx == NULL) {
134 output_ctx->oformat = find_output_format("flv");
135 if (output_ctx->oformat == NULL) {
136 printf("Couldn't find output format 'flv'!\n");
140 if (avio_open2(&output_ctx->pb, "output.flv", AVIO_FLAG_WRITE, NULL, NULL) != 0) {
141 printf("Couldn't open output.flv\n");
145 // Copy the stream headers from input to output.
146 printf("Found %d stream(s).\n", input_ctx->nb_streams);
147 for (int i = 0; i < input_ctx->nb_streams; ++i) {
148 AVStream *stream = avformat_new_stream(output_ctx, NULL);
149 if (stream == NULL) {
150 printf("Couldn't add stream %d\n", i);
154 copy_stream_settings(stream, input_ctx->streams[i]);
156 if (avformat_write_header(output_ctx, NULL) != 0) {
157 printf("avformat_write_header()\n");
163 while (av_read_frame(input_ctx, &packet) >= 0) {
164 // printf("pts=%ld dts=%ld stream=%d size=%d flags=0x%x\n",
165 // packet.pts, packet.dts, packet.stream_index, packet.size, packet.flags);
166 av_write_frame(output_ctx, &packet);
167 // av_free_packet(&packet);