"Fossies" - the Fresh Open Source Software Archive

Member "quicktime4linux-2.3/qtffmpeg.c" (8 Aug 2008, 16801 Bytes) of package /linux/privat/old/quicktime4linux-2.3-src.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 #include "colormodels.h"
    2 #include "funcprotos.h"
    3 #include <pthread.h>
    4 #include "quicktime.h"
    5 #include "qtffmpeg.h"
    6 #include "qtprivate.h"
    7 #include <string.h>
    8 // FFMPEG front end for quicktime.
    9 
   10 
   11 
   12 
   13 
   14 
   15 
   16 
   17 int ffmpeg_initialized = 0;
   18 pthread_mutex_t ffmpeg_lock = PTHREAD_MUTEX_INITIALIZER;
   19 
   20 
   21 
   22 
   23 static void dump_context(void *ptr)
   24 {
   25     AVCodecContext *context = (AVCodecContext*)ptr;
   26 
   27     printf("dump_context %d\n", __LINE__);
   28     printf("    bit_rate=%d\n", context->bit_rate);
   29     printf("    bit_rate_tolerance=%d\n", context->bit_rate_tolerance);
   30     printf("    flags=%d\n", context->flags);
   31     printf("    sub_id=%d\n", context->sub_id);
   32     printf("    me_method=%d\n", context->me_method);
   33     printf("    extradata_size=%d\n", context->extradata_size);
   34     printf("    time_base.num=%d\n", context->time_base.num);
   35     printf("    time_base.den=%d\n", context->time_base.den);
   36     printf("    width=%d\n", context->width);
   37     printf("    height=%d\n", context->height);
   38     printf("    gop_size=%d\n", context->gop_size);
   39     printf("    pix_fmt=%d\n", context->pix_fmt);
   40     printf("    rate_emu=%d\n", context->rate_emu);
   41     printf("    sample_rate=%d\n", context->sample_rate);
   42     printf("    channels=%d\n", context->channels);
   43     printf("    sample_fmt=%d\n", context->sample_fmt);
   44     printf("    frame_size=%d\n", context->frame_size);
   45     printf("    frame_number=%d\n", context->frame_number);
   46     printf("    real_pict_num=%d\n", context->real_pict_num);
   47     printf("    delay=%d\n", context->delay);
   48     printf("    qcompress=%d\n", context->qcompress);
   49     printf("    qblur=%d\n", context->qblur);
   50     printf("    qmin=%d\n", context->qmin);
   51     printf("    qmax=%d\n", context->qmax);
   52     printf("    max_qdiff=%d\n", context->max_qdiff);
   53     printf("    max_b_frames=%d\n", context->max_b_frames);
   54     printf("    b_quant_factor=%d\n", context->b_quant_factor);
   55     printf("    b_frame_strategy=%d\n", context->b_frame_strategy);
   56     printf("    hurry_up=%d\n", context->hurry_up);
   57     printf("    rtp_payload_size=%d\n", context->rtp_payload_size);
   58     printf("    codec_id=%d\n", context->codec_id);
   59     printf("    codec_tag=%d\n", context->codec_tag);
   60     printf("    workaround_bugs=%d\n", context->workaround_bugs);
   61     printf("    error_resilience=%d\n", context->error_resilience);
   62     printf("    has_b_frames=%d\n", context->has_b_frames);
   63     printf("    block_align=%d\n", context->block_align);
   64     printf("    parse_only=%d\n", context->parse_only);
   65     printf("    idct_algo=%d\n", context->idct_algo);
   66     printf("    slice_count=%d\n", context->slice_count);
   67     printf("    slice_offset=%p\n", context->slice_offset);
   68     printf("    error_concealment=%d\n", context->error_concealment);
   69     printf("    dsp_mask=%p\n", context->dsp_mask);
   70     printf("    bits_per_sample=%d\n", context->bits_per_sample);
   71     printf("    slice_flags=%d\n", context->slice_flags);
   72     printf("    xvmc_acceleration=%d\n", context->xvmc_acceleration);
   73     printf("    antialias_algo=%d\n", context->antialias_algo);
   74     printf("    thread_count=%d\n", context->thread_count);
   75     printf("    skip_top=%d\n", context->skip_top);
   76     printf("    profile=%d\n", context->profile);
   77     printf("    level=%d\n", context->level);
   78     printf("    lowres=%d\n", context->lowres);
   79     printf("    coded_width=%d\n", context->coded_width);
   80     printf("    coded_height=%d\n", context->coded_height);
   81     printf("    request_channels=%d\n", context->request_channels);
   82 }
   83 
   84 quicktime_ffmpeg_t* quicktime_new_ffmpeg(int cpus,
   85     int fields,
   86     int ffmpeg_id,
   87     int w,
   88     int h,
   89     quicktime_stsd_table_t *stsd_table)
   90 {
   91     quicktime_ffmpeg_t *ptr = calloc(1, sizeof(quicktime_ffmpeg_t));
   92     quicktime_esds_t *esds = &stsd_table->esds;
   93     quicktime_avcc_t *avcc = &stsd_table->avcc;
   94     int i;
   95 
   96     ptr->fields = fields;
   97     ptr->width = w;
   98     ptr->height = h;
   99     ptr->ffmpeg_id = ffmpeg_id;
  100 
  101 
  102 //printf("quicktime_new_ffmpeg 1 ffmpeg_id=%d\n", ptr->ffmpeg_id);
  103     if(ffmpeg_id == CODEC_ID_SVQ1)
  104     {
  105         ptr->width_i = quicktime_quantize32(ptr->width);
  106         ptr->height_i = quicktime_quantize32(ptr->height);
  107     }
  108     else
  109     {
  110         ptr->width_i = quicktime_quantize16(ptr->width);
  111         ptr->height_i = quicktime_quantize16(ptr->height);
  112     }
  113 
  114     pthread_mutex_lock(&ffmpeg_lock);
  115     if(!ffmpeg_initialized)
  116     {
  117         ffmpeg_initialized = 1;
  118         avcodec_init();
  119         avcodec_register_all();
  120     }
  121 
  122     for(i = 0; i < fields; i++)
  123     {
  124         ptr->decoder[i] = avcodec_find_decoder(ptr->ffmpeg_id);
  125         if(!ptr->decoder[i])
  126         {
  127             printf("quicktime_new_ffmpeg: avcodec_find_decoder returned NULL.\n");
  128             quicktime_delete_ffmpeg(ptr);
  129             return 0;
  130         }
  131 
  132         AVCodecContext *context = ptr->decoder_context[i] = avcodec_alloc_context();
  133         static char fake_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
  134 //      static unsigned char extra_data[] = 
  135 //      {
  136 //          0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0xc8, 0x88, 0xba, 0x98, 0x60, 0xfa, 0x67, 0x80, 0x91, 0x02, 0x83, 0x1f
  137 //      };
  138         context->width = ptr->width_i;
  139         context->height = ptr->height_i;
  140 //      context->width = w;
  141 //      context->height = h;
  142         context->extradata = fake_data;
  143         context->extradata_size = 0;
  144         if(esds->mpeg4_header && esds->mpeg4_header_size) 
  145         {
  146             context->extradata = esds->mpeg4_header;
  147             context->extradata_size = esds->mpeg4_header_size;
  148         }
  149         if(avcc->data && avcc->data_size)
  150         {
  151             context->extradata = avcc->data;
  152             context->extradata_size = avcc->data_size;
  153         }
  154 
  155         if(cpus > 1)
  156         {
  157             avcodec_thread_init(context, cpus);
  158 // Not exactly user friendly.
  159 //          context->thread_count = cpus;
  160         }
  161 
  162         if(avcodec_open(context, 
  163             ptr->decoder[i]) < 0)
  164         {
  165             printf("quicktime_new_ffmpeg: avcodec_open failed.\n");
  166             quicktime_delete_ffmpeg(ptr);
  167         }
  168         ptr->last_frame[i] = -1;
  169     }
  170     pthread_mutex_unlock(&ffmpeg_lock);
  171 
  172     return ptr;
  173 }
  174 
  175 
  176 
  177 void quicktime_delete_ffmpeg(quicktime_ffmpeg_t *ptr)
  178 {
  179     int i;
  180     if(ptr)
  181     {
  182         pthread_mutex_lock(&ffmpeg_lock);
  183         for(i = 0; i < ptr->fields; i++)
  184         {
  185             if(ptr->decoder_context[i])
  186             {
  187                 avcodec_close(ptr->decoder_context[i]);
  188                 free(ptr->decoder_context[i]);
  189             }
  190         }
  191         pthread_mutex_unlock(&ffmpeg_lock);
  192 
  193 
  194 
  195         if(ptr->temp_frame) free(ptr->temp_frame);
  196         if(ptr->work_buffer) free(ptr->work_buffer);
  197 
  198 
  199         free(ptr);
  200     }
  201 }
  202 
  203 
  204 static int decode_wrapper(quicktime_t *file,
  205     quicktime_video_map_t *vtrack,
  206     quicktime_ffmpeg_t *ffmpeg,
  207     int frame_number, 
  208     int current_field, 
  209     int track,
  210     int drop_it)
  211 {
  212     int got_picture = 0; 
  213     int result = 0; 
  214     int bytes = 0;
  215     int header_bytes = 0;
  216     char *compressor = vtrack->track->mdia.minf.stbl.stsd.table[0].format;
  217     quicktime_trak_t *trak = vtrack->track;
  218     quicktime_stsd_table_t *stsd_table = &trak->mdia.minf.stbl.stsd.table[0];
  219 
  220     quicktime_set_video_position(file, frame_number, track);
  221 
  222     bytes = quicktime_frame_size(file, frame_number, track); 
  223     if(frame_number == 0)
  224     {
  225         header_bytes = stsd_table->esds.mpeg4_header_size;
  226     }
  227 
  228     if(!ffmpeg->work_buffer || ffmpeg->buffer_size < bytes + header_bytes) 
  229     { 
  230         if(ffmpeg->work_buffer) free(ffmpeg->work_buffer); 
  231         ffmpeg->buffer_size = bytes + header_bytes; 
  232         ffmpeg->work_buffer = calloc(1, ffmpeg->buffer_size + 100); 
  233     } 
  234  
  235     if(header_bytes)
  236         memcpy(ffmpeg->work_buffer, stsd_table->esds.mpeg4_header, header_bytes);
  237 
  238 //printf("decode_wrapper %d frame_number=%d field=%d offset=0x%llx bytes=%d header_bytes=%d\n", 
  239 //__LINE__, frame_number, current_field, quicktime_ftell(file), bytes, header_bytes);
  240     if(!quicktime_read_data(file, 
  241         ffmpeg->work_buffer + header_bytes, 
  242         bytes))
  243         result = -1;
  244 
  245 /*
  246  * static FILE *out = 0;
  247  * if(!out) out = fopen("/tmp/debug", "w");
  248  * fwrite(ffmpeg->work_buffer, bytes + header_bytes, 1, out);
  249  * 
  250  */
  251 
  252     if(!result)
  253     { 
  254 
  255 
  256 // No way to determine if there was an error based on nonzero status.
  257 // Need to test row pointers to determine if an error occurred.
  258         if(drop_it)
  259             ffmpeg->decoder_context[current_field]->skip_frame = AVDISCARD_NONREF /* AVDISCARD_BIDIR */;
  260         else
  261             ffmpeg->decoder_context[current_field]->skip_frame = AVDISCARD_DEFAULT;
  262         avcodec_get_frame_defaults(&ffmpeg->picture[current_field]);
  263 
  264 /*
  265  * printf("decode_wrapper %d frame_number=%d decoder_context=%p picture=%p buffer=%p bytes=%d\n", 
  266  * __LINE__,
  267  * frame_number,
  268  * ffmpeg->decoder_context[current_field],
  269  * &ffmpeg->picture[current_field],
  270  * ffmpeg->work_buffer,
  271  * bytes + header_bytes);
  272  */
  273 
  274 
  275 /*
  276  * if(frame_number >= 200 && frame_number < 280)
  277  * {
  278  * char string[1024];
  279  * sprintf(string, "/tmp/debug%03d", frame_number);
  280  * FILE *out = fopen(string, "w");
  281  * fwrite(ffmpeg->work_buffer, bytes, 1, out);
  282  * fclose(out);
  283  * }
  284  */
  285 
  286 
  287 /*
  288  * dump_context(ffmpeg->decoder_context[current_field]);
  289  * ffmpeg->decoder_context[current_field]->bit_rate = 64000;
  290  * ffmpeg->decoder_context[current_field]->bit_rate_tolerance = 4000000;
  291  * ffmpeg->decoder_context[current_field]->codec_tag = 1482049860;
  292  */
  293 
  294         ffmpeg->decoder_context[current_field]->workaround_bugs =  FF_BUG_NO_PADDING;
  295 
  296 // For ffmpeg.080508 you must add
  297 // s->workaround_bugs =  FF_BUG_NO_PADDING;
  298 // in h263dec.c to get MPEG-4 to work.
  299 // Also must compile using -O2 instead of -O3 on gcc 4.1
  300 
  301         result = avcodec_decode_video(ffmpeg->decoder_context[current_field], 
  302             &ffmpeg->picture[current_field], 
  303             &got_picture, 
  304             ffmpeg->work_buffer, 
  305             bytes + header_bytes);
  306 //printf("decode_wrapper %d\n", __LINE__);
  307 
  308 
  309 
  310         if(ffmpeg->picture[current_field].data[0])
  311         {
  312             result = 0;
  313         }
  314         else
  315         {
  316 // ffmpeg can't recover if the first frame errored out, like in a direct copy
  317 // sequence.
  318             result = 1;
  319         }
  320 
  321 #ifdef ARCH_X86
  322         asm("emms");
  323 #endif
  324     }
  325 
  326     return result;
  327 }
  328 
  329 // Get amount chroma planes are downsampled from luma plane.
  330 // Used for copying planes into cache.
  331 static int get_chroma_factor(quicktime_ffmpeg_t *ffmpeg, int current_field)
  332 {
  333     switch(ffmpeg->decoder_context[current_field]->pix_fmt)
  334     {
  335         case PIX_FMT_YUV420P:
  336             return 4;
  337             break;
  338         case PIX_FMT_YUVJ420P:
  339             return 4;
  340             break;
  341         case PIX_FMT_YUV422:
  342             return 2;
  343             break;
  344         case PIX_FMT_YUV422P:
  345             return 2;
  346             break;
  347         case PIX_FMT_YUV410P:
  348             return 9;
  349             break;
  350         default:
  351             fprintf(stderr, 
  352                 "get_chroma_factor: unrecognized color model %d\n", 
  353                 ffmpeg->decoder_context[current_field]->pix_fmt);
  354             return 9;
  355             break;
  356     }
  357 }
  358 
  359 int quicktime_ffmpeg_decode(quicktime_ffmpeg_t *ffmpeg,
  360     quicktime_t *file, 
  361     unsigned char **row_pointers, 
  362     int track)
  363 {
  364     quicktime_video_map_t *vtrack = &(file->vtracks[track]);
  365     quicktime_trak_t *trak = vtrack->track;
  366     int current_field = vtrack->current_position % ffmpeg->fields;
  367     int input_cmodel;
  368     int result = 0;
  369     int seeking_done = 0;
  370     int i;
  371 
  372 // Try frame cache
  373     result = quicktime_get_frame(vtrack->frame_cache,
  374         vtrack->current_position,
  375         &ffmpeg->picture[current_field].data[0],
  376         &ffmpeg->picture[current_field].data[1],
  377         &ffmpeg->picture[current_field].data[2]);
  378 
  379 
  380 // Didn't get frame
  381     if(!result)
  382     {
  383 // Codecs which work without locking:
  384 // H264
  385 // MPEG-4
  386 //      pthread_mutex_lock(&ffmpeg_lock);
  387 
  388 //printf("quicktime_ffmpeg_decode 1 %d\n", ffmpeg->last_frame[current_field]);
  389 
  390         if(ffmpeg->last_frame[current_field] == -1 &&
  391             ffmpeg->ffmpeg_id != CODEC_ID_H264)
  392         {
  393             int current_frame = vtrack->current_position;
  394 // For certain codecs,
  395 // must decode frame with stream header first but only the first frame in the
  396 // field sequence has a stream header.
  397             result = decode_wrapper(file, 
  398                 vtrack, 
  399                 ffmpeg, 
  400                 current_field, 
  401                 current_field, 
  402                 track,
  403                 0);
  404 // Reset position because decode wrapper set it
  405             quicktime_set_video_position(file, current_frame, track);
  406             ffmpeg->last_frame[current_field] = current_field;
  407         }
  408 
  409 
  410 // Handle seeking
  411 // Seeking requires keyframes
  412         if(quicktime_has_keyframes(file, track) && 
  413 // Not next frame
  414             vtrack->current_position != ffmpeg->last_frame[current_field] + ffmpeg->fields &&
  415 // Same frame requested twice
  416             vtrack->current_position != ffmpeg->last_frame[current_field])
  417         {
  418             int frame1;
  419             int first_frame;
  420             int frame2 = vtrack->current_position;
  421             int current_frame = frame2;
  422             int do_i_frame = 1;
  423 
  424 // If an interleaved codec, the opposite field would have been decoded in the previous
  425 // seek.
  426             if(!quicktime_has_frame(vtrack->frame_cache, vtrack->current_position + 1))
  427                 quicktime_reset_cache(vtrack->frame_cache);
  428 
  429 // Get first keyframe of same field
  430             frame1 = current_frame;
  431             do
  432             {
  433                 frame1 = quicktime_get_keyframe_before(file, 
  434                     frame1 - 1, 
  435                     track);
  436             }while(frame1 > 0 && (frame1 % ffmpeg->fields) != current_field);
  437 //printf("quicktime_ffmpeg_decode 1 %d\n", frame1);
  438 
  439 // For MPEG-4, get another keyframe before first keyframe.
  440 // The Sanyo tends to glitch with only 1 keyframe.
  441 // Not enough memory.
  442             if( 0 /* frame1 > 0 && ffmpeg->ffmpeg_id == CODEC_ID_MPEG4 */)
  443             {
  444                 do
  445                 {
  446                     frame1 = quicktime_get_keyframe_before(file,
  447                         frame1 - 1,
  448                         track);
  449                 }while(frame1 > 0 && (frame1 & ffmpeg->fields) != current_field);
  450 //printf("quicktime_ffmpeg_decode 2 %d\n", frame1);
  451             }
  452 
  453 // Keyframe is before last decoded frame and current frame is after last decoded
  454 // frame, so instead of rerendering from the last keyframe we can rerender from
  455 // the last decoded frame.
  456             if(frame1 < ffmpeg->last_frame[current_field] &&
  457                 frame2 > ffmpeg->last_frame[current_field])
  458             {
  459                 frame1 = ffmpeg->last_frame[current_field] + ffmpeg->fields;
  460                 do_i_frame = 0;
  461             }
  462 
  463             first_frame = frame1;
  464 
  465 /*
  466  * printf("quicktime_ffmpeg_decode 2 last_frame=%d frame1=%d frame2=%d\n", 
  467  * ffmpeg->last_frame[current_field],
  468  * frame1,
  469  * frame2);
  470  */
  471             while(frame1 <= frame2)
  472             {
  473                 result = decode_wrapper(file, 
  474                     vtrack, 
  475                     ffmpeg, 
  476                     frame1, 
  477                     current_field, 
  478                     track,
  479 // Don't drop if we want to cache it
  480                     0 /* (frame1 < frame2) */);
  481 
  482                 if(ffmpeg->picture[current_field].data[0] &&
  483 // FFmpeg seems to glitch out if we include the first frame.
  484                     frame1 > first_frame)
  485                 {
  486                     int y_size = ffmpeg->picture[current_field].linesize[0] * ffmpeg->height_i;
  487                     int u_size = y_size / get_chroma_factor(ffmpeg, current_field);
  488                     int v_size = y_size / get_chroma_factor(ffmpeg, current_field);
  489                     quicktime_put_frame(vtrack->frame_cache,
  490                         frame1,
  491                         ffmpeg->picture[current_field].data[0],
  492                         ffmpeg->picture[current_field].data[1],
  493                         ffmpeg->picture[current_field].data[2],
  494                         y_size,
  495                         u_size,
  496                         v_size);
  497                 }
  498 
  499 // For some codecs,
  500 // may need to do the same frame twice if it is the first I frame.
  501                 if(do_i_frame)
  502                 {
  503                     result = decode_wrapper(file, 
  504                         vtrack, 
  505                         ffmpeg, 
  506                         frame1, 
  507                         current_field, 
  508                         track,
  509                         0);
  510                     do_i_frame = 0;
  511                 }
  512                 frame1 += ffmpeg->fields;
  513             }
  514 
  515             vtrack->current_position = frame2;
  516             seeking_done = 1;
  517         }
  518 
  519 // Not decoded in seeking process
  520         if(!seeking_done &&
  521 // Same frame not requested
  522             vtrack->current_position != ffmpeg->last_frame[current_field])
  523         {
  524             result = decode_wrapper(file, 
  525                 vtrack, 
  526                 ffmpeg, 
  527                 vtrack->current_position, 
  528                 current_field, 
  529                 track,
  530                 0);
  531         }
  532 
  533 //      pthread_mutex_unlock(&ffmpeg_lock);
  534 
  535 
  536         ffmpeg->last_frame[current_field] = vtrack->current_position;
  537     }
  538 
  539 // Hopefully this setting will be left over if the cache was used.
  540     switch(ffmpeg->decoder_context[current_field]->pix_fmt)
  541     {
  542         case PIX_FMT_YUV420P:
  543             input_cmodel = BC_YUV420P;
  544             break;
  545 // It's not much of a decoder library
  546         case PIX_FMT_YUVJ420P:
  547             input_cmodel = BC_YUV420P;
  548             break;
  549         case PIX_FMT_YUV422:
  550             input_cmodel = BC_YUV422;
  551             break;
  552         case PIX_FMT_YUV422P:
  553             input_cmodel = BC_YUV422P;
  554             break;
  555         case PIX_FMT_YUV410P:
  556             input_cmodel = BC_YUV9P;
  557             break;
  558         default:
  559             fprintf(stderr, 
  560                 "quicktime_ffmpeg_decode: unrecognized color model %d\n", 
  561                 ffmpeg->decoder_context[current_field]->pix_fmt);
  562             input_cmodel = 0;
  563             break;
  564     }
  565 
  566     if(ffmpeg->picture[current_field].data[0])
  567     {
  568         unsigned char **input_rows;
  569 
  570         input_rows = 
  571             malloc(sizeof(unsigned char*) * 
  572             ffmpeg->decoder_context[current_field]->height);
  573 
  574 
  575         for(i = 0; i < ffmpeg->decoder_context[current_field]->height; i++)
  576             input_rows[i] = ffmpeg->picture[current_field].data[0] + 
  577                 i * 
  578                 ffmpeg->decoder_context[current_field]->width * 
  579                 cmodel_calculate_pixelsize(input_cmodel);
  580 
  581 
  582         cmodel_transfer(row_pointers, /* Leave NULL if non existent */
  583             input_rows,
  584             row_pointers[0], /* Leave NULL if non existent */
  585             row_pointers[1],
  586             row_pointers[2],
  587             ffmpeg->picture[current_field].data[0], /* Leave NULL if non existent */
  588             ffmpeg->picture[current_field].data[1],
  589             ffmpeg->picture[current_field].data[2],
  590             file->in_x,        /* Dimensions to capture from input frame */
  591             file->in_y, 
  592             file->in_w, 
  593             file->in_h,
  594             0,       /* Dimensions to project on output frame */
  595             0, 
  596             file->out_w, 
  597             file->out_h,
  598             input_cmodel, 
  599             file->color_model,
  600             0,         /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
  601             ffmpeg->picture[current_field].linesize[0],       /* For planar use the luma rowspan */
  602             ffmpeg->width);
  603 
  604         free(input_rows);
  605     }
  606 
  607 
  608     return result;
  609 }
  610 
  611 
  612 
  613 
  614 
  615