]> git.sesse.net Git - ffmpeg/blobdiff - ffmpeg.c
fate: add bprint test.
[ffmpeg] / ffmpeg.c
index a897c9e917aca8c9043d27868b3aa391b1619fca..87c3f7a5d34b1387308f8a6bfd13e3281d49795d 100644 (file)
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -201,19 +201,6 @@ typedef struct FilterGraph {
     int         nb_outputs;
 } FilterGraph;
 
-typedef struct FrameBuffer {
-    uint8_t *base[4];
-    uint8_t *data[4];
-    int  linesize[4];
-
-    int h, w;
-    enum PixelFormat pix_fmt;
-
-    int refcount;
-    struct InputStream *ist;
-    struct FrameBuffer *next;
-} FrameBuffer;
-
 typedef struct InputStream {
     int file_index;
     AVStream *st;
@@ -534,145 +521,6 @@ static void reset_options(OptionsContext *o, int is_input)
     init_opts();
 }
 
-static int alloc_buffer(InputStream *ist, AVCodecContext *s, FrameBuffer **pbuf)
-{
-    FrameBuffer  *buf = av_mallocz(sizeof(*buf));
-    int i, ret;
-    const int pixel_size = av_pix_fmt_descriptors[s->pix_fmt].comp[0].step_minus1+1;
-    int h_chroma_shift, v_chroma_shift;
-    int edge = 32; // XXX should be avcodec_get_edge_width(), but that fails on svq1
-    int w = s->width, h = s->height;
-
-    if (!buf)
-        return AVERROR(ENOMEM);
-
-    avcodec_align_dimensions(s, &w, &h);
-
-    if (!(s->flags & CODEC_FLAG_EMU_EDGE)) {
-        w += 2*edge;
-        h += 2*edge;
-    }
-
-    if ((ret = av_image_alloc(buf->base, buf->linesize, w, h,
-                              s->pix_fmt, 32)) < 0) {
-        av_freep(&buf);
-        return ret;
-    }
-    /* XXX this shouldn't be needed, but some tests break without this line
-     * those decoders are buggy and need to be fixed.
-     * the following tests fail:
-     * cdgraphics, ansi, aasc, fraps-v1, qtrle-1bit
-     */
-    memset(buf->base[0], 128, ret);
-
-    avcodec_get_chroma_sub_sample(s->pix_fmt, &h_chroma_shift, &v_chroma_shift);
-    for (i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) {
-        const int h_shift = i==0 ? 0 : h_chroma_shift;
-        const int v_shift = i==0 ? 0 : v_chroma_shift;
-        if ((s->flags & CODEC_FLAG_EMU_EDGE) || !buf->linesize[1] || !buf->base[i])
-            buf->data[i] = buf->base[i];
-        else
-            buf->data[i] = buf->base[i] +
-                           FFALIGN((buf->linesize[i]*edge >> v_shift) +
-                                   (pixel_size*edge >> h_shift), 32);
-    }
-    buf->w       = s->width;
-    buf->h       = s->height;
-    buf->pix_fmt = s->pix_fmt;
-    buf->ist     = ist;
-
-    *pbuf = buf;
-    return 0;
-}
-
-static void free_buffer_pool(InputStream *ist)
-{
-    FrameBuffer *buf = ist->buffer_pool;
-    while (buf) {
-        ist->buffer_pool = buf->next;
-        av_freep(&buf->base[0]);
-        av_free(buf);
-        buf = ist->buffer_pool;
-    }
-}
-
-static void unref_buffer(InputStream *ist, FrameBuffer *buf)
-{
-    av_assert0(buf->refcount > 0);
-    buf->refcount--;
-    if (!buf->refcount) {
-        FrameBuffer *tmp;
-        for(tmp= ist->buffer_pool; tmp; tmp= tmp->next)
-            av_assert1(tmp != buf);
-        buf->next = ist->buffer_pool;
-        ist->buffer_pool = buf;
-    }
-}
-
-static int codec_get_buffer(AVCodecContext *s, AVFrame *frame)
-{
-    InputStream *ist = s->opaque;
-    FrameBuffer *buf;
-    int ret, i;
-
-    if(av_image_check_size(s->width, s->height, 0, s) || s->pix_fmt<0)
-        return -1;
-
-    if (!ist->buffer_pool && (ret = alloc_buffer(ist, s, &ist->buffer_pool)) < 0)
-        return ret;
-
-    buf              = ist->buffer_pool;
-    ist->buffer_pool = buf->next;
-    buf->next        = NULL;
-    if (buf->w != s->width || buf->h != s->height || buf->pix_fmt != s->pix_fmt) {
-        av_freep(&buf->base[0]);
-        av_free(buf);
-        if ((ret = alloc_buffer(ist, s, &buf)) < 0)
-            return ret;
-    }
-    av_assert0(!buf->refcount);
-    buf->refcount++;
-
-    frame->opaque        = buf;
-    frame->type          = FF_BUFFER_TYPE_USER;
-    frame->extended_data = frame->data;
-    frame->pkt_pts       = s->pkt ? s->pkt->pts : AV_NOPTS_VALUE;
-    frame->width         = buf->w;
-    frame->height        = buf->h;
-    frame->format        = buf->pix_fmt;
-    frame->sample_aspect_ratio = s->sample_aspect_ratio;
-
-    for (i = 0; i < FF_ARRAY_ELEMS(buf->data); i++) {
-        frame->base[i]     = buf->base[i];  // XXX h264.c uses base though it shouldn't
-        frame->data[i]     = buf->data[i];
-        frame->linesize[i] = buf->linesize[i];
-    }
-
-    return 0;
-}
-
-static void codec_release_buffer(AVCodecContext *s, AVFrame *frame)
-{
-    InputStream *ist = s->opaque;
-    FrameBuffer *buf = frame->opaque;
-    int i;
-
-    if(frame->type!=FF_BUFFER_TYPE_USER)
-        return avcodec_default_release_buffer(s, frame);
-
-    for (i = 0; i < FF_ARRAY_ELEMS(frame->data); i++)
-        frame->data[i] = NULL;
-
-    unref_buffer(ist, buf);
-}
-
-static void filter_release_buffer(AVFilterBuffer *fb)
-{
-    FrameBuffer *buf = fb->priv;
-    av_free(fb);
-    unref_buffer(buf->ist, buf);
-}
-
 static enum PixelFormat choose_pixel_fmt(AVStream *st, AVCodec *codec, enum PixelFormat target)
 {
     if (codec && codec->pix_fmts) {
@@ -1369,8 +1217,11 @@ static void term_init(void)
 #if HAVE_TERMIOS_H
     if(!run_as_daemon){
         struct termios tty;
-
-        if (tcgetattr (0, &tty) == 0) {
+        int istty = 1;
+#if HAVE_ISATTY
+        istty = isatty(0) && isatty(2);
+#endif
+        if (istty && tcgetattr (0, &tty) == 0) {
             oldtty = tty;
             restore_tty = 1;
             atexit(term_exit);
@@ -1508,7 +1359,7 @@ void av_noreturn exit_program(int ret)
     for (i = 0; i < nb_input_streams; i++) {
         av_freep(&input_streams[i]->decoded_frame);
         av_dict_free(&input_streams[i]->opts);
-        free_buffer_pool(input_streams[i]);
+        free_buffer_pool(&input_streams[i]->buffer_pool);
         av_freep(&input_streams[i]->filters);
         av_freep(&input_streams[i]);
     }
@@ -1799,6 +1650,7 @@ static void do_subtitle_out(AVFormatContext *s,
         pkt.data = subtitle_out;
         pkt.size = subtitle_out_size;
         pkt.pts  = av_rescale_q(sub->pts, AV_TIME_BASE_Q, ost->st->time_base);
+        pkt.duration = av_rescale_q(sub->end_display_time, (AVRational){ 1, 1000 }, ost->st->time_base);
         if (enc->codec_id == CODEC_ID_DVB_SUBTITLE) {
             /* XXX: the pts correction is handled here. Maybe handling
                it in the codec would be better */
@@ -2845,7 +2697,7 @@ static int init_input_stream(int ist_index, char *error, int error_len)
         if (codec->type == AVMEDIA_TYPE_VIDEO && ist->dr1) {
             ist->st->codec->get_buffer     = codec_get_buffer;
             ist->st->codec->release_buffer = codec_release_buffer;
-            ist->st->codec->opaque         = ist;
+            ist->st->codec->opaque         = &ist->buffer_pool;
         }
 
         if (!av_dict_get(ist->opts, "threads", NULL, 0))
@@ -3358,6 +3210,99 @@ static int select_input_file(uint8_t *no_packet)
     return file_index;
 }
 
+static int check_keyboard_interaction(int64_t cur_time)
+{
+    int i, ret, key;
+    static int64_t last_time;
+    if (received_nb_signals)
+        return AVERROR_EXIT;
+    /* read_key() returns 0 on EOF */
+    if(cur_time - last_time >= 100000 && !run_as_daemon){
+        key =  read_key();
+        last_time = cur_time;
+    }else
+        key = -1;
+    if (key == 'q')
+        return AVERROR_EXIT;
+    if (key == '+') av_log_set_level(av_log_get_level()+10);
+    if (key == '-') av_log_set_level(av_log_get_level()-10);
+    if (key == 's') qp_hist     ^= 1;
+    if (key == 'h'){
+        if (do_hex_dump){
+            do_hex_dump = do_pkt_dump = 0;
+        } else if(do_pkt_dump){
+            do_hex_dump = 1;
+        } else
+            do_pkt_dump = 1;
+        av_log_set_level(AV_LOG_DEBUG);
+    }
+    if (key == 'c' || key == 'C'){
+        char buf[4096], target[64], command[256], arg[256] = {0};
+        double time;
+        int k, n = 0;
+        fprintf(stderr, "\nEnter command: <target> <time> <command>[ <argument>]\n");
+        i = 0;
+        while ((k = read_key()) != '\n' && k != '\r' && i < sizeof(buf)-1)
+            if (k > 0)
+                buf[i++] = k;
+        buf[i] = 0;
+        if (k > 0 &&
+            (n = sscanf(buf, "%63[^ ] %lf %255[^ ] %255[^\n]", target, &time, command, arg)) >= 3) {
+            av_log(NULL, AV_LOG_DEBUG, "Processing command target:%s time:%f command:%s arg:%s",
+                   target, time, command, arg);
+            for (i = 0; i < nb_filtergraphs; i++) {
+                FilterGraph *fg = filtergraphs[i];
+                if (fg->graph) {
+                    if (time < 0) {
+                        ret = avfilter_graph_send_command(fg->graph, target, command, arg, buf, sizeof(buf),
+                                                          key == 'c' ? AVFILTER_CMD_FLAG_ONE : 0);
+                        fprintf(stderr, "Command reply for stream %d: ret:%d res:%s\n", i, ret, buf);
+                    } else {
+                        ret = avfilter_graph_queue_command(fg->graph, target, command, arg, 0, time);
+                    }
+                }
+            }
+        } else {
+            av_log(NULL, AV_LOG_ERROR,
+                   "Parse error, at least 3 arguments were expected, "
+                   "only %d given in string '%s'\n", n, buf);
+        }
+    }
+    if (key == 'd' || key == 'D'){
+        int debug=0;
+        if(key == 'D') {
+            debug = input_streams[0]->st->codec->debug<<1;
+            if(!debug) debug = 1;
+            while(debug & (FF_DEBUG_DCT_COEFF|FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE)) //unsupported, would just crash
+                debug += debug;
+        }else
+            if(scanf("%d", &debug)!=1)
+                fprintf(stderr,"error parsing debug value\n");
+        for(i=0;i<nb_input_streams;i++) {
+            input_streams[i]->st->codec->debug = debug;
+        }
+        for(i=0;i<nb_output_streams;i++) {
+            OutputStream *ost = output_streams[i];
+            ost->st->codec->debug = debug;
+        }
+        if(debug) av_log_set_level(AV_LOG_DEBUG);
+        fprintf(stderr,"debug=%d\n", debug);
+    }
+    if (key == '?'){
+        fprintf(stderr, "key    function\n"
+                        "?      show this help\n"
+                        "+      increase verbosity\n"
+                        "-      decrease verbosity\n"
+                        "c      Send command to filtergraph\n"
+                        "D      cycle through available debug modes\n"
+                        "h      dump packets/hex press to cycle through the 3 states\n"
+                        "q      quit\n"
+                        "s      Show QP histogram\n"
+        );
+    }
+    return 0;
+}
+
 /*
  * The following code is the main loop of the file converter
  */
@@ -3370,7 +3315,6 @@ static int transcode(void)
     uint8_t *no_packet;
     int no_packet_count = 0;
     int64_t timer_start;
-    int key;
 
     if (!(no_packet = av_mallocz(nb_input_files)))
         exit_program(1);
@@ -3391,95 +3335,9 @@ static int transcode(void)
         int64_t cur_time= av_gettime();
 
         /* if 'q' pressed, exits */
-        if (!using_stdin) {
-            static int64_t last_time;
-            if (received_nb_signals)
-                break;
-            /* read_key() returns 0 on EOF */
-            if(cur_time - last_time >= 100000 && !run_as_daemon){
-                key =  read_key();
-                last_time = cur_time;
-            }else
-                key = -1;
-            if (key == 'q')
+        if (!using_stdin)
+            if (check_keyboard_interaction(cur_time) < 0)
                 break;
-            if (key == '+') av_log_set_level(av_log_get_level()+10);
-            if (key == '-') av_log_set_level(av_log_get_level()-10);
-            if (key == 's') qp_hist     ^= 1;
-            if (key == 'h'){
-                if (do_hex_dump){
-                    do_hex_dump = do_pkt_dump = 0;
-                } else if(do_pkt_dump){
-                    do_hex_dump = 1;
-                } else
-                    do_pkt_dump = 1;
-                av_log_set_level(AV_LOG_DEBUG);
-            }
-            if (key == 'c' || key == 'C'){
-                char buf[4096], target[64], command[256], arg[256] = {0};
-                double time;
-                int k, n = 0;
-                fprintf(stderr, "\nEnter command: <target> <time> <command>[ <argument>]\n");
-                i = 0;
-                while ((k = read_key()) != '\n' && k != '\r' && i < sizeof(buf)-1)
-                    if (k > 0)
-                        buf[i++] = k;
-                buf[i] = 0;
-                if (k > 0 &&
-                    (n = sscanf(buf, "%63[^ ] %lf %255[^ ] %255[^\n]", target, &time, command, arg)) >= 3) {
-                    av_log(NULL, AV_LOG_DEBUG, "Processing command target:%s time:%f command:%s arg:%s",
-                           target, time, command, arg);
-                    for (i = 0; i < nb_filtergraphs; i++) {
-                        FilterGraph *fg = filtergraphs[i];
-                        if (fg->graph) {
-                            if (time < 0) {
-                                ret = avfilter_graph_send_command(fg->graph, target, command, arg, buf, sizeof(buf),
-                                                                  key == 'c' ? AVFILTER_CMD_FLAG_ONE : 0);
-                                fprintf(stderr, "Command reply for stream %d: ret:%d res:%s\n", i, ret, buf);
-                            } else {
-                                ret = avfilter_graph_queue_command(fg->graph, target, command, arg, 0, time);
-                            }
-                        }
-                    }
-                } else {
-                    av_log(NULL, AV_LOG_ERROR,
-                           "Parse error, at least 3 arguments were expected, "
-                           "only %d given in string '%s'\n", n, buf);
-                }
-            }
-            if (key == 'd' || key == 'D'){
-                int debug=0;
-                if(key == 'D') {
-                    debug = input_streams[0]->st->codec->debug<<1;
-                    if(!debug) debug = 1;
-                    while(debug & (FF_DEBUG_DCT_COEFF|FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE)) //unsupported, would just crash
-                        debug += debug;
-                }else
-                    if(scanf("%d", &debug)!=1)
-                        fprintf(stderr,"error parsing debug value\n");
-                for(i=0;i<nb_input_streams;i++) {
-                    input_streams[i]->st->codec->debug = debug;
-                }
-                for(i=0;i<nb_output_streams;i++) {
-                    ost = output_streams[i];
-                    ost->st->codec->debug = debug;
-                }
-                if(debug) av_log_set_level(AV_LOG_DEBUG);
-                fprintf(stderr,"debug=%d\n", debug);
-            }
-            if (key == '?'){
-                fprintf(stderr, "key    function\n"
-                                "?      show this help\n"
-                                "+      increase verbosity\n"
-                                "-      decrease verbosity\n"
-                                "c      Send command to filtergraph\n"
-                                "D      cycle through available debug modes\n"
-                                "h      dump packets/hex press to cycle through the 3 states\n"
-                                "q      quit\n"
-                                "s      Show QP histogram\n"
-                );
-            }
-        }
 
         /* check if there's any stream where output is still needed */
         if (!need_output()) {