]> git.sesse.net Git - cubemap/blob - remux.cpp
Initial checkin.
[cubemap] / remux.cpp
1 #define __STDC_CONSTANT_MACROS
2 #include <stdio.h>
3 #include <stdint.h>
4
5 extern "C" {
6 #include <libavcodec/avcodec.h>
7 #include <libavformat/avformat.h>
8 }
9
10 AVOutputFormat *find_output_format(const char *name)
11 {
12         AVOutputFormat *output_fmt = NULL;
13         while ((output_fmt = av_oformat_next(output_fmt)) != NULL) {
14                 if (strcmp(output_fmt->name, "flv") == 0) {
15                         return output_fmt;
16                 }
17         }
18         return NULL;
19 }
20
21 void copy_stream_settings(AVStream *stream, const AVStream *istream)
22 {
23         AVCodecContext *codec = stream->codec;
24
25         const AVCodecContext *icodec = istream->codec;
26
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;
30
31         codec->codec_id = icodec->codec_id;
32         codec->codec_type = icodec->codec_type;
33 #if 0
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;
39                 }
40         }
41 #endif
42
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;
47
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;
52
53         codec->bits_per_coded_sample  = icodec->bits_per_coded_sample;
54         codec->time_base = istream->time_base;
55
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;
60         }
61
62         av_reduce(&codec->time_base.num, &codec->time_base.den,
63                         codec->time_base.num, codec->time_base.den, INT_MAX);
64
65         printf("time base: %d/%d\n", codec->time_base.num, codec->time_base.den);
66
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;
76 #if 0
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;
81 #endif
82                         break;
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;
94                                 } else {
95                                         stream->sample_aspect_ratio = (AVRational){0, 1};
96                                 }
97                                 codec->sample_aspect_ratio = stream->sample_aspect_ratio;
98                         }
99                         stream->avg_frame_rate = istream->avg_frame_rate;
100                         break;
101                 case AVMEDIA_TYPE_SUBTITLE:
102                         codec->width  = icodec->width;
103                         codec->height = icodec->height;
104                         break;
105                 case AVMEDIA_TYPE_DATA:
106                 case AVMEDIA_TYPE_ATTACHMENT:
107                         break;
108                 default:
109                         abort();
110         }
111 }
112                                 
113 int main(int argc, char *argv[])
114 {
115         av_register_all();
116         avformat_network_init();
117
118         // Open input.
119         AVFormatContext *input_ctx = NULL;
120         if (avformat_open_input(&input_ctx, argv[1], NULL, NULL) != 0) {
121                 exit(1);
122         }
123         if (avformat_find_stream_info(input_ctx, NULL) < 0) {
124                 exit(1);
125         }
126         av_dump_format(input_ctx, 0, argv[1], 0);
127
128         // Open output.
129         AVFormatContext *output_ctx = avformat_alloc_context();
130         if (output_ctx == NULL) {
131                 exit(1);
132         }
133
134         output_ctx->oformat = find_output_format("flv");
135         if (output_ctx->oformat == NULL) {
136                 printf("Couldn't find output format 'flv'!\n");
137                 exit(1);
138         }
139
140         if (avio_open2(&output_ctx->pb, "output.flv", AVIO_FLAG_WRITE, NULL, NULL) != 0) {
141                 printf("Couldn't open output.flv\n");
142                 exit(1);
143         }
144
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);
151                         exit(1);
152                 }
153
154                 copy_stream_settings(stream, input_ctx->streams[i]);
155         }
156         if (avformat_write_header(output_ctx, NULL) != 0) {
157                 printf("avformat_write_header()\n");
158                 exit(1);
159         }
160         
161
162         AVPacket packet;
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);
168         }
169
170         return 0;
171 }