Merge remote-tracking branch 'qatar/master'
[ffmpeg.git] / ffmpeg.c
index 3e20d44..9661869 100644 (file)
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -704,9 +704,17 @@ static const enum PixelFormat *choose_pixel_fmts(OutputStream *ost)
     if (ost->st->codec->pix_fmt != PIX_FMT_NONE) {
         ost->pix_fmts[0] = choose_pixel_fmt(ost->st, ost->enc, ost->st->codec->pix_fmt);
         return ost->pix_fmts;
-    } else if (ost->enc->pix_fmts)
+    } else if (ost->enc->pix_fmts) {
+        if (ost->st->codec->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
+            if (ost->st->codec->codec_id == CODEC_ID_MJPEG) {
+                return (const enum PixelFormat[]) { PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_NONE };
+            } else if (ost->st->codec->codec_id == CODEC_ID_LJPEG) {
+                return (const enum PixelFormat[]) { PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, PIX_FMT_YUVJ444P, PIX_FMT_YUV420P,
+                                                    PIX_FMT_YUV422P, PIX_FMT_YUV444P, PIX_FMT_BGRA, PIX_FMT_NONE };
+            }
+        }
         return ost->enc->pix_fmts;
-    else
+    else
         return NULL;
 }
 
@@ -2484,6 +2492,9 @@ static int transcode_video(InputStream *ist, AVPacket *pkt, int *got_output, int
     quality = same_quant ? decoded_frame->quality : 0;
     if (!*got_output) {
         /* no picture yet */
+        if (!pkt->size)
+            for (i = 0; i < ist->nb_filters; i++)
+                av_buffersrc_buffer(ist->filters[i]->filter, NULL);
         return ret;
     }
 
@@ -3432,7 +3443,7 @@ static int transcode(void)
             if (ost->is_past_recording_time ||
                 (os->pb && avio_tell(os->pb) >= of->limit_filesize))
                 continue;
-            if (ost->frame_number > ost->max_frames) {
+            if (ost->frame_number >= ost->max_frames) {
                 int j;
                 for (j = 0; j < of->ctx->nb_streams; j++)
                     output_streams[of->ost_index + j]->is_past_recording_time = 1;
@@ -3480,6 +3491,13 @@ static int transcode(void)
         }
         if (ret < 0) {
             input_files[file_index]->eof_reached = 1;
+
+            for (i = 0; i < input_files[file_index]->nb_streams; i++) {
+                ist = input_streams[input_files[file_index]->ist_index + i];
+                if (ist->decoding_needed)
+                    output_packet(ist, NULL);
+            }
+
             if (opt_shortest)
                 break;
             else
@@ -3578,7 +3596,7 @@ static int transcode(void)
     /* at the end of stream, we must flush the decoder buffers */
     for (i = 0; i < nb_input_streams; i++) {
         ist = input_streams[i];
-        if (ist->decoding_needed) {
+        if (!input_files[ist->file_index]->eof_reached && ist->decoding_needed) {
             output_packet(ist, NULL);
         }
     }
@@ -3738,41 +3756,41 @@ static int opt_map(OptionsContext *o, const char *opt, const char *arg)
             exit_program(1);
         }
     } else {
-    file_idx = strtol(map, &p, 0);
-    if (file_idx >= nb_input_files || file_idx < 0) {
-        av_log(NULL, AV_LOG_FATAL, "Invalid input file index: %d.\n", file_idx);
-        exit_program(1);
-    }
-    if (negative)
-        /* disable some already defined maps */
-        for (i = 0; i < o->nb_stream_maps; i++) {
-            m = &o->stream_maps[i];
-            if (file_idx == m->file_index &&
-                check_stream_specifier(input_files[m->file_index]->ctx,
-                                       input_files[m->file_index]->ctx->streams[m->stream_index],
-                                       *p == ':' ? p + 1 : p) > 0)
-                m->disabled = 1;
+        file_idx = strtol(map, &p, 0);
+        if (file_idx >= nb_input_files || file_idx < 0) {
+            av_log(NULL, AV_LOG_FATAL, "Invalid input file index: %d.\n", file_idx);
+            exit_program(1);
         }
-    else
-        for (i = 0; i < input_files[file_idx]->nb_streams; i++) {
-            if (check_stream_specifier(input_files[file_idx]->ctx, input_files[file_idx]->ctx->streams[i],
-                        *p == ':' ? p + 1 : p) <= 0)
-                continue;
-            o->stream_maps = grow_array(o->stream_maps, sizeof(*o->stream_maps),
-                                        &o->nb_stream_maps, o->nb_stream_maps + 1);
-            m = &o->stream_maps[o->nb_stream_maps - 1];
-
-            m->file_index   = file_idx;
-            m->stream_index = i;
-
-            if (sync_file_idx >= 0) {
-                m->sync_file_index   = sync_file_idx;
-                m->sync_stream_index = sync_stream_idx;
-            } else {
-                m->sync_file_index   = file_idx;
-                m->sync_stream_index = i;
+        if (negative)
+            /* disable some already defined maps */
+            for (i = 0; i < o->nb_stream_maps; i++) {
+                m = &o->stream_maps[i];
+                if (file_idx == m->file_index &&
+                    check_stream_specifier(input_files[m->file_index]->ctx,
+                                           input_files[m->file_index]->ctx->streams[m->stream_index],
+                                           *p == ':' ? p + 1 : p) > 0)
+                    m->disabled = 1;
+            }
+        else
+            for (i = 0; i < input_files[file_idx]->nb_streams; i++) {
+                if (check_stream_specifier(input_files[file_idx]->ctx, input_files[file_idx]->ctx->streams[i],
+                            *p == ':' ? p + 1 : p) <= 0)
+                    continue;
+                o->stream_maps = grow_array(o->stream_maps, sizeof(*o->stream_maps),
+                                            &o->nb_stream_maps, o->nb_stream_maps + 1);
+                m = &o->stream_maps[o->nb_stream_maps - 1];
+
+                m->file_index   = file_idx;
+                m->stream_index = i;
+
+                if (sync_file_idx >= 0) {
+                    m->sync_file_index   = sync_file_idx;
+                    m->sync_stream_index = sync_stream_idx;
+                } else {
+                    m->sync_file_index   = file_idx;
+                    m->sync_stream_index = i;
+                }
             }
-        }
     }
 
     if (!m) {
@@ -4171,8 +4189,16 @@ static int opt_input_file(OptionsContext *o, const char *opt, const char *filena
         av_dict_set(&format_opts, "sample_rate", buf, 0);
     }
     if (o->nb_audio_channels) {
-        snprintf(buf, sizeof(buf), "%d", o->audio_channels[o->nb_audio_channels - 1].u.i);
-        av_dict_set(&format_opts, "channels", buf, 0);
+        /* because we set audio_channels based on both the "ac" and
+         * "channel_layout" options, we need to check that the specified
+         * demuxer actually has the "channels" option before setting it */
+        if (file_iformat && file_iformat->priv_class &&
+            av_opt_find(&file_iformat->priv_class, "channels", NULL, 0,
+                        AV_OPT_SEARCH_FAKE_OBJ)) {
+            snprintf(buf, sizeof(buf), "%d",
+                     o->audio_channels[o->nb_audio_channels - 1].u.i);
+            av_dict_set(&format_opts, "channels", buf, 0);
+        }
     }
     if (o->nb_frame_rates) {
         av_dict_set(&format_opts, "framerate", o->frame_rates[o->nb_frame_rates - 1].u.str, 0);
@@ -4963,28 +4989,27 @@ loop_end:
                 }
                 init_output_filter(ofilter, o, oc);
             } else {
-            ist = input_streams[input_files[map->file_index]->ist_index + map->stream_index];
-            if(o->subtitle_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE)
-                continue;
-            if(o->   audio_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
-                continue;
-            if(o->   video_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
-                continue;
-            if(o->    data_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_DATA)
-                continue;
-
-            switch (ist->st->codec->codec_type) {
-            case AVMEDIA_TYPE_VIDEO:    ost = new_video_stream(o, oc, src_idx);    break;
-            case AVMEDIA_TYPE_AUDIO:    ost = new_audio_stream(o, oc, src_idx);    break;
-            case AVMEDIA_TYPE_SUBTITLE: ost = new_subtitle_stream(o, oc, src_idx); break;
-            case AVMEDIA_TYPE_DATA:     ost = new_data_stream(o, oc, src_idx);     break;
-            case AVMEDIA_TYPE_ATTACHMENT: ost = new_attachment_stream(o, oc, src_idx); break;
-            default:
-                av_log(NULL, AV_LOG_FATAL, "Cannot map stream #%d:%d - unsupported type.\n",
-                       map->file_index, map->stream_index);
-                exit_program(1);
-            }
-
+                ist = input_streams[input_files[map->file_index]->ist_index + map->stream_index];
+                if(o->subtitle_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE)
+                    continue;
+                if(o->   audio_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
+                    continue;
+                if(o->   video_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
+                    continue;
+                if(o->    data_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_DATA)
+                    continue;
+
+                switch (ist->st->codec->codec_type) {
+                case AVMEDIA_TYPE_VIDEO:      ost = new_video_stream     (o, oc, src_idx); break;
+                case AVMEDIA_TYPE_AUDIO:      ost = new_audio_stream     (o, oc, src_idx); break;
+                case AVMEDIA_TYPE_SUBTITLE:   ost = new_subtitle_stream  (o, oc, src_idx); break;
+                case AVMEDIA_TYPE_DATA:       ost = new_data_stream      (o, oc, src_idx); break;
+                case AVMEDIA_TYPE_ATTACHMENT: ost = new_attachment_stream(o, oc, src_idx); break;
+                default:
+                    av_log(NULL, AV_LOG_FATAL, "Cannot map stream #%d:%d - unsupported type.\n",
+                        map->file_index, map->stream_index);
+                    exit_program(1);
+                }
             }
         }
     }