Beispiel #1
0
/* this thread gets the stream from the disk or the network */
static int decode_thread(void *arg)
{
/* DECODE THREAD */
    FFMovie *movie = arg;
    int status;
    AVPacket pkt1, *pkt = &pkt1;

    while(!movie->abort_request && !Global_abort_all) {
        /* read if the queues have room */
        if (movie->audioq.size < MAX_AUDIOQ_SIZE &&
            !movie->dest_showtime) {

            if (av_read_packet(movie->context, pkt) < 0) {
                break;
            }
            if (movie->audio_st &&
                        pkt->stream_index == movie->audio_st->index) {
                packet_queue_put(&movie->audioq, pkt);
            } else if (movie->video_st &&
                    pkt->stream_index == movie->video_st->index) {
                status = video_read_packet(movie, pkt);
                av_free_packet(pkt);
                if(status < 0) {
                    break;
                }
            } else {
                av_free_packet(pkt);
            }
        }

        if(movie->dest_showtime) {
            double now = get_master_clock(movie);
            if(now >= movie->dest_showtime) {
                video_display(movie);
                movie->dest_showtime = 0;
            } else {
//                printf("showtime not ready, waiting... (%.2f,%.2f)\n",
//                            (float)now, (float)movie->dest_showtime);
                SDL_Delay(10);
            }
        }

        
        if(movie->paused) {
            double endpause, startpause = SDL_GetTicks() / 1000.0;
            while(movie->paused && !movie->abort_request && !Global_abort_all) {
                SDL_Delay(100);
            }
            endpause = SDL_GetTicks() / 1000.0;
            movie->dest_showtime = 0;
            movie->time_offset += endpause - startpause;
        }
    }

    ffmovie_cleanup(movie);
    return 0;
}
Beispiel #2
0
/*
 * internal function to only read one paquet
 */
bool SoundSourceFFmpeg::readInput(){
    char * dst;
    unsigned char * src;
    int ret = 0;
    int readsize = 0;
    int inputsize = 0;
    int tries = 0;
    //DEBUG
    bufferSize = 0;
    bufferOffset = 0;
    memset(buffer, 0, AVCODEC_MAX_AUDIO_FRAME_SIZE);
    while (av_read_packet(pFormatCtx, &packet)>0) {
        if (packet.stream_index==audioStream){
            dst = (char *)buffer;
            src = packet.data;
            inputsize = 0;
            readsize = 0;
            //qDebug() << "ffmpeg: before avcodec_decode_audio packet.size(" << packet.size << ")";
            tries = 0;
            do {
                ret = avcodec_decode_audio(pCodecCtx, (int16_t *)dst, &readsize, src, packet.size - inputsize);
                if (readsize == 0)
                {
                    tries++;
                    //qDebug() << "ffmpeg: skip frame, decoded readsize = 0";
                    break;
                }
                if (ret <= 0)
                {
                    tries++;
                    //qDebug() << "ffmpeg: skip frame, decoded ret = 0";
                    if (tries > 3) break;
                    continue;
                }
                dst += readsize;
                bufferSize += readsize;
                src += ret;
                inputsize += ret;
                //qDebug() << "ffmpeg: loop buffersize(" << bufferSize << "), readsize(" << readsize << ") ret(" << ret << ") psize(" << packet.size << ")";
            } while (inputsize < packet.size);
            //qDebug() << "ffmpeg: after avcodec_decode_audio outsize(" << bufferSize << ") - ret(" << ret << ")";
            if (bufferSize != 0)
                return true;

        }
        //debug
        av_free_packet(&packet);
    }
    return false;
}
Beispiel #3
0
int test_rtsp(char *url)
{
    int err;
    AVFormatContext *ic = NULL;
    AVInputFormat *fmt = &ff_rtsp_demuxer;
    AVFormatParameters params, *ap = &params;
    AVPacket cur_pkt, *pkt = &cur_pkt;

    memset(ap, 0, sizeof(*ap));

    ic = avformat_alloc_context();
    if(ic == NULL)
        return 0;

    ic->iformat = fmt;
    strcpy(ic->filename, url);

    if (fmt->priv_data_size > 0) {
        ic->priv_data = av_mallocz(fmt->priv_data_size);
        if (!ic->priv_data) {
            return 0;
        }
    } else {
        ic->priv_data = NULL;
    }

    err = ic->iformat->read_header(ic, ap);
    if (err < 0)
        return 0;

    while(1) {
        av_init_packet(pkt);
        //err = ic->iformat->read_packet(ic, pkt);
        err = av_read_packet(ic, pkt);
        if (err < 0)
            return 0;
        printf("stream: %d, len: %d, pts: %lld\n", pkt->stream_index, pkt->size, pkt->pts);
        dump_packet(pkt);
        if (pkt->destruct) pkt->destruct(pkt);
        pkt->data = NULL; pkt->size = 0;
    }

    return 1;
}
Beispiel #4
0
static int
decode_frame (GeglOperation *operation,
              glong          frame)
{
  GeglChantO *o = GEGL_CHANT_PROPERTIES (operation);
  Priv       *p = (Priv*)o->chant_data;
  glong       prevframe = p->prevframe;
  glong       decodeframe;        /*< frame to be requested decoded */

  if (frame >= p->frames)
    {
      frame = p->frames - 1;
    }

  if (frame < 0)
    {
      frame = 0;
    }

  if (frame == prevframe)
    {
      return 0;
    }

  /* figure out which frame we should start decoding at */

  if (frame == prevframe + 1)
    {
      decodeframe = prevframe + 1;
    }
  else
    {
      decodeframe = prev_keyframe (p, frame);
      if (prevframe > decodeframe && prevframe < frame)
        decodeframe = prevframe + 1;
    }

  if (decodeframe < prevframe)
    {
      /* seeking backwards, since it ffmpeg doesn't allow us,. we'll reload the file */
      g_free (p->loadedfilename);
      p->loadedfilename = NULL;
      init (o);
    }

  while (decodeframe <= frame)
    {
      int       got_picture = 0;

      do
        {
          int       decoded_bytes;

          if (p->coded_bytes <= 0)
            {
              do
                {
                  if (av_read_packet (p->ic, &p->pkt) < 0)
                    {
                      fprintf (stderr, "av_read_packet failed for %s\n",
                               o->path);
                      return -1;
                    }
                }
              while (p->pkt.stream_index != p->video_stream);

              p->coded_bytes = p->pkt.size;
              p->coded_buf = p->pkt.data;
            }
          decoded_bytes =
            avcodec_decode_video2 (p->video_st->codec, p->lavc_frame,
                                  &got_picture, &p->pkt);
          if (decoded_bytes < 0)
            {
              fprintf (stderr, "avcodec_decode_video failed for %s\n",
                       o->path);
              return -1;
            }

          p->coded_buf += decoded_bytes;
          p->coded_bytes -= decoded_bytes;
        }
      while (!got_picture);

      decodeframe++;
    }
  p->prevframe = frame;
  return 0;
}
Beispiel #5
0
/**
 * @return 0 when a packet was written into /p pkt, and no more data is left;
 *         1 when a packet was written into /p pkt, and more packets might be left;
 *        <0 when not enough data was provided to return a full packet, or on error.
 */
static int asfrtp_parse_packet(AVFormatContext *s, PayloadContext *asf,
                               AVStream *st, AVPacket *pkt,
                               uint32_t *timestamp,
                               const uint8_t *buf, int len, int flags)
{
    ByteIOContext *pb = &asf->pb;
    int res, mflags, len_off;
    RTSPState *rt = s->priv_data;

    if (!rt->asf_ctx)
        return -1;

    if (len > 0) {
        int off, out_len = 0;

        if (len < 4)
            return -1;

        av_freep(&asf->buf);

        init_put_byte(pb, buf, len, 0, NULL, NULL, NULL, NULL);

        while (url_ftell(pb) + 4 < len) {
            int start_off = url_ftell(pb);

            mflags = get_byte(pb);
            if (mflags & 0x80)
                flags |= RTP_FLAG_KEY;
            len_off = get_be24(pb);
            if (mflags & 0x20)   /**< relative timestamp */
                url_fskip(pb, 4);
            if (mflags & 0x10)   /**< has duration */
                url_fskip(pb, 4);
            if (mflags & 0x8)    /**< has location ID */
                url_fskip(pb, 4);
            off = url_ftell(pb);

            if (!(mflags & 0x40)) {
                /**
                 * If 0x40 is not set, the len_off field specifies an offset
                 * of this packet's payload data in the complete (reassembled)
                 * ASF packet. This is used to spread one ASF packet over
                 * multiple RTP packets.
                 */
                if (asf->pktbuf && len_off != url_ftell(asf->pktbuf)) {
                    uint8_t *p;
                    url_close_dyn_buf(asf->pktbuf, &p);
                    asf->pktbuf = NULL;
                    av_free(p);
                }
                if (!len_off && !asf->pktbuf &&
                    (res = url_open_dyn_buf(&asf->pktbuf)) < 0)
                    return res;
                if (!asf->pktbuf)
                    return AVERROR(EIO);

                put_buffer(asf->pktbuf, buf + off, len - off);
                url_fskip(pb, len - off);
                if (!(flags & RTP_FLAG_MARKER))
                    return -1;
                out_len     = url_close_dyn_buf(asf->pktbuf, &asf->buf);
                asf->pktbuf = NULL;
            } else {
                /**
                 * If 0x40 is set, the len_off field specifies the length of
                 * the next ASF packet that can be read from this payload
                 * data alone. This is commonly the same as the payload size,
                 * but could be less in case of packet splitting (i.e.
                 * multiple ASF packets in one RTP packet).
                 */

                int cur_len = start_off + len_off - off;
                int prev_len = out_len;
                out_len += cur_len;
                asf->buf = av_realloc(asf->buf, out_len);
                memcpy(asf->buf + prev_len, buf + off,
                       FFMIN(cur_len, len - off));
                url_fskip(pb, cur_len);
            }
        }

        init_packetizer(pb, asf->buf, out_len);
        pb->pos += rt->asf_pb_pos;
        pb->eof_reached = 0;
        rt->asf_ctx->pb = pb;
    }

    for (;;) {
        int i;

        res = av_read_packet(rt->asf_ctx, pkt);
        rt->asf_pb_pos = url_ftell(pb);
        if (res != 0)
            break;
        for (i = 0; i < s->nb_streams; i++) {
            if (s->streams[i]->id == rt->asf_ctx->streams[pkt->stream_index]->id) {
                pkt->stream_index = i;
                return 1; // FIXME: return 0 if last packet
            }
        }
        av_free_packet(pkt);
    }

    return res == 1 ? -1 : res;
}