⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tutorial04.c

📁 ffmpeg开发指南
💻 C
📖 第 1 页 / 共 2 页
字号:
  SDL_UnlockMutex(is->pictq_mutex);}int queue_picture(VideoState *is, AVFrame *pFrame) {  VideoPicture *vp;  int dst_pix_fmt;  AVPicture pict;  /* wait until we have space for a new pic */  SDL_LockMutex(is->pictq_mutex);  while(is->pictq_size >= VIDEO_PICTURE_QUEUE_SIZE &&	!is->quit) {    SDL_CondWait(is->pictq_cond, is->pictq_mutex);  }  SDL_UnlockMutex(is->pictq_mutex);  if(is->quit)    return -1;  // windex is set to 0 initially  vp = &is->pictq[is->pictq_windex];  /* allocate or resize the buffer! */  if(!vp->bmp ||     vp->width != is->video_st->codec->width ||     vp->height != is->video_st->codec->height) {    SDL_Event event;    vp->allocated = 0;    /* we have to do it in the main thread */    event.type = FF_ALLOC_EVENT;    event.user.data1 = is;    SDL_PushEvent(&event);    /* wait until we have a picture allocated */    SDL_LockMutex(is->pictq_mutex);    while(!vp->allocated && !is->quit) {      SDL_CondWait(is->pictq_cond, is->pictq_mutex);    }    SDL_UnlockMutex(is->pictq_mutex);    if(is->quit) {      return -1;    }  }  /* We have a place to put our picture on the queue */  if(vp->bmp) {    SDL_LockYUVOverlay(vp->bmp);        dst_pix_fmt = PIX_FMT_YUV420P;    /* point pict at the queue */    pict.data[0] = vp->bmp->pixels[0];    pict.data[1] = vp->bmp->pixels[2];    pict.data[2] = vp->bmp->pixels[1];        pict.linesize[0] = vp->bmp->pitches[0];    pict.linesize[1] = vp->bmp->pitches[2];    pict.linesize[2] = vp->bmp->pitches[1];        // Convert the image into YUV format that SDL uses    img_convert(&pict, dst_pix_fmt,		(AVPicture *)pFrame, is->video_st->codec->pix_fmt, 		is->video_st->codec->width, is->video_st->codec->height);        SDL_UnlockYUVOverlay(vp->bmp);    /* now we inform our display thread that we have a pic ready */    if(++is->pictq_windex == VIDEO_PICTURE_QUEUE_SIZE) {      is->pictq_windex = 0;    }    SDL_LockMutex(is->pictq_mutex);    is->pictq_size++;    SDL_UnlockMutex(is->pictq_mutex);  }  return 0;}int video_thread(void *arg) {  VideoState *is = (VideoState *)arg;  AVPacket pkt1, *packet = &pkt1;  int len1, frameFinished;  AVFrame *pFrame;  pFrame = avcodec_alloc_frame();  for(;;) {    if(packet_queue_get(&is->videoq, packet, 1) < 0) {      // means we quit getting packets      break;    }    // Decode video frame    len1 = avcodec_decode_video(is->video_st->codec, pFrame, &frameFinished, 				packet->data, packet->size);    // Did we get a video frame?    if(frameFinished) {      if(queue_picture(is, pFrame) < 0) {	break;      }    }    av_free_packet(packet);  }  av_free(pFrame);  return 0;}int stream_component_open(VideoState *is, int stream_index) {  AVFormatContext *pFormatCtx = is->pFormatCtx;  AVCodecContext *codecCtx;  AVCodec *codec;  SDL_AudioSpec wanted_spec, spec;  if(stream_index < 0 || stream_index >= pFormatCtx->nb_streams) {    return -1;  }  // Get a pointer to the codec context for the video stream  codecCtx = pFormatCtx->streams[stream_index]->codec;  if(codecCtx->codec_type == CODEC_TYPE_AUDIO) {    // Set audio settings from codec info    wanted_spec.freq = codecCtx->sample_rate;    wanted_spec.format = AUDIO_S16SYS;    wanted_spec.channels = codecCtx->channels;    wanted_spec.silence = 0;    wanted_spec.samples = SDL_AUDIO_BUFFER_SIZE;    wanted_spec.callback = audio_callback;    wanted_spec.userdata = is;        if(SDL_OpenAudio(&wanted_spec, &spec) < 0) {      fprintf(stderr, "SDL_OpenAudio: %s\n", SDL_GetError());      return -1;    }  }  codec = avcodec_find_decoder(codecCtx->codec_id);  if(!codec || (avcodec_open(codecCtx, codec) < 0)) {    fprintf(stderr, "Unsupported codec!\n");    return -1;  }  switch(codecCtx->codec_type) {  case CODEC_TYPE_AUDIO:    is->audioStream = stream_index;    is->audio_st = pFormatCtx->streams[stream_index];    is->audio_buf_size = 0;    is->audio_buf_index = 0;    memset(&is->audio_pkt, 0, sizeof(is->audio_pkt));    packet_queue_init(&is->audioq);    SDL_PauseAudio(0);    break;  case CODEC_TYPE_VIDEO:    is->videoStream = stream_index;    is->video_st = pFormatCtx->streams[stream_index];        packet_queue_init(&is->videoq);    is->video_tid = SDL_CreateThread(video_thread, is);    break;  default:    break;  }}int decode_interrupt_cb(void) {  return (global_video_state && global_video_state->quit);}int decode_thread(void *arg) {  VideoState *is = (VideoState *)arg;  AVFormatContext *pFormatCtx;  AVPacket pkt1, *packet = &pkt1;  int video_index = -1;  int audio_index = -1;  int i;  is->videoStream=-1;  is->audioStream=-1;  global_video_state = is;  // will interrupt blocking functions if we quit!  url_set_interrupt_cb(decode_interrupt_cb);  // Open video file  if(av_open_input_file(&pFormatCtx, is->filename, NULL, 0, NULL)!=0)    return -1; // Couldn't open file  is->pFormatCtx = pFormatCtx;    // Retrieve stream information  if(av_find_stream_info(pFormatCtx)<0)    return -1; // Couldn't find stream information    // Dump information about file onto standard error  dump_format(pFormatCtx, 0, is->filename, 0);    // Find the first video stream  for(i=0; i<pFormatCtx->nb_streams; i++) {    if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO &&       video_index < 0) {      video_index=i;    }    if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_AUDIO &&       audio_index < 0) {      audio_index=i;    }  }  if(audio_index >= 0) {    stream_component_open(is, audio_index);  }  if(video_index >= 0) {    stream_component_open(is, video_index);  }     if(is->videoStream < 0 || is->audioStream < 0) {    fprintf(stderr, "%s: could not open codecs\n", is->filename);    goto fail;  }  // main decode loop  for(;;) {    if(is->quit) {      break;    }    // seek stuff goes here    if(is->audioq.size > MAX_AUDIOQ_SIZE ||       is->videoq.size > MAX_VIDEOQ_SIZE) {      SDL_Delay(10);      continue;    }    if(av_read_frame(is->pFormatCtx, packet) < 0) {      if(url_ferror(&pFormatCtx->pb) == 0) {	SDL_Delay(100); /* no error; wait for user input */	continue;      } else {	break;      }    }    // Is this a packet from the video stream?    if(packet->stream_index == is->videoStream) {      packet_queue_put(&is->videoq, packet);    } else if(packet->stream_index == is->audioStream) {      packet_queue_put(&is->audioq, packet);    } else {      av_free_packet(packet);    }  }  /* all done - wait for it */  while(!is->quit) {    SDL_Delay(100);  } fail:  if(1){    SDL_Event event;    event.type = FF_QUIT_EVENT;    event.user.data1 = is;    SDL_PushEvent(&event);  }  return 0;}int main(int argc, char *argv[]) {  SDL_Event       event;  VideoState      *is;  is = av_mallocz(sizeof(VideoState));  if(argc < 2) {    fprintf(stderr, "Usage: test <file>\n");    exit(1);  }  // Register all formats and codecs  av_register_all();    if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {    fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());    exit(1);  }  // Make a screen to put our video#ifndef __DARWIN__        screen = SDL_SetVideoMode(640, 480, 0, 0);#else        screen = SDL_SetVideoMode(640, 480, 24, 0);#endif  if(!screen) {    fprintf(stderr, "SDL: could not set video mode - exiting\n");    exit(1);  }  pstrcpy(is->filename, sizeof(is->filename), argv[1]);  is->pictq_mutex = SDL_CreateMutex();  is->pictq_cond = SDL_CreateCond();  schedule_refresh(is, 40);  is->parse_tid = SDL_CreateThread(decode_thread, is);  if(!is->parse_tid) {    av_free(is);    return -1;  }  for(;;) {    SDL_WaitEvent(&event);    switch(event.type) {    case FF_QUIT_EVENT:    case SDL_QUIT:      is->quit = 1;      SDL_Quit();      return 0;      break;    case FF_ALLOC_EVENT:      alloc_picture(event.user.data1);      break;    case FF_REFRESH_EVENT:      video_refresh_timer(event.user.data1);      break;    default:      break;    }  }  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -