Originally committed as revision 4351 to svn://svn.ffmpeg.org/ffmpeg/trunk
Fabrice Bellard authored on 2005/06/03 23:31:45... | ... |
@@ -98,7 +98,7 @@ static int frame_topBand = 0; |
98 | 98 |
static int frame_bottomBand = 0; |
99 | 99 |
static int frame_leftBand = 0; |
100 | 100 |
static int frame_rightBand = 0; |
101 |
-static int max_frames[3] = {INT_MAX, INT_MAX, INT_MAX}; |
|
101 |
+static int max_frames[4] = {INT_MAX, INT_MAX, INT_MAX, INT_MAX}; |
|
102 | 102 |
static int frame_rate = 25; |
103 | 103 |
static int frame_rate_base = 1; |
104 | 104 |
static int video_bit_rate = 200*1000; |
... | ... |
@@ -219,6 +219,10 @@ static int audio_disable = 0; |
219 | 219 |
static int audio_channels = 1; |
220 | 220 |
static int audio_codec_id = CODEC_ID_NONE; |
221 | 221 |
static int audio_codec_tag = 0; |
222 |
+static char *audio_language = NULL; |
|
223 |
+ |
|
224 |
+static int subtitle_codec_id = CODEC_ID_NONE; |
|
225 |
+static char *subtitle_language = NULL; |
|
222 | 226 |
|
223 | 227 |
static int mux_rate= 0; |
224 | 228 |
static int mux_packet_size= 0; |
... | ... |
@@ -244,6 +248,7 @@ static int bitexact = 0; |
244 | 244 |
static char *pass_logfilename = NULL; |
245 | 245 |
static int audio_stream_copy = 0; |
246 | 246 |
static int video_stream_copy = 0; |
247 |
+static int subtitle_stream_copy = 0; |
|
247 | 248 |
static int video_sync_method= 1; |
248 | 249 |
static int audio_sync_method= 0; |
249 | 250 |
static int copy_ts= 0; |
... | ... |
@@ -693,6 +698,58 @@ static void fill_pad_region(AVPicture* img, int height, int width, |
693 | 693 |
} |
694 | 694 |
} |
695 | 695 |
|
696 |
+static void do_subtitle_out(AVFormatContext *s, |
|
697 |
+ AVOutputStream *ost, |
|
698 |
+ AVInputStream *ist, |
|
699 |
+ AVSubtitle *sub, |
|
700 |
+ int64_t pts) |
|
701 |
+{ |
|
702 |
+ static uint8_t *subtitle_out = NULL; |
|
703 |
+ int subtitle_out_max_size = 65536; |
|
704 |
+ int subtitle_out_size, nb, i; |
|
705 |
+ AVCodecContext *enc; |
|
706 |
+ AVPacket pkt; |
|
707 |
+ |
|
708 |
+ if (pts == AV_NOPTS_VALUE) { |
|
709 |
+ fprintf(stderr, "Subtitle packets must have a pts\n"); |
|
710 |
+ return; |
|
711 |
+ } |
|
712 |
+ |
|
713 |
+ enc = &ost->st->codec; |
|
714 |
+ |
|
715 |
+ if (!subtitle_out) { |
|
716 |
+ subtitle_out = av_malloc(subtitle_out_max_size); |
|
717 |
+ } |
|
718 |
+ |
|
719 |
+ /* Note: DVB subtitle need one packet to draw them and one other |
|
720 |
+ packet to clear them */ |
|
721 |
+ /* XXX: signal it in the codec context ? */ |
|
722 |
+ if (enc->codec_id == CODEC_ID_DVB_SUBTITLE) |
|
723 |
+ nb = 2; |
|
724 |
+ else |
|
725 |
+ nb = 1; |
|
726 |
+ |
|
727 |
+ for(i = 0; i < nb; i++) { |
|
728 |
+ subtitle_out_size = avcodec_encode_subtitle(enc, subtitle_out, |
|
729 |
+ subtitle_out_max_size, sub); |
|
730 |
+ |
|
731 |
+ av_init_packet(&pkt); |
|
732 |
+ pkt.stream_index = ost->index; |
|
733 |
+ pkt.data = subtitle_out; |
|
734 |
+ pkt.size = subtitle_out_size; |
|
735 |
+ pkt.pts = av_rescale_q(av_rescale_q(pts, ist->st->time_base, AV_TIME_BASE_Q) + input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q, ost->st->time_base); |
|
736 |
+ if (enc->codec_id == CODEC_ID_DVB_SUBTITLE) { |
|
737 |
+ /* XXX: the pts correction is handled here. Maybe handling |
|
738 |
+ it in the codec would be better */ |
|
739 |
+ if (i == 0) |
|
740 |
+ pkt.pts += 90 * sub->start_display_time; |
|
741 |
+ else |
|
742 |
+ pkt.pts += 90 * sub->end_display_time; |
|
743 |
+ } |
|
744 |
+ av_interleaved_write_frame(s, &pkt); |
|
745 |
+ } |
|
746 |
+} |
|
747 |
+ |
|
696 | 748 |
static int bit_buffer_size= 1024*256; |
697 | 749 |
static uint8_t *bit_buffer= NULL; |
698 | 750 |
|
... | ... |
@@ -1130,6 +1187,8 @@ static int output_packet(AVInputStream *ist, int ist_index, |
1130 | 1130 |
void *buffer_to_free; |
1131 | 1131 |
static int samples_size= 0; |
1132 | 1132 |
static short *samples= NULL; |
1133 |
+ AVSubtitle subtitle, *subtitle_to_free; |
|
1134 |
+ int got_subtitle; |
|
1133 | 1135 |
|
1134 | 1136 |
if(!pkt){ |
1135 | 1137 |
ist->pts= ist->next_pts; // needed for last packet if vsync=0 |
... | ... |
@@ -1153,6 +1212,7 @@ static int output_packet(AVInputStream *ist, int ist_index, |
1153 | 1153 |
/* decode the packet if needed */ |
1154 | 1154 |
data_buf = NULL; /* fail safe */ |
1155 | 1155 |
data_size = 0; |
1156 |
+ subtitle_to_free = NULL; |
|
1156 | 1157 |
if (ist->decoding_needed) { |
1157 | 1158 |
switch(ist->st->codec.codec_type) { |
1158 | 1159 |
case CODEC_TYPE_AUDIO:{ |
... | ... |
@@ -1197,10 +1257,21 @@ static int output_packet(AVInputStream *ist, int ist_index, |
1197 | 1197 |
} |
1198 | 1198 |
len = 0; |
1199 | 1199 |
break; |
1200 |
- default: |
|
1200 |
+ case CODEC_TYPE_SUBTITLE: |
|
1201 |
+ ret = avcodec_decode_subtitle(&ist->st->codec, |
|
1202 |
+ &subtitle, &got_subtitle, ptr, len); |
|
1203 |
+ if (ret < 0) |
|
1201 | 1204 |
goto fail_decode; |
1205 |
+ if (!got_subtitle) { |
|
1206 |
+ goto discard_packet; |
|
1202 | 1207 |
} |
1203 |
- } else { |
|
1208 |
+ subtitle_to_free = &subtitle; |
|
1209 |
+ len = 0; |
|
1210 |
+ break; |
|
1211 |
+ default: |
|
1212 |
+ goto fail_decode; |
|
1213 |
+ } |
|
1214 |
+ } else { |
|
1204 | 1215 |
switch(ist->st->codec.codec_type) { |
1205 | 1216 |
case CODEC_TYPE_AUDIO: |
1206 | 1217 |
ist->next_pts += ((int64_t)AV_TIME_BASE * ist->st->codec.frame_size) / |
... | ... |
@@ -1293,6 +1364,10 @@ static int output_packet(AVInputStream *ist, int ist_index, |
1293 | 1293 |
if (do_vstats && frame_size) |
1294 | 1294 |
do_video_stats(os, ost, frame_size); |
1295 | 1295 |
break; |
1296 |
+ case CODEC_TYPE_SUBTITLE: |
|
1297 |
+ do_subtitle_out(os, ost, ist, &subtitle, |
|
1298 |
+ pkt->pts); |
|
1299 |
+ break; |
|
1296 | 1300 |
default: |
1297 | 1301 |
av_abort(); |
1298 | 1302 |
} |
... | ... |
@@ -1322,9 +1397,16 @@ static int output_packet(AVInputStream *ist, int ist_index, |
1322 | 1322 |
opkt.pts= av_rescale_q(av_rescale_q(pkt->pts, ist->st->time_base, AV_TIME_BASE_Q) + input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q, ost->st->time_base); |
1323 | 1323 |
else |
1324 | 1324 |
opkt.pts= AV_NOPTS_VALUE; |
1325 |
- opkt.dts= av_rescale_q(av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q) + input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q, ost->st->time_base); |
|
1325 |
+ |
|
1326 |
+ { |
|
1327 |
+ int64_t dts; |
|
1328 |
+ if (pkt->dts == AV_NOPTS_VALUE) |
|
1329 |
+ dts = ist->next_pts; |
|
1330 |
+ else |
|
1331 |
+ dts= av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q); |
|
1332 |
+ opkt.dts= av_rescale_q(dts + input_files_ts_offset[ist->file_index], AV_TIME_BASE_Q, ost->st->time_base); |
|
1333 |
+ } |
|
1326 | 1334 |
opkt.flags= pkt->flags; |
1327 |
- |
|
1328 | 1335 |
av_interleaved_write_frame(os, &opkt); |
1329 | 1336 |
ost->st->codec.frame_number++; |
1330 | 1337 |
ost->frame_number++; |
... | ... |
@@ -1332,6 +1414,12 @@ static int output_packet(AVInputStream *ist, int ist_index, |
1332 | 1332 |
} |
1333 | 1333 |
} |
1334 | 1334 |
av_free(buffer_to_free); |
1335 |
+ /* XXX: allocate the subtitles in the codec ? */ |
|
1336 |
+ if (subtitle_to_free) { |
|
1337 |
+ av_free(subtitle_to_free->bitmap); |
|
1338 |
+ av_free(subtitle_to_free->rgba_palette); |
|
1339 |
+ subtitle_to_free = NULL; |
|
1340 |
+ } |
|
1335 | 1341 |
} |
1336 | 1342 |
discard_packet: |
1337 | 1343 |
if (pkt == NULL) { |
... | ... |
@@ -1579,6 +1667,8 @@ static int av_encode(AVFormatContext **output_files, |
1579 | 1579 |
codec->height = icodec->height; |
1580 | 1580 |
codec->has_b_frames = icodec->has_b_frames; |
1581 | 1581 |
break; |
1582 |
+ case CODEC_TYPE_SUBTITLE: |
|
1583 |
+ break; |
|
1582 | 1584 |
default: |
1583 | 1585 |
av_abort(); |
1584 | 1586 |
} |
... | ... |
@@ -1686,8 +1776,13 @@ static int av_encode(AVFormatContext **output_files, |
1686 | 1686 |
ost->encoding_needed = 1; |
1687 | 1687 |
ist->decoding_needed = 1; |
1688 | 1688 |
break; |
1689 |
+ case CODEC_TYPE_SUBTITLE: |
|
1690 |
+ ost->encoding_needed = 1; |
|
1691 |
+ ist->decoding_needed = 1; |
|
1692 |
+ break; |
|
1689 | 1693 |
default: |
1690 | 1694 |
av_abort(); |
1695 |
+ break; |
|
1691 | 1696 |
} |
1692 | 1697 |
/* two pass mode */ |
1693 | 1698 |
if (ost->encoding_needed && |
... | ... |
@@ -1984,7 +2079,7 @@ static int av_encode(AVFormatContext **output_files, |
1984 | 1984 |
av_free_packet(&pkt); |
1985 | 1985 |
goto redo; |
1986 | 1986 |
} |
1987 |
- |
|
1987 |
+ |
|
1988 | 1988 |
discard_packet: |
1989 | 1989 |
av_free_packet(&pkt); |
1990 | 1990 |
|
... | ... |
@@ -2722,28 +2817,34 @@ static void opt_audio_device(const char *arg) |
2722 | 2722 |
audio_device = av_strdup(arg); |
2723 | 2723 |
} |
2724 | 2724 |
|
2725 |
-static void opt_audio_codec(const char *arg) |
|
2725 |
+static void opt_codec(int *pstream_copy, int *pcodec_id, |
|
2726 |
+ int codec_type, const char *arg) |
|
2726 | 2727 |
{ |
2727 | 2728 |
AVCodec *p; |
2728 | 2729 |
|
2729 | 2730 |
if (!strcmp(arg, "copy")) { |
2730 |
- audio_stream_copy = 1; |
|
2731 |
+ *pstream_copy = 1; |
|
2731 | 2732 |
} else { |
2732 | 2733 |
p = first_avcodec; |
2733 | 2734 |
while (p) { |
2734 |
- if (!strcmp(p->name, arg) && p->type == CODEC_TYPE_AUDIO) |
|
2735 |
+ if (!strcmp(p->name, arg) && p->type == codec_type) |
|
2735 | 2736 |
break; |
2736 | 2737 |
p = p->next; |
2737 | 2738 |
} |
2738 | 2739 |
if (p == NULL) { |
2739 |
- fprintf(stderr, "Unknown audio codec '%s'\n", arg); |
|
2740 |
+ fprintf(stderr, "Unknown codec '%s'\n", arg); |
|
2740 | 2741 |
exit(1); |
2741 | 2742 |
} else { |
2742 |
- audio_codec_id = p->id; |
|
2743 |
+ *pcodec_id = p->id; |
|
2743 | 2744 |
} |
2744 | 2745 |
} |
2745 | 2746 |
} |
2746 | 2747 |
|
2748 |
+static void opt_audio_codec(const char *arg) |
|
2749 |
+{ |
|
2750 |
+ opt_codec(&audio_stream_copy, &audio_codec_id, CODEC_TYPE_AUDIO, arg); |
|
2751 |
+} |
|
2752 |
+ |
|
2747 | 2753 |
static void opt_audio_tag(const char *arg) |
2748 | 2754 |
{ |
2749 | 2755 |
char *tail; |
... | ... |
@@ -2811,24 +2912,12 @@ static void opt_motion_estimation(const char *arg) |
2811 | 2811 |
|
2812 | 2812 |
static void opt_video_codec(const char *arg) |
2813 | 2813 |
{ |
2814 |
- AVCodec *p; |
|
2814 |
+ opt_codec(&video_stream_copy, &video_codec_id, CODEC_TYPE_VIDEO, arg); |
|
2815 |
+} |
|
2815 | 2816 |
|
2816 |
- if (!strcmp(arg, "copy")) { |
|
2817 |
- video_stream_copy = 1; |
|
2818 |
- } else { |
|
2819 |
- p = first_avcodec; |
|
2820 |
- while (p) { |
|
2821 |
- if (!strcmp(p->name, arg) && p->type == CODEC_TYPE_VIDEO) |
|
2822 |
- break; |
|
2823 |
- p = p->next; |
|
2824 |
- } |
|
2825 |
- if (p == NULL) { |
|
2826 |
- fprintf(stderr, "Unknown video codec '%s'\n", arg); |
|
2827 |
- exit(1); |
|
2828 |
- } else { |
|
2829 |
- video_codec_id = p->id; |
|
2830 |
- } |
|
2831 |
- } |
|
2817 |
+static void opt_subtitle_codec(const char *arg) |
|
2818 |
+{ |
|
2819 |
+ opt_codec(&subtitle_stream_copy, &subtitle_codec_id, CODEC_TYPE_SUBTITLE, arg); |
|
2832 | 2820 |
} |
2833 | 2821 |
|
2834 | 2822 |
static void opt_map(const char *arg) |
... | ... |
@@ -3011,6 +3100,8 @@ static void opt_input_file(const char *filename) |
3011 | 3011 |
break; |
3012 | 3012 |
case CODEC_TYPE_DATA: |
3013 | 3013 |
break; |
3014 |
+ case CODEC_TYPE_SUBTITLE: |
|
3015 |
+ break; |
|
3014 | 3016 |
default: |
3015 | 3017 |
av_abort(); |
3016 | 3018 |
} |
... | ... |
@@ -3058,6 +3149,7 @@ static void check_audio_video_inputs(int *has_video_ptr, int *has_audio_ptr) |
3058 | 3058 |
has_video = 1; |
3059 | 3059 |
break; |
3060 | 3060 |
case CODEC_TYPE_DATA: |
3061 |
+ case CODEC_TYPE_SUBTITLE: |
|
3061 | 3062 |
break; |
3062 | 3063 |
default: |
3063 | 3064 |
av_abort(); |
... | ... |
@@ -3068,12 +3160,407 @@ static void check_audio_video_inputs(int *has_video_ptr, int *has_audio_ptr) |
3068 | 3068 |
*has_audio_ptr = has_audio; |
3069 | 3069 |
} |
3070 | 3070 |
|
3071 |
-static void opt_output_file(const char *filename) |
|
3071 |
+static void new_video_stream(AVFormatContext *oc) |
|
3072 | 3072 |
{ |
3073 | 3073 |
AVStream *st; |
3074 |
- AVFormatContext *oc; |
|
3075 |
- int use_video, use_audio, nb_streams, input_has_video, input_has_audio; |
|
3074 |
+ AVCodecContext *video_enc; |
|
3075 |
+ int codec_id; |
|
3076 |
+ |
|
3077 |
+ st = av_new_stream(oc, oc->nb_streams); |
|
3078 |
+ if (!st) { |
|
3079 |
+ fprintf(stderr, "Could not alloc stream\n"); |
|
3080 |
+ exit(1); |
|
3081 |
+ } |
|
3082 |
+#if defined(HAVE_THREADS) |
|
3083 |
+ if(thread_count>1) |
|
3084 |
+ avcodec_thread_init(&st->codec, thread_count); |
|
3085 |
+#endif |
|
3086 |
+ |
|
3087 |
+ video_enc = &st->codec; |
|
3088 |
+ |
|
3089 |
+ if(video_codec_tag) |
|
3090 |
+ video_enc->codec_tag= video_codec_tag; |
|
3091 |
+ |
|
3092 |
+ if (oc->oformat->flags & AVFMT_GLOBALHEADER) |
|
3093 |
+ video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER; |
|
3094 |
+ if (video_stream_copy) { |
|
3095 |
+ st->stream_copy = 1; |
|
3096 |
+ video_enc->codec_type = CODEC_TYPE_VIDEO; |
|
3097 |
+ } else { |
|
3098 |
+ char *p; |
|
3099 |
+ int i; |
|
3100 |
+ AVCodec *codec; |
|
3101 |
+ |
|
3102 |
+ codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, CODEC_TYPE_VIDEO); |
|
3103 |
+ if (video_codec_id != CODEC_ID_NONE) |
|
3104 |
+ codec_id = video_codec_id; |
|
3105 |
+ |
|
3106 |
+ video_enc->codec_id = codec_id; |
|
3107 |
+ codec = avcodec_find_encoder(codec_id); |
|
3108 |
+ |
|
3109 |
+ video_enc->bit_rate = video_bit_rate; |
|
3110 |
+ video_enc->bit_rate_tolerance = video_bit_rate_tolerance; |
|
3111 |
+ video_enc->time_base.den = frame_rate; |
|
3112 |
+ video_enc->time_base.num = frame_rate_base; |
|
3113 |
+ if(codec && codec->supported_framerates){ |
|
3114 |
+ const AVRational *p= codec->supported_framerates; |
|
3115 |
+ AVRational req= (AVRational){frame_rate, frame_rate_base}; |
|
3116 |
+ const AVRational *best=NULL; |
|
3117 |
+ AVRational best_error= (AVRational){INT_MAX, 1}; |
|
3118 |
+ for(; p->den!=0; p++){ |
|
3119 |
+ AVRational error= av_sub_q(req, *p); |
|
3120 |
+ if(error.num <0) error.num *= -1; |
|
3121 |
+ if(av_cmp_q(error, best_error) < 0){ |
|
3122 |
+ best_error= error; |
|
3123 |
+ best= p; |
|
3124 |
+ } |
|
3125 |
+ } |
|
3126 |
+ video_enc->time_base.den= best->num; |
|
3127 |
+ video_enc->time_base.num= best->den; |
|
3128 |
+ } |
|
3129 |
+ |
|
3130 |
+ video_enc->width = frame_width + frame_padright + frame_padleft; |
|
3131 |
+ video_enc->height = frame_height + frame_padtop + frame_padbottom; |
|
3132 |
+ video_enc->sample_aspect_ratio = av_d2q(frame_aspect_ratio*frame_height/frame_width, 255); |
|
3133 |
+ video_enc->pix_fmt = frame_pix_fmt; |
|
3134 |
+ |
|
3135 |
+ if(codec && codec->pix_fmts){ |
|
3136 |
+ const enum PixelFormat *p= codec->pix_fmts; |
|
3137 |
+ for(; *p!=-1; p++){ |
|
3138 |
+ if(*p == video_enc->pix_fmt) |
|
3139 |
+ break; |
|
3140 |
+ } |
|
3141 |
+ if(*p == -1) |
|
3142 |
+ video_enc->pix_fmt = codec->pix_fmts[0]; |
|
3143 |
+ } |
|
3144 |
+ |
|
3145 |
+ if (!intra_only) |
|
3146 |
+ video_enc->gop_size = gop_size; |
|
3147 |
+ else |
|
3148 |
+ video_enc->gop_size = 0; |
|
3149 |
+ if (video_qscale || same_quality) { |
|
3150 |
+ video_enc->flags |= CODEC_FLAG_QSCALE; |
|
3151 |
+ video_enc->global_quality= |
|
3152 |
+ st->quality = FF_QP2LAMBDA * video_qscale; |
|
3153 |
+ } |
|
3154 |
+ |
|
3155 |
+ if(intra_matrix) |
|
3156 |
+ video_enc->intra_matrix = intra_matrix; |
|
3157 |
+ if(inter_matrix) |
|
3158 |
+ video_enc->inter_matrix = inter_matrix; |
|
3159 |
+ |
|
3160 |
+ if(bitexact) |
|
3161 |
+ video_enc->flags |= CODEC_FLAG_BITEXACT; |
|
3162 |
+ |
|
3163 |
+ video_enc->mb_decision = mb_decision; |
|
3164 |
+ video_enc->mb_cmp = mb_cmp; |
|
3165 |
+ video_enc->ildct_cmp = ildct_cmp; |
|
3166 |
+ video_enc->me_sub_cmp = sub_cmp; |
|
3167 |
+ video_enc->me_cmp = cmp; |
|
3168 |
+ video_enc->me_pre_cmp = pre_cmp; |
|
3169 |
+ video_enc->pre_me = pre_me; |
|
3170 |
+ video_enc->lumi_masking = lumi_mask; |
|
3171 |
+ video_enc->dark_masking = dark_mask; |
|
3172 |
+ video_enc->spatial_cplx_masking = scplx_mask; |
|
3173 |
+ video_enc->temporal_cplx_masking = tcplx_mask; |
|
3174 |
+ video_enc->p_masking = p_mask; |
|
3175 |
+ video_enc->quantizer_noise_shaping= qns; |
|
3176 |
+ |
|
3177 |
+ if (use_umv) { |
|
3178 |
+ video_enc->flags |= CODEC_FLAG_H263P_UMV; |
|
3179 |
+ } |
|
3180 |
+ if (use_ss) { |
|
3181 |
+ video_enc->flags |= CODEC_FLAG_H263P_SLICE_STRUCT; |
|
3182 |
+ } |
|
3183 |
+ if (use_aic) { |
|
3184 |
+ video_enc->flags |= CODEC_FLAG_H263P_AIC; |
|
3185 |
+ } |
|
3186 |
+ if (use_aiv) { |
|
3187 |
+ video_enc->flags |= CODEC_FLAG_H263P_AIV; |
|
3188 |
+ } |
|
3189 |
+ if (use_4mv) { |
|
3190 |
+ video_enc->flags |= CODEC_FLAG_4MV; |
|
3191 |
+ } |
|
3192 |
+ if (use_obmc) { |
|
3193 |
+ video_enc->flags |= CODEC_FLAG_OBMC; |
|
3194 |
+ } |
|
3195 |
+ if (use_loop) { |
|
3196 |
+ video_enc->flags |= CODEC_FLAG_LOOP_FILTER; |
|
3197 |
+ } |
|
3198 |
+ |
|
3199 |
+ if(use_part) { |
|
3200 |
+ video_enc->flags |= CODEC_FLAG_PART; |
|
3201 |
+ } |
|
3202 |
+ if (use_alt_scan) { |
|
3203 |
+ video_enc->flags |= CODEC_FLAG_ALT_SCAN; |
|
3204 |
+ } |
|
3205 |
+ if (use_trell) { |
|
3206 |
+ video_enc->flags |= CODEC_FLAG_TRELLIS_QUANT; |
|
3207 |
+ } |
|
3208 |
+ if (use_mv0) { |
|
3209 |
+ video_enc->flags |= CODEC_FLAG_MV0; |
|
3210 |
+ } |
|
3211 |
+ if (do_normalize_aqp) { |
|
3212 |
+ video_enc->flags |= CODEC_FLAG_NORMALIZE_AQP; |
|
3213 |
+ } |
|
3214 |
+ if (use_scan_offset) { |
|
3215 |
+ video_enc->flags |= CODEC_FLAG_SVCD_SCAN_OFFSET; |
|
3216 |
+ } |
|
3217 |
+ if (closed_gop) { |
|
3218 |
+ video_enc->flags |= CODEC_FLAG_CLOSED_GOP; |
|
3219 |
+ } |
|
3220 |
+ if (strict_gop) { |
|
3221 |
+ video_enc->flags2 |= CODEC_FLAG2_STRICT_GOP; |
|
3222 |
+ } |
|
3223 |
+ if (use_qpel) { |
|
3224 |
+ video_enc->flags |= CODEC_FLAG_QPEL; |
|
3225 |
+ } |
|
3226 |
+ if (use_qprd) { |
|
3227 |
+ video_enc->flags |= CODEC_FLAG_QP_RD; |
|
3228 |
+ } |
|
3229 |
+ if (use_cbprd) { |
|
3230 |
+ video_enc->flags |= CODEC_FLAG_CBP_RD; |
|
3231 |
+ } |
|
3232 |
+ if (b_frames) { |
|
3233 |
+ video_enc->max_b_frames = b_frames; |
|
3234 |
+ video_enc->b_frame_strategy = b_strategy; |
|
3235 |
+ video_enc->b_quant_factor = 2.0; |
|
3236 |
+ } |
|
3237 |
+ if (do_interlace_dct) { |
|
3238 |
+ video_enc->flags |= CODEC_FLAG_INTERLACED_DCT; |
|
3239 |
+ } |
|
3240 |
+ if (do_interlace_me) { |
|
3241 |
+ video_enc->flags |= CODEC_FLAG_INTERLACED_ME; |
|
3242 |
+ } |
|
3243 |
+ if (no_output) { |
|
3244 |
+ video_enc->flags2 |= CODEC_FLAG2_NO_OUTPUT; |
|
3245 |
+ } |
|
3246 |
+ if (gray_only) { |
|
3247 |
+ video_enc->flags |= CODEC_FLAG_GRAY; |
|
3248 |
+ } |
|
3249 |
+ video_enc->qmin = video_qmin; |
|
3250 |
+ video_enc->qmax = video_qmax; |
|
3251 |
+ video_enc->lmin = video_lmin; |
|
3252 |
+ video_enc->lmax = video_lmax; |
|
3253 |
+ video_enc->rc_qsquish = video_qsquish; |
|
3254 |
+ video_enc->luma_elim_threshold = video_lelim; |
|
3255 |
+ video_enc->chroma_elim_threshold = video_celim; |
|
3256 |
+ video_enc->mb_lmin = video_mb_lmin; |
|
3257 |
+ video_enc->mb_lmax = video_mb_lmax; |
|
3258 |
+ video_enc->max_qdiff = video_qdiff; |
|
3259 |
+ video_enc->qblur = video_qblur; |
|
3260 |
+ video_enc->qcompress = video_qcomp; |
|
3261 |
+ video_enc->rc_eq = video_rc_eq; |
|
3262 |
+ video_enc->debug = debug; |
|
3263 |
+ video_enc->debug_mv = debug_mv; |
|
3264 |
+ video_enc->workaround_bugs = workaround_bugs; |
|
3265 |
+ video_enc->thread_count = thread_count; |
|
3266 |
+ p= video_rc_override_string; |
|
3267 |
+ for(i=0; p; i++){ |
|
3268 |
+ int start, end, q; |
|
3269 |
+ int e=sscanf(p, "%d,%d,%d", &start, &end, &q); |
|
3270 |
+ if(e!=3){ |
|
3271 |
+ fprintf(stderr, "error parsing rc_override\n"); |
|
3272 |
+ exit(1); |
|
3273 |
+ } |
|
3274 |
+ video_enc->rc_override= |
|
3275 |
+ av_realloc(video_enc->rc_override, |
|
3276 |
+ sizeof(RcOverride)*(i+1)); |
|
3277 |
+ video_enc->rc_override[i].start_frame= start; |
|
3278 |
+ video_enc->rc_override[i].end_frame = end; |
|
3279 |
+ if(q>0){ |
|
3280 |
+ video_enc->rc_override[i].qscale= q; |
|
3281 |
+ video_enc->rc_override[i].quality_factor= 1.0; |
|
3282 |
+ } |
|
3283 |
+ else{ |
|
3284 |
+ video_enc->rc_override[i].qscale= 0; |
|
3285 |
+ video_enc->rc_override[i].quality_factor= -q/100.0; |
|
3286 |
+ } |
|
3287 |
+ p= strchr(p, '/'); |
|
3288 |
+ if(p) p++; |
|
3289 |
+ } |
|
3290 |
+ video_enc->rc_override_count=i; |
|
3291 |
+ |
|
3292 |
+ video_enc->rc_max_rate = video_rc_max_rate; |
|
3293 |
+ video_enc->rc_min_rate = video_rc_min_rate; |
|
3294 |
+ video_enc->rc_buffer_size = video_rc_buffer_size; |
|
3295 |
+ video_enc->rc_initial_buffer_occupancy = video_rc_buffer_size*3/4; |
|
3296 |
+ video_enc->rc_buffer_aggressivity= video_rc_buffer_aggressivity; |
|
3297 |
+ video_enc->rc_initial_cplx= video_rc_initial_cplx; |
|
3298 |
+ video_enc->i_quant_factor = video_i_qfactor; |
|
3299 |
+ video_enc->b_quant_factor = video_b_qfactor; |
|
3300 |
+ video_enc->i_quant_offset = video_i_qoffset; |
|
3301 |
+ video_enc->b_quant_offset = video_b_qoffset; |
|
3302 |
+ video_enc->intra_quant_bias = video_intra_quant_bias; |
|
3303 |
+ video_enc->inter_quant_bias = video_inter_quant_bias; |
|
3304 |
+ video_enc->dct_algo = dct_algo; |
|
3305 |
+ video_enc->idct_algo = idct_algo; |
|
3306 |
+ video_enc->me_threshold= me_threshold; |
|
3307 |
+ video_enc->mb_threshold= mb_threshold; |
|
3308 |
+ video_enc->intra_dc_precision= intra_dc_precision - 8; |
|
3309 |
+ video_enc->strict_std_compliance = strict; |
|
3310 |
+ video_enc->error_rate = error_rate; |
|
3311 |
+ video_enc->noise_reduction= noise_reduction; |
|
3312 |
+ video_enc->scenechange_threshold= sc_threshold; |
|
3313 |
+ video_enc->me_range = me_range; |
|
3314 |
+ video_enc->coder_type= coder; |
|
3315 |
+ video_enc->context_model= context; |
|
3316 |
+ video_enc->prediction_method= predictor; |
|
3317 |
+ video_enc->profile= video_profile; |
|
3318 |
+ video_enc->level= video_level; |
|
3319 |
+ video_enc->nsse_weight= nsse_weight; |
|
3320 |
+ video_enc->me_subpel_quality= subpel_quality; |
|
3321 |
+ video_enc->me_penalty_compensation= me_penalty_compensation; |
|
3322 |
+ video_enc->frame_skip_threshold= frame_skip_threshold; |
|
3323 |
+ video_enc->frame_skip_factor= frame_skip_factor; |
|
3324 |
+ video_enc->frame_skip_exp= frame_skip_exp; |
|
3325 |
+ video_enc->frame_skip_cmp= frame_skip_cmp; |
|
3326 |
+ |
|
3327 |
+ if(packet_size){ |
|
3328 |
+ video_enc->rtp_mode= 1; |
|
3329 |
+ video_enc->rtp_payload_size= packet_size; |
|
3330 |
+ } |
|
3331 |
+ |
|
3332 |
+ if (do_psnr) |
|
3333 |
+ video_enc->flags|= CODEC_FLAG_PSNR; |
|
3334 |
+ |
|
3335 |
+ video_enc->me_method = me_method; |
|
3336 |
+ |
|
3337 |
+ /* two pass mode */ |
|
3338 |
+ if (do_pass) { |
|
3339 |
+ if (do_pass == 1) { |
|
3340 |
+ video_enc->flags |= CODEC_FLAG_PASS1; |
|
3341 |
+ } else { |
|
3342 |
+ video_enc->flags |= CODEC_FLAG_PASS2; |
|
3343 |
+ } |
|
3344 |
+ } |
|
3345 |
+ } |
|
3346 |
+ |
|
3347 |
+ /* reset some key parameters */ |
|
3348 |
+ video_disable = 0; |
|
3349 |
+ video_codec_id = CODEC_ID_NONE; |
|
3350 |
+ video_stream_copy = 0; |
|
3351 |
+} |
|
3352 |
+ |
|
3353 |
+static void new_audio_stream(AVFormatContext *oc) |
|
3354 |
+{ |
|
3355 |
+ AVStream *st; |
|
3356 |
+ AVCodecContext *audio_enc; |
|
3076 | 3357 |
int codec_id; |
3358 |
+ |
|
3359 |
+ st = av_new_stream(oc, oc->nb_streams); |
|
3360 |
+ if (!st) { |
|
3361 |
+ fprintf(stderr, "Could not alloc stream\n"); |
|
3362 |
+ exit(1); |
|
3363 |
+ } |
|
3364 |
+#if defined(HAVE_THREADS) |
|
3365 |
+ if(thread_count>1) |
|
3366 |
+ avcodec_thread_init(&st->codec, thread_count); |
|
3367 |
+#endif |
|
3368 |
+ |
|
3369 |
+ audio_enc = &st->codec; |
|
3370 |
+ audio_enc->codec_type = CODEC_TYPE_AUDIO; |
|
3371 |
+ |
|
3372 |
+ if(audio_codec_tag) |
|
3373 |
+ audio_enc->codec_tag= audio_codec_tag; |
|
3374 |
+ |
|
3375 |
+ if (oc->oformat->flags & AVFMT_GLOBALHEADER) |
|
3376 |
+ audio_enc->flags |= CODEC_FLAG_GLOBAL_HEADER; |
|
3377 |
+ if (audio_stream_copy) { |
|
3378 |
+ st->stream_copy = 1; |
|
3379 |
+ audio_enc->channels = audio_channels; |
|
3380 |
+ } else { |
|
3381 |
+ codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, CODEC_TYPE_AUDIO); |
|
3382 |
+ if (audio_codec_id != CODEC_ID_NONE) |
|
3383 |
+ codec_id = audio_codec_id; |
|
3384 |
+ audio_enc->codec_id = codec_id; |
|
3385 |
+ |
|
3386 |
+ audio_enc->bit_rate = audio_bit_rate; |
|
3387 |
+ audio_enc->strict_std_compliance = strict; |
|
3388 |
+ audio_enc->thread_count = thread_count; |
|
3389 |
+ /* For audio codecs other than AC3 or DTS we limit */ |
|
3390 |
+ /* the number of coded channels to stereo */ |
|
3391 |
+ if (audio_channels > 2 && codec_id != CODEC_ID_AC3 |
|
3392 |
+ && codec_id != CODEC_ID_DTS) { |
|
3393 |
+ audio_enc->channels = 2; |
|
3394 |
+ } else |
|
3395 |
+ audio_enc->channels = audio_channels; |
|
3396 |
+ } |
|
3397 |
+ audio_enc->sample_rate = audio_sample_rate; |
|
3398 |
+ if (audio_language) { |
|
3399 |
+ pstrcpy(st->language, sizeof(st->language), audio_language); |
|
3400 |
+ av_free(audio_language); |
|
3401 |
+ audio_language = NULL; |
|
3402 |
+ } |
|
3403 |
+ |
|
3404 |
+ /* reset some key parameters */ |
|
3405 |
+ audio_disable = 0; |
|
3406 |
+ audio_codec_id = CODEC_ID_NONE; |
|
3407 |
+ audio_stream_copy = 0; |
|
3408 |
+} |
|
3409 |
+ |
|
3410 |
+static void opt_new_subtitle_stream(void) |
|
3411 |
+{ |
|
3412 |
+ AVFormatContext *oc; |
|
3413 |
+ AVStream *st; |
|
3414 |
+ AVCodecContext *subtitle_enc; |
|
3415 |
+ |
|
3416 |
+ if (nb_output_files <= 0) { |
|
3417 |
+ fprintf(stderr, "At least one output file must be specified\n"); |
|
3418 |
+ exit(1); |
|
3419 |
+ } |
|
3420 |
+ oc = output_files[nb_output_files - 1]; |
|
3421 |
+ |
|
3422 |
+ st = av_new_stream(oc, oc->nb_streams); |
|
3423 |
+ if (!st) { |
|
3424 |
+ fprintf(stderr, "Could not alloc stream\n"); |
|
3425 |
+ exit(1); |
|
3426 |
+ } |
|
3427 |
+ |
|
3428 |
+ subtitle_enc = &st->codec; |
|
3429 |
+ subtitle_enc->codec_type = CODEC_TYPE_SUBTITLE; |
|
3430 |
+ if (subtitle_stream_copy) { |
|
3431 |
+ st->stream_copy = 1; |
|
3432 |
+ } else { |
|
3433 |
+ subtitle_enc->codec_id = subtitle_codec_id; |
|
3434 |
+ } |
|
3435 |
+ |
|
3436 |
+ if (subtitle_language) { |
|
3437 |
+ pstrcpy(st->language, sizeof(st->language), subtitle_language); |
|
3438 |
+ av_free(subtitle_language); |
|
3439 |
+ subtitle_language = NULL; |
|
3440 |
+ } |
|
3441 |
+ |
|
3442 |
+ subtitle_codec_id = CODEC_ID_NONE; |
|
3443 |
+ subtitle_stream_copy = 0; |
|
3444 |
+} |
|
3445 |
+ |
|
3446 |
+static void opt_new_audio_stream(void) |
|
3447 |
+{ |
|
3448 |
+ AVFormatContext *oc; |
|
3449 |
+ if (nb_output_files <= 0) { |
|
3450 |
+ fprintf(stderr, "At least one output file must be specified\n"); |
|
3451 |
+ exit(1); |
|
3452 |
+ } |
|
3453 |
+ oc = output_files[nb_output_files - 1]; |
|
3454 |
+ new_audio_stream(oc); |
|
3455 |
+} |
|
3456 |
+ |
|
3457 |
+static void opt_new_video_stream(void) |
|
3458 |
+{ |
|
3459 |
+ AVFormatContext *oc; |
|
3460 |
+ if (nb_output_files <= 0) { |
|
3461 |
+ fprintf(stderr, "At least one output file must be specified\n"); |
|
3462 |
+ exit(1); |
|
3463 |
+ } |
|
3464 |
+ oc = output_files[nb_output_files - 1]; |
|
3465 |
+ new_video_stream(oc); |
|
3466 |
+} |
|
3467 |
+ |
|
3468 |
+static void opt_output_file(const char *filename) |
|
3469 |
+{ |
|
3470 |
+ AVFormatContext *oc; |
|
3471 |
+ int use_video, use_audio, input_has_video, input_has_audio; |
|
3077 | 3472 |
AVFormatParameters params, *ap = ¶ms; |
3078 | 3473 |
|
3079 | 3474 |
if (!strcmp(filename, "-")) |
... | ... |
@@ -3091,6 +3578,7 @@ static void opt_output_file(const char *filename) |
3091 | 3091 |
} |
3092 | 3092 |
|
3093 | 3093 |
oc->oformat = file_oformat; |
3094 |
+ pstrcpy(oc->filename, sizeof(oc->filename), filename); |
|
3094 | 3095 |
|
3095 | 3096 |
if (!strcmp(file_oformat->name, "ffm") && |
3096 | 3097 |
strstart(filename, "http:", NULL)) { |
... | ... |
@@ -3122,328 +3610,15 @@ static void opt_output_file(const char *filename) |
3122 | 3122 |
use_video = 0; |
3123 | 3123 |
} |
3124 | 3124 |
|
3125 |
- nb_streams = 0; |
|
3126 | 3125 |
if (use_video) { |
3127 |
- AVCodecContext *video_enc; |
|
3128 |
- |
|
3129 |
- st = av_new_stream(oc, nb_streams++); |
|
3130 |
- if (!st) { |
|
3131 |
- fprintf(stderr, "Could not alloc stream\n"); |
|
3132 |
- exit(1); |
|
3133 |
- } |
|
3134 |
-#if defined(HAVE_THREADS) |
|
3135 |
- if(thread_count>1) |
|
3136 |
- avcodec_thread_init(&st->codec, thread_count); |
|
3137 |
-#endif |
|
3138 |
- |
|
3139 |
- video_enc = &st->codec; |
|
3140 |
- |
|
3141 |
- if(video_codec_tag) |
|
3142 |
- video_enc->codec_tag= video_codec_tag; |
|
3143 |
- |
|
3144 |
- if (file_oformat->flags & AVFMT_GLOBALHEADER) |
|
3145 |
- video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER; |
|
3146 |
- if (video_stream_copy) { |
|
3147 |
- st->stream_copy = 1; |
|
3148 |
- video_enc->codec_type = CODEC_TYPE_VIDEO; |
|
3149 |
- } else { |
|
3150 |
- char *p; |
|
3151 |
- int i; |
|
3152 |
- AVCodec *codec; |
|
3153 |
- |
|
3154 |
- codec_id = av_guess_codec(file_oformat, NULL, filename, NULL, CODEC_TYPE_VIDEO); |
|
3155 |
- if (video_codec_id != CODEC_ID_NONE) |
|
3156 |
- codec_id = video_codec_id; |
|
3157 |
- |
|
3158 |
- video_enc->codec_id = codec_id; |
|
3159 |
- codec = avcodec_find_encoder(codec_id); |
|
3160 |
- |
|
3161 |
- video_enc->bit_rate = video_bit_rate; |
|
3162 |
- video_enc->bit_rate_tolerance = video_bit_rate_tolerance; |
|
3163 |
- video_enc->time_base.den = frame_rate; |
|
3164 |
- video_enc->time_base.num = frame_rate_base; |
|
3165 |
- if(codec && codec->supported_framerates){ |
|
3166 |
- const AVRational *p= codec->supported_framerates; |
|
3167 |
- AVRational req= (AVRational){frame_rate, frame_rate_base}; |
|
3168 |
- const AVRational *best=NULL; |
|
3169 |
- AVRational best_error= (AVRational){INT_MAX, 1}; |
|
3170 |
- for(; p->den!=0; p++){ |
|
3171 |
- AVRational error= av_sub_q(req, *p); |
|
3172 |
- if(error.num <0) error.num *= -1; |
|
3173 |
- if(av_cmp_q(error, best_error) < 0){ |
|
3174 |
- best_error= error; |
|
3175 |
- best= p; |
|
3176 |
- } |
|
3177 |
- } |
|
3178 |
- video_enc->time_base.den= best->num; |
|
3179 |
- video_enc->time_base.num= best->den; |
|
3180 |
- } |
|
3181 |
- |
|
3182 |
- video_enc->width = frame_width + frame_padright + frame_padleft; |
|
3183 |
- video_enc->height = frame_height + frame_padtop + frame_padbottom; |
|
3184 |
- video_enc->sample_aspect_ratio = av_d2q(frame_aspect_ratio*frame_height/frame_width, 255); |
|
3185 |
- video_enc->pix_fmt = frame_pix_fmt; |
|
3186 |
- |
|
3187 |
- if(codec && codec->pix_fmts){ |
|
3188 |
- const enum PixelFormat *p= codec->pix_fmts; |
|
3189 |
- for(; *p!=-1; p++){ |
|
3190 |
- if(*p == video_enc->pix_fmt) |
|
3191 |
- break; |
|
3192 |
- } |
|
3193 |
- if(*p == -1) |
|
3194 |
- video_enc->pix_fmt = codec->pix_fmts[0]; |
|
3195 |
- } |
|
3196 |
- |
|
3197 |
- if (!intra_only) |
|
3198 |
- video_enc->gop_size = gop_size; |
|
3199 |
- else |
|
3200 |
- video_enc->gop_size = 0; |
|
3201 |
- if (video_qscale || same_quality) { |
|
3202 |
- video_enc->flags |= CODEC_FLAG_QSCALE; |
|
3203 |
- video_enc->global_quality= |
|
3204 |
- st->quality = FF_QP2LAMBDA * video_qscale; |
|
3205 |
- } |
|
3206 |
- |
|
3207 |
- if(intra_matrix) |
|
3208 |
- video_enc->intra_matrix = intra_matrix; |
|
3209 |
- if(inter_matrix) |
|
3210 |
- video_enc->inter_matrix = inter_matrix; |
|
3211 |
- |
|
3212 |
- if(bitexact) |
|
3213 |
- video_enc->flags |= CODEC_FLAG_BITEXACT; |
|
3214 |
- |
|
3215 |
- video_enc->mb_decision = mb_decision; |
|
3216 |
- video_enc->mb_cmp = mb_cmp; |
|
3217 |
- video_enc->ildct_cmp = ildct_cmp; |
|
3218 |
- video_enc->me_sub_cmp = sub_cmp; |
|
3219 |
- video_enc->me_cmp = cmp; |
|
3220 |
- video_enc->me_pre_cmp = pre_cmp; |
|
3221 |
- video_enc->pre_me = pre_me; |
|
3222 |
- video_enc->lumi_masking = lumi_mask; |
|
3223 |
- video_enc->dark_masking = dark_mask; |
|
3224 |
- video_enc->spatial_cplx_masking = scplx_mask; |
|
3225 |
- video_enc->temporal_cplx_masking = tcplx_mask; |
|
3226 |
- video_enc->p_masking = p_mask; |
|
3227 |
- video_enc->quantizer_noise_shaping= qns; |
|
3228 |
- |
|
3229 |
- if (use_umv) { |
|
3230 |
- video_enc->flags |= CODEC_FLAG_H263P_UMV; |
|
3231 |
- } |
|
3232 |
- if (use_ss) { |
|
3233 |
- video_enc->flags |= CODEC_FLAG_H263P_SLICE_STRUCT; |
|
3234 |
- } |
|
3235 |
- if (use_aic) { |
|
3236 |
- video_enc->flags |= CODEC_FLAG_H263P_AIC; |
|
3237 |
- } |
|
3238 |
- if (use_aiv) { |
|
3239 |
- video_enc->flags |= CODEC_FLAG_H263P_AIV; |
|
3240 |
- } |
|
3241 |
- if (use_4mv) { |
|
3242 |
- video_enc->flags |= CODEC_FLAG_4MV; |
|
3243 |
- } |
|
3244 |
- if (use_obmc) { |
|
3245 |
- video_enc->flags |= CODEC_FLAG_OBMC; |
|
3246 |
- } |
|
3247 |
- if (use_loop) { |
|
3248 |
- video_enc->flags |= CODEC_FLAG_LOOP_FILTER; |
|
3249 |
- } |
|
3250 |
- |
|
3251 |
- if(use_part) { |
|
3252 |
- video_enc->flags |= CODEC_FLAG_PART; |
|
3253 |
- } |
|
3254 |
- if (use_alt_scan) { |
|
3255 |
- video_enc->flags |= CODEC_FLAG_ALT_SCAN; |
|
3256 |
- } |
|
3257 |
- if (use_trell) { |
|
3258 |
- video_enc->flags |= CODEC_FLAG_TRELLIS_QUANT; |
|
3259 |
- } |
|
3260 |
- if (use_mv0) { |
|
3261 |
- video_enc->flags |= CODEC_FLAG_MV0; |
|
3262 |
- } |
|
3263 |
- if (do_normalize_aqp) { |
|
3264 |
- video_enc->flags |= CODEC_FLAG_NORMALIZE_AQP; |
|
3265 |
- } |
|
3266 |
- if (use_scan_offset) { |
|
3267 |
- video_enc->flags |= CODEC_FLAG_SVCD_SCAN_OFFSET; |
|
3268 |
- } |
|
3269 |
- if (closed_gop) { |
|
3270 |
- video_enc->flags |= CODEC_FLAG_CLOSED_GOP; |
|
3271 |
- } |
|
3272 |
- if (strict_gop) { |
|
3273 |
- video_enc->flags2 |= CODEC_FLAG2_STRICT_GOP; |
|
3274 |
- } |
|
3275 |
- if (use_qpel) { |
|
3276 |
- video_enc->flags |= CODEC_FLAG_QPEL; |
|
3277 |
- } |
|
3278 |
- if (use_qprd) { |
|
3279 |
- video_enc->flags |= CODEC_FLAG_QP_RD; |
|
3280 |
- } |
|
3281 |
- if (use_cbprd) { |
|
3282 |
- video_enc->flags |= CODEC_FLAG_CBP_RD; |
|
3283 |
- } |
|
3284 |
- if (b_frames) { |
|
3285 |
- video_enc->max_b_frames = b_frames; |
|
3286 |
- video_enc->b_frame_strategy = b_strategy; |
|
3287 |
- video_enc->b_quant_factor = 2.0; |
|
3288 |
- } |
|
3289 |
- if (do_interlace_dct) { |
|
3290 |
- video_enc->flags |= CODEC_FLAG_INTERLACED_DCT; |
|
3291 |
- } |
|
3292 |
- if (do_interlace_me) { |
|
3293 |
- video_enc->flags |= CODEC_FLAG_INTERLACED_ME; |
|
3294 |
- } |
|
3295 |
- if (no_output) { |
|
3296 |
- video_enc->flags2 |= CODEC_FLAG2_NO_OUTPUT; |
|
3297 |
- } |
|
3298 |
- if (gray_only) { |
|
3299 |
- video_enc->flags |= CODEC_FLAG_GRAY; |
|
3300 |
- } |
|
3301 |
- video_enc->qmin = video_qmin; |
|
3302 |
- video_enc->qmax = video_qmax; |
|
3303 |
- video_enc->lmin = video_lmin; |
|
3304 |
- video_enc->lmax = video_lmax; |
|
3305 |
- video_enc->rc_qsquish = video_qsquish; |
|
3306 |
- video_enc->luma_elim_threshold = video_lelim; |
|
3307 |
- video_enc->chroma_elim_threshold = video_celim; |
|
3308 |
- video_enc->mb_lmin = video_mb_lmin; |
|
3309 |
- video_enc->mb_lmax = video_mb_lmax; |
|
3310 |
- video_enc->max_qdiff = video_qdiff; |
|
3311 |
- video_enc->qblur = video_qblur; |
|
3312 |
- video_enc->qcompress = video_qcomp; |
|
3313 |
- video_enc->rc_eq = video_rc_eq; |
|
3314 |
- video_enc->debug = debug; |
|
3315 |
- video_enc->debug_mv = debug_mv; |
|
3316 |
- video_enc->workaround_bugs = workaround_bugs; |
|
3317 |
- video_enc->thread_count = thread_count; |
|
3318 |
- p= video_rc_override_string; |
|
3319 |
- for(i=0; p; i++){ |
|
3320 |
- int start, end, q; |
|
3321 |
- int e=sscanf(p, "%d,%d,%d", &start, &end, &q); |
|
3322 |
- if(e!=3){ |
|
3323 |
- fprintf(stderr, "error parsing rc_override\n"); |
|
3324 |
- exit(1); |
|
3325 |
- } |
|
3326 |
- video_enc->rc_override= |
|
3327 |
- av_realloc(video_enc->rc_override, |
|
3328 |
- sizeof(RcOverride)*(i+1)); |
|
3329 |
- video_enc->rc_override[i].start_frame= start; |
|
3330 |
- video_enc->rc_override[i].end_frame = end; |
|
3331 |
- if(q>0){ |
|
3332 |
- video_enc->rc_override[i].qscale= q; |
|
3333 |
- video_enc->rc_override[i].quality_factor= 1.0; |
|
3334 |
- } |
|
3335 |
- else{ |
|
3336 |
- video_enc->rc_override[i].qscale= 0; |
|
3337 |
- video_enc->rc_override[i].quality_factor= -q/100.0; |
|
3338 |
- } |
|
3339 |
- p= strchr(p, '/'); |
|
3340 |
- if(p) p++; |
|
3341 |
- } |
|
3342 |
- video_enc->rc_override_count=i; |
|
3343 |
- |
|
3344 |
- video_enc->rc_max_rate = video_rc_max_rate; |
|
3345 |
- video_enc->rc_min_rate = video_rc_min_rate; |
|
3346 |
- video_enc->rc_buffer_size = video_rc_buffer_size; |
|
3347 |
- video_enc->rc_initial_buffer_occupancy = video_rc_buffer_size*3/4; |
|
3348 |
- video_enc->rc_buffer_aggressivity= video_rc_buffer_aggressivity; |
|
3349 |
- video_enc->rc_initial_cplx= video_rc_initial_cplx; |
|
3350 |
- video_enc->i_quant_factor = video_i_qfactor; |
|
3351 |
- video_enc->b_quant_factor = video_b_qfactor; |
|
3352 |
- video_enc->i_quant_offset = video_i_qoffset; |
|
3353 |
- video_enc->b_quant_offset = video_b_qoffset; |
|
3354 |
- video_enc->intra_quant_bias = video_intra_quant_bias; |
|
3355 |
- video_enc->inter_quant_bias = video_inter_quant_bias; |
|
3356 |
- video_enc->dct_algo = dct_algo; |
|
3357 |
- video_enc->idct_algo = idct_algo; |
|
3358 |
- video_enc->me_threshold= me_threshold; |
|
3359 |
- video_enc->mb_threshold= mb_threshold; |
|
3360 |
- video_enc->intra_dc_precision= intra_dc_precision - 8; |
|
3361 |
- video_enc->strict_std_compliance = strict; |
|
3362 |
- video_enc->error_rate = error_rate; |
|
3363 |
- video_enc->noise_reduction= noise_reduction; |
|
3364 |
- video_enc->scenechange_threshold= sc_threshold; |
|
3365 |
- video_enc->me_range = me_range; |
|
3366 |
- video_enc->coder_type= coder; |
|
3367 |
- video_enc->context_model= context; |
|
3368 |
- video_enc->prediction_method= predictor; |
|
3369 |
- video_enc->profile= video_profile; |
|
3370 |
- video_enc->level= video_level; |
|
3371 |
- video_enc->nsse_weight= nsse_weight; |
|
3372 |
- video_enc->me_subpel_quality= subpel_quality; |
|
3373 |
- video_enc->me_penalty_compensation= me_penalty_compensation; |
|
3374 |
- video_enc->frame_skip_threshold= frame_skip_threshold; |
|
3375 |
- video_enc->frame_skip_factor= frame_skip_factor; |
|
3376 |
- video_enc->frame_skip_exp= frame_skip_exp; |
|
3377 |
- video_enc->frame_skip_cmp= frame_skip_cmp; |
|
3378 |
- |
|
3379 |
- if(packet_size){ |
|
3380 |
- video_enc->rtp_mode= 1; |
|
3381 |
- video_enc->rtp_payload_size= packet_size; |
|
3382 |
- } |
|
3383 |
- |
|
3384 |
- if (do_psnr) |
|
3385 |
- video_enc->flags|= CODEC_FLAG_PSNR; |
|
3386 |
- |
|
3387 |
- video_enc->me_method = me_method; |
|
3388 |
- |
|
3389 |
- /* two pass mode */ |
|
3390 |
- if (do_pass) { |
|
3391 |
- if (do_pass == 1) { |
|
3392 |
- video_enc->flags |= CODEC_FLAG_PASS1; |
|
3393 |
- } else { |
|
3394 |
- video_enc->flags |= CODEC_FLAG_PASS2; |
|
3395 |
- } |
|
3396 |
- } |
|
3397 |
- } |
|
3126 |
+ new_video_stream(oc); |
|
3398 | 3127 |
} |
3399 | 3128 |
|
3400 | 3129 |
if (use_audio) { |
3401 |
- AVCodecContext *audio_enc; |
|
3402 |
- |
|
3403 |
- st = av_new_stream(oc, nb_streams++); |
|
3404 |
- if (!st) { |
|
3405 |
- fprintf(stderr, "Could not alloc stream\n"); |
|
3406 |
- exit(1); |
|
3407 |
- } |
|
3408 |
-#if defined(HAVE_THREADS) |
|
3409 |
- if(thread_count>1) |
|
3410 |
- avcodec_thread_init(&st->codec, thread_count); |
|
3411 |
-#endif |
|
3412 |
- |
|
3413 |
- audio_enc = &st->codec; |
|
3414 |
- audio_enc->codec_type = CODEC_TYPE_AUDIO; |
|
3415 |
- |
|
3416 |
- if(audio_codec_tag) |
|
3417 |
- audio_enc->codec_tag= audio_codec_tag; |
|
3418 |
- |
|
3419 |
- if (file_oformat->flags & AVFMT_GLOBALHEADER) |
|
3420 |
- audio_enc->flags |= CODEC_FLAG_GLOBAL_HEADER; |
|
3421 |
- if (audio_stream_copy) { |
|
3422 |
- st->stream_copy = 1; |
|
3423 |
- audio_enc->channels = audio_channels; |
|
3424 |
- } else { |
|
3425 |
- codec_id = av_guess_codec(file_oformat, NULL, filename, NULL, CODEC_TYPE_AUDIO); |
|
3426 |
- if (audio_codec_id != CODEC_ID_NONE) |
|
3427 |
- codec_id = audio_codec_id; |
|
3428 |
- audio_enc->codec_id = codec_id; |
|
3429 |
- |
|
3430 |
- audio_enc->bit_rate = audio_bit_rate; |
|
3431 |
- audio_enc->strict_std_compliance = strict; |
|
3432 |
- audio_enc->thread_count = thread_count; |
|
3433 |
- /* For audio codecs other than AC3 or DTS we limit */ |
|
3434 |
- /* the number of coded channels to stereo */ |
|
3435 |
- if (audio_channels > 2 && codec_id != CODEC_ID_AC3 |
|
3436 |
- && codec_id != CODEC_ID_DTS) { |
|
3437 |
- audio_enc->channels = 2; |
|
3438 |
- } else |
|
3439 |
- audio_enc->channels = audio_channels; |
|
3440 |
- } |
|
3441 |
- audio_enc->sample_rate = audio_sample_rate; |
|
3130 |
+ new_audio_stream(oc); |
|
3442 | 3131 |
} |
3443 | 3132 |
|
3444 |
- oc->nb_streams = nb_streams; |
|
3445 |
- |
|
3446 |
- if (!nb_streams) { |
|
3133 |
+ if (!oc->nb_streams) { |
|
3447 | 3134 |
fprintf(stderr, "No audio or video streams available\n"); |
3448 | 3135 |
exit(1); |
3449 | 3136 |
} |
... | ... |
@@ -3462,8 +3637,6 @@ static void opt_output_file(const char *filename) |
3462 | 3462 |
|
3463 | 3463 |
output_files[nb_output_files++] = oc; |
3464 | 3464 |
|
3465 |
- pstrcpy(oc->filename, sizeof(oc->filename), filename); |
|
3466 |
- |
|
3467 | 3465 |
/* check filename in case of an image number is expected */ |
3468 | 3466 |
if (oc->oformat->flags & AVFMT_NEEDNUMBER) { |
3469 | 3467 |
if (filename_number_test(oc->filename) < 0) { |
... | ... |
@@ -3520,12 +3693,6 @@ static void opt_output_file(const char *filename) |
3520 | 3520 |
file_oformat = NULL; |
3521 | 3521 |
file_iformat = NULL; |
3522 | 3522 |
image_format = NULL; |
3523 |
- audio_disable = 0; |
|
3524 |
- video_disable = 0; |
|
3525 |
- audio_codec_id = CODEC_ID_NONE; |
|
3526 |
- video_codec_id = CODEC_ID_NONE; |
|
3527 |
- audio_stream_copy = 0; |
|
3528 |
- video_stream_copy = 0; |
|
3529 | 3523 |
} |
3530 | 3524 |
|
3531 | 3525 |
/* prepare dummy protocols for grab */ |
... | ... |
@@ -3722,6 +3889,7 @@ static void show_formats(void) |
3722 | 3722 |
int decode=0; |
3723 | 3723 |
int encode=0; |
3724 | 3724 |
int cap=0; |
3725 |
+ const char *type_str; |
|
3725 | 3726 |
|
3726 | 3727 |
p2=NULL; |
3727 | 3728 |
for(p = first_avcodec; p != NULL; p = p->next) { |
... | ... |
@@ -3740,11 +3908,25 @@ static void show_formats(void) |
3740 | 3740 |
break; |
3741 | 3741 |
last_name= p2->name; |
3742 | 3742 |
|
3743 |
+ switch(p2->type) { |
|
3744 |
+ case CODEC_TYPE_VIDEO: |
|
3745 |
+ type_str = "V"; |
|
3746 |
+ break; |
|
3747 |
+ case CODEC_TYPE_AUDIO: |
|
3748 |
+ type_str = "A"; |
|
3749 |
+ break; |
|
3750 |
+ case CODEC_TYPE_SUBTITLE: |
|
3751 |
+ type_str = "S"; |
|
3752 |
+ break; |
|
3753 |
+ default: |
|
3754 |
+ type_str = "?"; |
|
3755 |
+ break; |
|
3756 |
+ } |
|
3743 | 3757 |
printf( |
3744 | 3758 |
" %s%s%s%s%s%s %s", |
3745 | 3759 |
decode ? "D": (/*p2->decoder ? "d":*/" "), |
3746 | 3760 |
encode ? "E":" ", |
3747 |
- p2->type == CODEC_TYPE_AUDIO ? "A":"V", |
|
3761 |
+ type_str, |
|
3748 | 3762 |
cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S":" ", |
3749 | 3763 |
cap & CODEC_CAP_DR1 ? "D":" ", |
3750 | 3764 |
cap & CODEC_CAP_TRUNCATED ? "T":" ", |
... | ... |
@@ -4132,7 +4314,8 @@ const OptionDef options[] = { |
4132 | 4132 |
{ "skip_factor", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&frame_skip_factor}, "frame skip factor", "factor" }, |
4133 | 4133 |
{ "skip_exp", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&frame_skip_exp}, "frame skip exponent", "exponent" }, |
4134 | 4134 |
{ "skip_cmp", OPT_INT | HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)&frame_skip_cmp}, "frame skip compare function", "compare function" }, |
4135 |
- { "gray", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, { &gray_only }, "encode/decode grayscale" }, |
|
4135 |
+ { "gray", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, { (void *)&gray_only }, "encode/decode grayscale" }, |
|
4136 |
+ { "newvideo", OPT_VIDEO, {(void*)opt_new_video_stream}, "add a new video stream to the current output stream" }, |
|
4136 | 4137 |
|
4137 | 4138 |
/* audio options */ |
4138 | 4139 |
{ "ab", HAS_ARG | OPT_AUDIO, {(void*)opt_audio_bitrate}, "set audio bitrate (in kbit/s)", "bitrate", }, |
... | ... |
@@ -4142,7 +4325,14 @@ const OptionDef options[] = { |
4142 | 4142 |
{ "acodec", HAS_ARG | OPT_AUDIO, {(void*)opt_audio_codec}, "force audio codec ('copy' to copy stream)", "codec" }, |
4143 | 4143 |
{ "atag", HAS_ARG | OPT_EXPERT | OPT_AUDIO, {(void*)opt_audio_tag}, "force audio tag/fourcc", "fourcc/tag" }, |
4144 | 4144 |
{ "vol", OPT_INT | HAS_ARG | OPT_AUDIO, {(void*)&audio_volume}, "change audio volume (256=normal)" , "volume" }, // |
4145 |
+ { "newaudio", OPT_AUDIO, {(void*)opt_new_audio_stream}, "add a new audio stream to the current output stream" }, |
|
4146 |
+ { "alang", HAS_ARG | OPT_STRING | OPT_AUDIO, {(void *)&audio_language}, "set the ISO 639 language code (3 letters) of the current audio stream" , "code" }, |
|
4145 | 4147 |
|
4148 |
+ /* subtitle options */ |
|
4149 |
+ { "scodec", HAS_ARG | OPT_SUBTITLE, {(void*)opt_subtitle_codec}, "force subtitle codec ('copy' to copy stream)", "codec" }, |
|
4150 |
+ { "newsubtitle", OPT_SUBTITLE, {(void*)opt_new_subtitle_stream}, "add a new subtitle stream to the current output stream" }, |
|
4151 |
+ { "slang", HAS_ARG | OPT_STRING | OPT_SUBTITLE, {(void *)&subtitle_language}, "set the ISO 639 language code (3 letters) of the current subtitle stream" , "code" }, |
|
4152 |
+ |
|
4146 | 4153 |
/* grab options */ |
4147 | 4154 |
{ "vd", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_GRAB, {(void*)opt_video_device}, "set video grab device", "device" }, |
4148 | 4155 |
{ "vc", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_GRAB, {(void*)opt_video_channel}, "set video grab channel (DV1394 only)", "channel" }, |
... | ... |
@@ -4233,6 +4423,9 @@ static void show_help(void) |
4233 | 4233 |
show_help_options(options, "\nAdvanced Audio options:\n", |
4234 | 4234 |
OPT_EXPERT | OPT_AUDIO | OPT_VIDEO | OPT_GRAB, |
4235 | 4235 |
OPT_AUDIO | OPT_EXPERT); |
4236 |
+ show_help_options(options, "\nSubtitle options:\n", |
|
4237 |
+ OPT_SUBTITLE | OPT_GRAB, |
|
4238 |
+ OPT_SUBTITLE); |
|
4236 | 4239 |
show_help_options(options, "\nAudio/Video grab options:\n", |
4237 | 4240 |
OPT_GRAB, |
4238 | 4241 |
OPT_GRAB); |