00001 #ifndef QTFFUTIL_H_
00002 #define QTFFUTIL_H_
00003
00004
00005
00006
00007 #ifdef CONFIG_OS2
00008 MorphToPM();
00009
00010 setbuf( stdout, NULL );
00011 setbuf( stderr, NULL );
00012 #endif
00013
00014
00015 AVPicture grabPict;
00016 extern Uint8 *dataR, *dataG, *dataB, *dataA;
00017
00018 extern int globWidth, globHeight;
00019 extern int globLine0, globLine1, globLine2;
00020
00021 void packet_queue_init(PacketQueue *q);
00022 void packet_queue_flush(PacketQueue *q);
00023 void packet_queue_end(PacketQueue *q);
00024 int packet_queue_put(PacketQueue *q, AVPacket *pkt);
00025 void packet_queue_abort(PacketQueue *q);
00026 int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block);
00027 Uint32 sdl_refresh_timer_cb(Uint32 interval, void *opaque);
00028 double get_audio_clock(VideoState *is);
00029 double get_video_clock(VideoState *is);
00030 double get_external_clock(VideoState *is);
00031 void stream_pause(VideoState *is);
00032 int queue_picture(VideoState *is, AVFrame *src_frame, double pts);
00033 int output_picture2(VideoState *is, AVFrame *src_frame, double pts1);
00034 int video_thread(void *arg);
00035 int subtitle_thread(void *arg);
00036 void update_sample_display(VideoState *is, short *samples, int samples_size);
00037 int synchronize_audio(VideoState *is, short *samples,int samples_size1, double pts);
00038 int audio_decode_frame(VideoState *is, uint8_t *audio_buf, double *pts_ptr);
00039 int audio_write_get_buf_size(VideoState *is);
00040 void sdl_audio_callback(void *opaque, Uint8 *stream, int len);
00041 int stream_component_open(VideoState *is, int stream_index);
00042 void stream_component_close(VideoState *is, int stream_index);
00043 void dump_stream_info(AVFormatContext *s);
00044 int decode_interrupt_cb(void);
00045 int decode_thread(void *arg);
00046
00047
00048
00049 void packet_queue_init(PacketQueue *q)
00050 {
00051 memset(q, 0, sizeof(PacketQueue));
00052 q->mutex = SDL_CreateMutex();
00053 q->cond = SDL_CreateCond();
00054 }
00055
00056 void packet_queue_flush(PacketQueue *q)
00057 {
00058 AVPacketList *pkt, *pkt1;
00059
00060 SDL_LockMutex(q->mutex);
00061 for(pkt = q->first_pkt; pkt != NULL; pkt = pkt1) {
00062 pkt1 = pkt->next;
00063 av_free_packet(&pkt->pkt);
00064 av_freep(&pkt);
00065 }
00066 q->last_pkt = NULL;
00067 q->first_pkt = NULL;
00068 q->nb_packets = 0;
00069 q->size = 0;
00070 SDL_UnlockMutex(q->mutex);
00071 }
00072
00073 void packet_queue_end(PacketQueue *q)
00074 {
00075 packet_queue_flush(q);
00076 SDL_DestroyMutex(q->mutex);
00077 SDL_DestroyCond(q->cond);
00078 }
00079
00080 int packet_queue_put(PacketQueue *q, AVPacket *pkt)
00081 {
00082 AVPacketList *pkt1;
00083
00084
00085 if (av_dup_packet(pkt) < 0)
00086 return -1;
00087
00088 pkt1 = (AVPacketList*) av_malloc(sizeof(AVPacketList));
00089 if (!pkt1)
00090 return -1;
00091 pkt1->pkt = *pkt;
00092 pkt1->next = NULL;
00093
00094
00095 SDL_LockMutex(q->mutex);
00096
00097 if (!q->last_pkt)
00098
00099 q->first_pkt = pkt1;
00100 else
00101 q->last_pkt->next = pkt1;
00102 q->last_pkt = pkt1;
00103 q->nb_packets++;
00104 q->size += pkt1->pkt.size;
00105
00106 SDL_CondSignal(q->cond);
00107
00108 SDL_UnlockMutex(q->mutex);
00109 return 0;
00110 }
00111
00112 void packet_queue_abort(PacketQueue *q)
00113 {
00114 SDL_LockMutex(q->mutex);
00115
00116 q->abort_request = 1;
00117
00118 SDL_CondSignal(q->cond);
00119
00120 SDL_UnlockMutex(q->mutex);
00121 }
00122
00123
00124 int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block)
00125 {
00126 AVPacketList *pkt1;
00127 int ret;
00128
00129 SDL_LockMutex(q->mutex);
00130
00131 for(;;) {
00132 if (q->abort_request) {
00133 ret = -1;
00134 break;
00135 }
00136
00137 pkt1 = q->first_pkt;
00138 if (pkt1) {
00139 q->first_pkt = pkt1->next;
00140 if (!q->first_pkt)
00141 q->last_pkt = NULL;
00142 q->nb_packets--;
00143 q->size -= pkt1->pkt.size;
00144 *pkt = pkt1->pkt;
00145 av_free(pkt1);
00146 ret = 1;
00147 break;
00148 } else if (!block) {
00149 ret = 0;
00150 break;
00151 } else {
00152 SDL_CondWait(q->cond, q->mutex);
00153 }
00154 }
00155 SDL_UnlockMutex(q->mutex);
00156 return ret;
00157 }
00158
00159 Uint32 sdl_refresh_timer_cb(Uint32 interval, void *opaque)
00160 {
00161 SDL_Event event;
00162 event.type = FF_REFRESH_EVENT;
00163 event.user.data1 = opaque;
00164 SDL_PushEvent(&event);
00165 return 0;
00166 }
00167
00168
00169 double get_audio_clock(VideoState *is)
00170 {
00171 double pts;
00172 int hw_buf_size, bytes_per_sec;
00173 pts = is->audio_clock;
00174 hw_buf_size = audio_write_get_buf_size(is);
00175 bytes_per_sec = 0;
00176 if (is->audio_st) {
00177 bytes_per_sec = is->audio_st->codec->sample_rate *
00178 2 * is->audio_st->codec->channels;
00179 }
00180 if (bytes_per_sec)
00181 pts -= (double)hw_buf_size / bytes_per_sec;
00182 return pts;
00183 }
00184
00185
00186 double get_video_clock(VideoState *is)
00187 {
00188 double delta;
00189 if (is->paused) {
00190 delta = 0;
00191 } else {
00192 delta = (av_gettime() - is->video_current_pts_time) / 1000000.0;
00193 }
00194 return is->video_current_pts + delta;
00195 }
00196
00197
00198 double get_external_clock(VideoState *is)
00199 {
00200 int64_t ti;
00201 ti = av_gettime();
00202 return is->external_clock + ((ti - is->external_clock_time) * 1e-6);
00203 }
00204
00205
00206 double get_master_clock(VideoState *is)
00207 {
00208 double val;
00209
00210 if (is->av_sync_type == AV_SYNC_VIDEO_MASTER) {
00211 if (is->video_st)
00212 val = get_video_clock(is);
00213 else
00214 val = get_audio_clock(is);
00215 } else if (is->av_sync_type == AV_SYNC_AUDIO_MASTER) {
00216 if (is->audio_st)
00217 val = get_audio_clock(is);
00218 else
00219 val = get_video_clock(is);
00220 } else {
00221 val = get_external_clock(is);
00222 }
00223 return val;
00224 }
00225
00226
00227 void stream_pause(VideoState *is)
00228 {
00229 is->paused = !is->paused;
00230 if (is->paused) {
00231 is->video_current_pts = get_video_clock(is);
00232 }
00233 }
00234
00239 int queue_picture(VideoState *is, AVFrame *src_frame, double pts)
00240 {
00241 VideoPicture *vp;
00242 int dst_pix_fmt;
00243 AVPicture pict;
00244
00245
00246
00247
00248
00249 SDL_LockMutex(is->pictq_mutex);
00250 while (is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&
00251 !is->videoq.abort_request) {
00252 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
00253 }
00254 SDL_UnlockMutex(is->pictq_mutex);
00255
00256 if (is->videoq.abort_request)
00257 return -1;
00258
00259 vp = &is->pictq[is->pictq_windex];
00260
00261
00262 if (!vp->bmp ||
00263 vp->width != is->video_st->codec->width ||
00264 vp->height != is->video_st->codec->height) {
00265 SDL_Event event;
00266
00267 vp->allocated = 0;
00268
00269
00270
00271 event.type = FF_ALLOC_EVENT;
00272 event.user.data1 = is;
00273 SDL_PushEvent(&event);
00274
00275
00276 SDL_LockMutex(is->pictq_mutex);
00277 while (!vp->allocated && !is->videoq.abort_request) {
00278 SDL_CondWait(is->pictq_cond, is->pictq_mutex);
00279 }
00280 SDL_UnlockMutex(is->pictq_mutex);
00281
00282 if (is->videoq.abort_request)
00283 return -1;
00284 }
00285
00286
00287 if (vp->bmp) {
00288
00289 SDL_LockYUVOverlay (vp->bmp);
00290
00291 dst_pix_fmt = PIX_FMT_YUV420P;
00292
00293 pict.data[0] = vp->bmp->pixels[0];
00294 pict.data[1] = vp->bmp->pixels[2];
00295 pict.data[2] = vp->bmp->pixels[1];
00296
00297 pict.linesize[0] = vp->bmp->pitches[0];
00298 pict.linesize[1] = vp->bmp->pitches[2];
00299 pict.linesize[2] = vp->bmp->pitches[1];
00300
00301
00302 globWidth = is->video_st->codec->width;
00303 globHeight = is->video_st->codec->height;
00304 globLine0 =pict.linesize[0];
00305 globLine1 =pict.linesize[1];
00306 globLine2 =pict.linesize[2];
00307
00308
00309 if (!dataR)
00310 dataR = (Uint8*)av_malloc( globLine0 * globHeight);
00311 if (!dataG)
00312 dataG = (Uint8*)av_malloc(globLine1 * globHeight);
00313 if (!dataB)
00314 dataB = (Uint8*)av_malloc(globLine2 * globHeight);
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 img_convert(&pict, dst_pix_fmt,
00328 (AVPicture *)src_frame, is->video_st->codec->pix_fmt,
00329 is->video_st->codec->width, is->video_st->codec->height);
00330
00331 memcpy( dataR, vp->bmp->pixels[0], globLine0 * globHeight);
00332 memcpy( dataG, vp->bmp->pixels[2], globLine2 * globHeight);
00333 memcpy( dataB, vp->bmp->pixels[1], globLine1 * globHeight);
00334
00335
00336
00337 SDL_UnlockYUVOverlay(vp->bmp);
00338
00339 vp->pts = pts;
00340
00341
00342 if (++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE)
00343 is->pictq_windex = 0;
00344 SDL_LockMutex(is->pictq_mutex);
00345 is->pictq_size++;
00346 SDL_UnlockMutex(is->pictq_mutex);
00347 }
00348 return 0;
00349 }
00350
00355 int output_picture2(VideoState *is, AVFrame *src_frame, double pts1)
00356 {
00357 double frame_delay, pts;
00358
00359 pts = pts1;
00360
00361 if (pts != 0) {
00362
00363 is->video_clock = pts;
00364 } else {
00365 pts = is->video_clock;
00366 }
00367
00368 frame_delay = av_q2d(is->video_st->codec->time_base);
00369
00370
00371 frame_delay += src_frame->repeat_pict * (frame_delay * 0.5);
00372 is->video_clock += frame_delay;
00373 return queue_picture(is, src_frame, pts);
00374 }
00375
00376 int video_thread(void *arg)
00377 {
00378 VideoState *is = (VideoState*)arg;
00379 AVPacket pkt1, *pkt = &pkt1;
00380 int len1, got_picture;
00381 AVFrame *frame= avcodec_alloc_frame();
00382 double pts;
00383
00384 for(;;) {
00385 while (is->paused && !is->videoq.abort_request) {
00386 SDL_Delay(10);
00387 }
00388 if (packet_queue_get(&is->videoq, pkt, 1) < 0)
00389 break;
00390
00391
00392 pts = 0;
00393 if (pkt->dts != AV_NOPTS_VALUE)
00394 pts = av_q2d(is->video_st->time_base)*pkt->dts;
00395
00396 SDL_LockMutex(is->video_decoder_mutex);
00397 len1 = avcodec_decode_video(is->video_st->codec,
00398 frame, &got_picture,
00399 pkt->data, pkt->size);
00400 SDL_UnlockMutex(is->video_decoder_mutex);
00401
00402 if (got_picture) {
00403 if (output_picture2(is, frame, pts) < 0)
00404 goto the_end;
00405 }
00406 av_free_packet(pkt);
00407 if (step)
00408 if (cur_stream)
00409 stream_pause(cur_stream);
00410 }
00411 the_end:
00412 av_free(frame);
00413 return 0;
00414 }
00415
00416 int subtitle_thread(void *arg)
00417 {
00418 VideoState *is = (VideoState*)arg;
00419 SubPicture *sp;
00420 AVPacket pkt1, *pkt = &pkt1;
00421 int len1, got_subtitle;
00422 double pts;
00423 int i, j;
00424 int r, g, b, y, u, v, a;
00425
00426 for(;;) {
00427 while (is->paused && !is->subtitleq.abort_request) {
00428 SDL_Delay(10);
00429 }
00430 if (packet_queue_get(&is->subtitleq, pkt, 1) < 0)
00431 break;
00432
00433 SDL_LockMutex(is->subpq_mutex);
00434 while (is->subpq_size >= SUBPICTURE_QUEUE_SIZE &&
00435 !is->subtitleq.abort_request) {
00436 SDL_CondWait(is->subpq_cond, is->subpq_mutex);
00437 }
00438 SDL_UnlockMutex(is->subpq_mutex);
00439
00440 if (is->subtitleq.abort_request)
00441 goto the_end;
00442
00443 sp = &is->subpq[is->subpq_windex];
00444
00445
00446
00447 pts = 0;
00448 if (pkt->pts != AV_NOPTS_VALUE)
00449 pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
00450
00451 SDL_LockMutex(is->subtitle_decoder_mutex);
00452 len1 = avcodec_decode_subtitle(is->subtitle_st->codec,
00453 &sp->sub, &got_subtitle,
00454 pkt->data, pkt->size);
00455 SDL_UnlockMutex(is->subtitle_decoder_mutex);
00456
00457
00458 if (got_subtitle && sp->sub.format == 0) {
00459 sp->pts = pts;
00460
00461 for (i = 0; i < sp->sub.num_rects; i++)
00462 {
00463 for (j = 0; j < sp->sub.rects[i].nb_colors; j++)
00464 {
00465 RGBA_IN(r, g, b, a, sp->sub.rects[i].rgba_palette + j);
00466 y = RGB_TO_Y_CCIR(r, g, b);
00467 u = RGB_TO_U_CCIR(r, g, b, 0);
00468 v = RGB_TO_V_CCIR(r, g, b, 0);
00469 YUVA_OUT(sp->sub.rects[i].rgba_palette + j, y, u, v, a);
00470 }
00471 }
00472
00473
00474 if (++is->subpq_windex == SUBPICTURE_QUEUE_SIZE)
00475 is->subpq_windex = 0;
00476 SDL_LockMutex(is->subpq_mutex);
00477 is->subpq_size++;
00478 SDL_UnlockMutex(is->subpq_mutex);
00479 }
00480 av_free_packet(pkt);
00481 }
00482 the_end:
00483 return 0;
00484 }
00485
00486
00487 void update_sample_display(VideoState *is, short *samples, int samples_size)
00488 {
00489 int size, len, channels;
00490
00491 channels = is->audio_st->codec->channels;
00492
00493 size = samples_size / sizeof(short);
00494 while (size > 0) {
00495 len = SAMPLE_ARRAY_SIZE - is->sample_array_index;
00496 if (len > size)
00497 len = size;
00498 memcpy(is->sample_array + is->sample_array_index, samples, len * sizeof(short));
00499 samples += len;
00500 is->sample_array_index += len;
00501 if (is->sample_array_index >= SAMPLE_ARRAY_SIZE)
00502 is->sample_array_index = 0;
00503 size -= len;
00504 }
00505 }
00506
00507
00508
00509 int synchronize_audio(VideoState *is, short *samples,int samples_size1, double pts)
00510 {
00511 int n, samples_size;
00512 double ref_clock;
00513
00514 n = 2 * is->audio_st->codec->channels;
00515 samples_size = samples_size1;
00516
00517
00518 if (((is->av_sync_type == AV_SYNC_VIDEO_MASTER && is->video_st) ||
00519 is->av_sync_type == AV_SYNC_EXTERNAL_CLOCK)) {
00520 double diff, avg_diff;
00521 int wanted_size, min_size, max_size, nb_samples;
00522
00523 ref_clock = get_master_clock(is);
00524 diff = get_audio_clock(is) - ref_clock;
00525
00526 if (diff < AV_NOSYNC_THRESHOLD) {
00527 is->audio_diff_cum = diff + is->audio_diff_avg_coef * is->audio_diff_cum;
00528 if (is->audio_diff_avg_count < AUDIO_DIFF_AVG_NB) {
00529
00530 is->audio_diff_avg_count++;
00531 } else {
00532
00533 avg_diff = is->audio_diff_cum * (1.0 - is->audio_diff_avg_coef);
00534
00535 if (fabs(avg_diff) >= is->audio_diff_threshold) {
00536 wanted_size = samples_size + ((int)(diff * is->audio_st->codec->sample_rate) * n);
00537 nb_samples = samples_size / n;
00538
00539 min_size = ((nb_samples * (100 - SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
00540 max_size = ((nb_samples * (100 + SAMPLE_CORRECTION_PERCENT_MAX)) / 100) * n;
00541 if (wanted_size < min_size)
00542 wanted_size = min_size;
00543 else if (wanted_size > max_size)
00544 wanted_size = max_size;
00545
00546
00547 if (wanted_size < samples_size) {
00548
00549 samples_size = wanted_size;
00550 } else if (wanted_size > samples_size) {
00551 uint8_t *samples_end, *q;
00552 int nb;
00553
00554
00555 nb = (samples_size - wanted_size);
00556 samples_end = (uint8_t *)samples + samples_size - n;
00557 q = samples_end + n;
00558 while (nb > 0) {
00559 memcpy(q, samples_end, n);
00560 q += n;
00561 nb -= n;
00562 }
00563 samples_size = wanted_size;
00564 }
00565 }
00566 }
00567 } else {
00568
00569
00570 is->audio_diff_avg_count = 0;
00571 is->audio_diff_cum = 0;
00572 }
00573 }
00574 return samples_size;
00575 }
00576
00577
00578 int audio_decode_frame(VideoState *is, uint8_t *audio_buf, double *pts_ptr)
00579 {
00580 AVPacket *pkt = &is->audio_pkt;
00581 int n, len1, data_size;
00582 double pts;
00583
00584 for(;;) {
00585
00586 while (is->audio_pkt_size > 0) {
00587 SDL_LockMutex(is->audio_decoder_mutex);
00588 len1 = avcodec_decode_audio(is->audio_st->codec,
00589 (int16_t *)audio_buf, &data_size,
00590 is->audio_pkt_data, is->audio_pkt_size);
00591 SDL_UnlockMutex(is->audio_decoder_mutex);
00592 if (len1 < 0) {
00593
00594 is->audio_pkt_size = 0;
00595 break;
00596 }
00597
00598 is->audio_pkt_data += len1;
00599 is->audio_pkt_size -= len1;
00600 if (data_size <= 0)
00601 continue;
00602
00603 pts = is->audio_clock;
00604 *pts_ptr = pts;
00605 n = 2 * is->audio_st->codec->channels;
00606 is->audio_clock += (double)data_size /
00607 (double)(n * is->audio_st->codec->sample_rate);
00608 #if defined(DEBUG_SYNC)
00609 {
00610 static double last_clock;
00611 printf("audio: delay=%0.3f clock=%0.3f pts=%0.3f\n",
00612 is->audio_clock - last_clock,
00613 is->audio_clock, pts);
00614 last_clock = is->audio_clock;
00615 }
00616 #endif
00617 return data_size;
00618 }
00619
00620
00621 if (pkt->data)
00622 av_free_packet(pkt);
00623
00624 if (is->paused || is->audioq.abort_request) {
00625 return -1;
00626 }
00627
00628
00629 if (packet_queue_get(&is->audioq, pkt, 1) < 0)
00630 return -1;
00631 is->audio_pkt_data = pkt->data;
00632 is->audio_pkt_size = pkt->size;
00633
00634
00635 if (pkt->pts != AV_NOPTS_VALUE) {
00636 is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
00637 }
00638 }
00639 }
00640
00641
00642
00643 int audio_write_get_buf_size(VideoState *is)
00644 {
00645 return is->audio_hw_buf_size - is->audio_buf_index;
00646 }
00647
00648
00649 void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
00650 {
00651 VideoState *is = (VideoState*)opaque;
00652 int audio_size, len1;
00653 double pts;
00654
00655 audio_callback_time = av_gettime();
00656
00657 while (len > 0) {
00658 if (is->audio_buf_index >= is->audio_buf_size) {
00659 audio_size = audio_decode_frame(is, is->audio_buf, &pts);
00660 if (audio_size < 0) {
00661
00662 is->audio_buf_size = 1024;
00663 memset(is->audio_buf, 0, is->audio_buf_size);
00664 } else {
00665 if (is->show_audio)
00666 update_sample_display(is, (int16_t *)is->audio_buf, audio_size);
00667 audio_size = synchronize_audio(is, (int16_t *)is->audio_buf, audio_size,
00668 pts);
00669 is->audio_buf_size = audio_size;
00670 }
00671 is->audio_buf_index = 0;
00672 }
00673 len1 = is->audio_buf_size - is->audio_buf_index;
00674 if (len1 > len)
00675 len1 = len;
00676 memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
00677 len -= len1;
00678 stream += len1;
00679 is->audio_buf_index += len1;
00680 }
00681 }
00682
00683
00684
00685 int stream_component_open(VideoState *is, int stream_index)
00686 {
00687 AVFormatContext *ic = is->ic;
00688 AVCodecContext *enc;
00689 AVCodec *codec;
00690 SDL_AudioSpec wanted_spec, spec;
00691
00692 if (stream_index < 0 || stream_index >= ic->nb_streams)
00693 return -1;
00694 enc = ic->streams[stream_index]->codec;
00695
00696
00697 if (enc->codec_type == CODEC_TYPE_AUDIO) {
00698 wanted_spec.freq = enc->sample_rate;
00699 wanted_spec.format = AUDIO_S16SYS;
00700
00701 if (enc->channels > 2)
00702 enc->channels = 2;
00703 wanted_spec.channels = enc->channels;
00704 wanted_spec.silence = 0;
00705 wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;
00706 wanted_spec.callback = sdl_audio_callback;
00707 wanted_spec.userdata = is;
00708 if (SDL_OpenAudio(&wanted_spec, &spec) < 0) {
00709 fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());
00710 return -1;
00711 }
00712 is->audio_hw_buf_size = spec.size;
00713 }
00714
00715 codec = avcodec_find_decoder(enc->codec_id);
00716 enc->debug_mv = debug_mv;
00717 enc->debug = debug;
00718 if(debug)
00719 av_log_set_level(AV_LOG_DEBUG);
00720 enc->workaround_bugs = workaround_bugs;
00721 enc->lowres = lowres;
00722 if(lowres) enc->flags |= CODEC_FLAG_EMU_EDGE;
00723 enc->idct_algo= idct;
00724 if(fast) enc->flags2 |= CODEC_FLAG2_FAST;
00725 enc->skip_frame= skip_frame;
00726 enc->skip_idct= skip_idct;
00727 enc->skip_loop_filter= skip_loop_filter;
00728 enc->error_resilience= error_resilience;
00729 enc->error_concealment= error_concealment;
00730 if (!codec ||
00731 avcodec_open(enc, codec) < 0)
00732 return -1;
00733 #if defined(HAVE_THREADS)
00734 if(thread_count>1)
00735 avcodec_thread_init(enc, thread_count);
00736 #endif
00737 enc->thread_count= thread_count;
00738 switch(enc->codec_type) {
00739 case CODEC_TYPE_AUDIO:
00740 is->audio_stream = stream_index;
00741 is->audio_st = ic->streams[stream_index];
00742 is->audio_buf_size = 0;
00743 is->audio_buf_index = 0;
00744
00745
00746 is->audio_diff_avg_coef = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
00747 is->audio_diff_avg_count = 0;
00748
00749
00750 is->audio_diff_threshold = 2.0 * SDL_AUDIO_BUFFER_SIZE / enc->sample_rate;
00751
00752 memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));
00753 packet_queue_init(&is->audioq);
00754 SDL_PauseAudio(0);
00755 break;
00756 case CODEC_TYPE_VIDEO:
00757 is->video_stream = stream_index;
00758 is->video_st = ic->streams[stream_index];
00759
00760 is->frame_last_delay = 40e-3;
00761 is->frame_timer = (double)av_gettime() / 1000000.0;
00762 is->video_current_pts_time = av_gettime();
00763
00764 packet_queue_init(&is->videoq);
00765 is->video_tid = SDL_CreateThread(video_thread, is);
00766 break;
00767 case CODEC_TYPE_SUBTITLE:
00768 is->subtitle_stream = stream_index;
00769 is->subtitle_st = ic->streams[stream_index];
00770 packet_queue_init(&is->subtitleq);
00771
00772 is->subtitle_tid = SDL_CreateThread(subtitle_thread, is);
00773 break;
00774 default:
00775 break;
00776 }
00777 return 0;
00778 }
00779
00780 void stream_component_close(VideoState *is, int stream_index)
00781 {
00782 AVFormatContext *ic = is->ic;
00783 AVCodecContext *enc;
00784
00785 if (stream_index < 0 || stream_index >= ic->nb_streams)
00786 return;
00787 enc = ic->streams[stream_index]->codec;
00788
00789 switch(enc->codec_type) {
00790 case CODEC_TYPE_AUDIO:
00791 packet_queue_abort(&is->audioq);
00792
00793 SDL_CloseAudio();
00794
00795 packet_queue_end(&is->audioq);
00796 break;
00797 case CODEC_TYPE_VIDEO:
00798 packet_queue_abort(&is->videoq);
00799
00800
00801
00802 SDL_LockMutex(is->pictq_mutex);
00803 SDL_CondSignal(is->pictq_cond);
00804 SDL_UnlockMutex(is->pictq_mutex);
00805
00806 SDL_WaitThread(is->video_tid, NULL);
00807
00808 packet_queue_end(&is->videoq);
00809 break;
00810 case CODEC_TYPE_SUBTITLE:
00811 packet_queue_abort(&is->subtitleq);
00812
00813
00814
00815 SDL_LockMutex(is->subpq_mutex);
00816 is->subtitle_stream_changed = 1;
00817
00818 SDL_CondSignal(is->subpq_cond);
00819 SDL_UnlockMutex(is->subpq_mutex);
00820
00821 SDL_WaitThread(is->subtitle_tid, NULL);
00822
00823 packet_queue_end(&is->subtitleq);
00824 break;
00825 default:
00826 break;
00827 }
00828
00829 avcodec_close(enc);
00830 switch(enc->codec_type) {
00831 case CODEC_TYPE_AUDIO:
00832 is->audio_st = NULL;
00833 is->audio_stream = -1;
00834 break;
00835 case CODEC_TYPE_VIDEO:
00836 is->video_st = NULL;
00837 is->video_stream = -1;
00838 break;
00839 case CODEC_TYPE_SUBTITLE:
00840 is->subtitle_st = NULL;
00841 is->subtitle_stream = -1;
00842 break;
00843 default:
00844 break;
00845 }
00846 }
00847
00848 void dump_stream_info(AVFormatContext *s)
00849 {
00850 if (s->track != 0)
00851 fprintf(stderr, "Track: %d\n", s->track);
00852 if (s->title[0] != '\0')
00853 fprintf(stderr, "Title: %s\n", s->title);
00854 if (s->author[0] != '\0')
00855 fprintf(stderr, "Author: %s\n", s->author);
00856 if (s->album[0] != '\0')
00857 fprintf(stderr, "Album: %s\n", s->album);
00858 if (s->year != 0)
00859 fprintf(stderr, "Year: %d\n", s->year);
00860 if (s->genre[0] != '\0')
00861 fprintf(stderr, "Genre: %s\n", s->genre);
00862 }
00863
00864 int decode_interrupt_cb(void)
00865 {
00866 return (global_video_state && global_video_state->abort_request);
00867 }
00868
00869
00870 int decode_thread(void *arg)
00871 {
00872 VideoState *is = (VideoState*)arg;
00873 AVFormatContext *ic;
00874 int err, i, ret, video_index, audio_index, use_play;
00875 AVPacket pkt1, *pkt = &pkt1;
00876 AVFormatParameters params, *ap = ¶ms;
00877
00878 video_index = -1;
00879 audio_index = -1;
00880 is->video_stream = -1;
00881 is->audio_stream = -1;
00882 is->subtitle_stream = -1;
00883
00884 global_video_state = is;
00885 url_set_interrupt_cb(decode_interrupt_cb);
00886
00887 memset(ap, 0, sizeof(*ap));
00888 ap->image_format = image_format;
00889 ap->initial_pause = 1;
00890
00891
00892 err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap);
00893 if (err < 0) {
00894
00895 ret = -1;
00896 goto fail;
00897 }
00898 is->ic = ic;
00899
00900
00901
00902 use_play = 0;
00903
00904
00905 if(genpts)
00906 ic->flags |= AVFMT_FLAG_GENPTS;
00907
00908 if (!use_play) {
00909 err = av_find_stream_info(ic);
00910 if (err < 0) {
00911 fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
00912 ret = -1;
00913 goto fail;
00914 }
00915 ic->pb.eof_reached= 0;
00916 }
00917
00918
00919 if (start_time != AV_NOPTS_VALUE) {
00920 int64_t timestamp;
00921
00922 timestamp = start_time;
00923
00924 if (ic->start_time != AV_NOPTS_VALUE)
00925 timestamp += ic->start_time;
00926 ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);
00927 if (ret < 0) {
00928 fprintf(stderr, "%s: could not seek to position %0.3f\n",
00929 is->filename, (double)timestamp / AV_TIME_BASE);
00930 }
00931 }
00932
00933
00934 av_read_play(ic);
00935
00936 if (use_play) {
00937 err = av_find_stream_info(ic);
00938 if (err < 0) {
00939 fprintf(stderr, "%s: could not find codec parameters\n", is->filename);
00940 ret = -1;
00941 goto fail;
00942 }
00943 }
00944
00945 for(i = 0; i < ic->nb_streams; i++) {
00946 AVCodecContext *enc = ic->streams[i]->codec;
00947 switch(enc->codec_type) {
00948 case CODEC_TYPE_AUDIO:
00949 if (audio_index < 0 && !audio_disable)
00950 audio_index = i;
00951 break;
00952 case CODEC_TYPE_VIDEO:
00953 if (video_index < 0 && !video_disable)
00954 video_index = i;
00955 break;
00956 default:
00957 break;
00958 }
00959 }
00960 if (show_status) {
00961 dump_format(ic, 0, is->filename, 0);
00962 dump_stream_info(ic);
00963 }
00964
00965
00966 if (audio_index >= 0) {
00967 stream_component_open(is, audio_index);
00968 }
00969
00970 if (video_index >= 0) {
00971 stream_component_open(is, video_index);
00972 } else {
00973 if (!display_disable)
00974 is->show_audio = 1;
00975 }
00976
00977 if (is->video_stream < 0 && is->audio_stream < 0) {
00978 fprintf(stderr, "%s: could not open codecs\n", is->filename);
00979 ret = -1;
00980 goto fail;
00981 }
00982
00983 for(;;) {
00984 if (is->abort_request)
00985 break;
00986 #ifdef CONFIG_NETWORK
00987 if (is->paused != is->last_paused) {
00988 is->last_paused = is->paused;
00989 if (is->paused)
00990 av_read_pause(ic);
00991 else
00992 av_read_play(ic);
00993 }
00994
00995
00996
00997
00998
00999
01000 #endif
01001 if (is->seek_req) {
01002
01003 SDL_LockMutex(is->video_decoder_mutex);
01004 SDL_LockMutex(is->audio_decoder_mutex);
01005 SDL_LockMutex(is->subtitle_decoder_mutex);
01006 ret = av_seek_frame(is->ic, -1, is->seek_pos, is->seek_flags);
01007 if (ret < 0) {
01008 fprintf(stderr, "%s: error while seeking\n", is->ic->filename);
01009 }else{
01010 if (is->audio_stream >= 0) {
01011 packet_queue_flush(&is->audioq);
01012 }
01013 if (is->subtitle_stream >= 0) {
01014 packet_queue_flush(&is->subtitleq);
01015 }
01016 if (is->video_stream >= 0) {
01017 packet_queue_flush(&is->videoq);
01018 avcodec_flush_buffers(ic->streams[video_index]->codec);
01019 }
01020 }
01021 SDL_UnlockMutex(is->subtitle_decoder_mutex);
01022 SDL_UnlockMutex(is->audio_decoder_mutex);
01023 SDL_UnlockMutex(is->video_decoder_mutex);
01024 is->seek_req = 0;
01025 }
01026
01027
01028 if (is->audioq.size > MAX_AUDIOQ_SIZE ||
01029 is->videoq.size > MAX_VIDEOQ_SIZE ||
01030 is->subtitleq.size > MAX_SUBTITLEQ_SIZE ||
01031 url_feof(&ic->pb)) {
01032
01033 SDL_Delay(10);
01034 continue;
01035 }
01036 ret = av_read_frame(ic, pkt);
01037 if (ret < 0) {
01038 if (url_ferror(&ic->pb) == 0) {
01039 SDL_Delay(100);
01040 continue;
01041 } else
01042 break;
01043 }
01044 if (pkt->stream_index == is->audio_stream) {
01045 packet_queue_put(&is->audioq, pkt);
01046 } else if (pkt->stream_index == is->video_stream) {
01047 packet_queue_put(&is->videoq, pkt);
01048 } else if (pkt->stream_index == is->subtitle_stream) {
01049 packet_queue_put(&is->subtitleq, pkt);
01050 } else {
01051 av_free_packet(pkt);
01052 }
01053 }
01054
01055 while (!is->abort_request) {
01056 SDL_Delay(100);
01057 }
01058
01059 ret = 0;
01060 fail:
01061
01062 global_video_state = NULL;
01063
01064
01065 if (is->audio_stream >= 0)
01066 stream_component_close(is, is->audio_stream);
01067 if (is->video_stream >= 0)
01068 stream_component_close(is, is->video_stream);
01069 if (is->subtitle_stream >= 0)
01070 stream_component_close(is, is->subtitle_stream);
01071 if (is->ic) {
01072 av_close_input_file(is->ic);
01073 is->ic = NULL;
01074 }
01075 url_set_interrupt_cb(NULL);
01076
01077 if (ret != 0) {
01078 SDL_Event event;
01079
01080 event.type = FF_QUIT_EVENT;
01081 event.user.data1 = is;
01082 SDL_PushEvent(&event);
01083 }
01084 return 0;
01085 }
01086
01087 #endif