~ubuntu-branches/ubuntu/raring/forked-daapd/raring-proposed

« back to all changes in this revision

Viewing changes to src/player.c

  • Committer: Bazaar Package Importer
  • Author(s): Julien BLACHE
  • Date: 2011-04-09 11:41:55 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20110409114155-5i6vbc4v0eqtvcsg
Tags: 0.15-1
* New upstream release.

* debian/control:
  + Add build-dependency on gperf.
  + Bump Standards-Version to 3.9.2 (no changes).
* debian/copyright:
  + Update list of copyright holders.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (C) 2010 Julien BLACHE <jb@jblache.org>
 
2
 * Copyright (C) 2010-2011 Julien BLACHE <jb@jblache.org>
3
3
 *
4
4
 * This program is free software; you can redistribute it and/or modify
5
5
 * it under the terms of the GNU General Public License as published by
512
512
}
513
513
 
514
514
 
 
515
/* Metadata */
 
516
static void
 
517
metadata_prune(uint64_t pos)
 
518
{
 
519
  raop_metadata_prune(pos);
 
520
}
 
521
 
 
522
static void
 
523
metadata_purge(void)
 
524
{
 
525
  raop_metadata_purge();
 
526
}
 
527
 
 
528
static void
 
529
metadata_send(struct player_source *ps, int startup)
 
530
{
 
531
  uint64_t offset;
 
532
  uint64_t rtptime;
 
533
 
 
534
  offset = 0;
 
535
 
 
536
  /* Determine song boundaries, dependent on context */
 
537
 
 
538
  /* Restart after pause/seek */
 
539
  if (ps->stream_start)
 
540
    {
 
541
      offset = ps->output_start - ps->stream_start;
 
542
      rtptime = ps->stream_start;
 
543
    }
 
544
  else if (startup)
 
545
    {
 
546
      rtptime = last_rtptime + AIRTUNES_V2_PACKET_SAMPLES;
 
547
    }
 
548
  /* Generic case */
 
549
  else if (cur_streaming && (cur_streaming->end))
 
550
    {
 
551
      rtptime = cur_streaming->end + 1;
 
552
    }
 
553
  else
 
554
    {
 
555
      rtptime = 0;
 
556
      DPRINTF(E_LOG, L_PLAYER, "PTOH! Unhandled song boundary case in metadata_send()\n");
 
557
    }
 
558
 
 
559
  raop_metadata_send(ps->id, rtptime, offset, startup);
 
560
}
 
561
 
 
562
 
515
563
/* Audio sources */
516
564
/* Thread: httpd (DACP) */
517
565
static struct player_source *
781
829
 
782
830
/* Helper */
783
831
static int
784
 
source_open(struct player_source *ps)
 
832
source_open(struct player_source *ps, int no_md)
785
833
{
786
834
  struct media_file_info *mfi;
787
835
 
819
867
      return -1;
820
868
    }
821
869
 
 
870
  if (!no_md)
 
871
    metadata_send(ps, (player_state == PLAY_PLAYING) ? 0 : 1);
 
872
 
822
873
  return 0;
823
874
}
824
875
 
857
908
    {
858
909
      case REPEAT_SONG:
859
910
        if (cur_streaming->ctx)
860
 
          ret = transcode_seek(cur_streaming->ctx, 0);
 
911
          {
 
912
            ret = transcode_seek(cur_streaming->ctx, 0);
 
913
 
 
914
            /* source_open() takes care of sending metadata, but we don't
 
915
             * call it when repeating a song as we just seek back to 0
 
916
             * so we have to handle metadata ourselves here
 
917
             */
 
918
            if (ret >= 0)
 
919
              metadata_send(cur_streaming, 0);
 
920
          }
861
921
        else
862
 
          ret = source_open(cur_streaming);
 
922
          ret = source_open(cur_streaming, force);
863
923
 
864
924
        if (ret < 0)
865
925
          {
903
963
 
904
964
  do
905
965
    {
906
 
      ret = source_open(ps);
 
966
      ret = source_open(ps, force);
907
967
      if (ret < 0)
908
968
        {
909
969
          if (shuffle)
961
1021
 
962
1022
  do
963
1023
    {
964
 
      ret = source_open(ps);
 
1024
      ret = source_open(ps, 1);
965
1025
      if (ret < 0)
966
1026
        {
967
1027
          if (shuffle)
1030
1090
        {
1031
1091
          cur_playing = cur_streaming;
1032
1092
          status_update(PLAY_PLAYING);
 
1093
 
 
1094
          /* Start of streaming, no metadata to prune yet */
1033
1095
        }
1034
1096
 
1035
1097
      return pos;
1070
1132
 
1071
1133
      status_update(PLAY_PLAYING);
1072
1134
 
 
1135
      metadata_prune(pos);
 
1136
 
1073
1137
      return pos;
1074
1138
    }
1075
1139
 
1111
1175
      DPRINTF(E_DBG, L_PLAYER, "Playback switched to next song\n");
1112
1176
 
1113
1177
      status_update(PLAY_PLAYING);
 
1178
 
 
1179
      metadata_prune(pos);
1114
1180
    }
1115
1181
 
1116
1182
  return pos;
1787
1853
  evbuffer_drain(audio_buf, EVBUFFER_LENGTH(audio_buf));
1788
1854
 
1789
1855
  status_update(PLAY_STOPPED);
 
1856
 
 
1857
  metadata_purge();
1790
1858
}
1791
1859
 
1792
1860
 
1922
1990
 
1923
1991
  status_update(PLAY_STOPPED);
1924
1992
 
 
1993
  metadata_purge();
 
1994
 
1925
1995
  /* We're async if we need to flush RAOP devices */
1926
1996
  if (cmd->raop_pending > 0)
1927
1997
    return 1; /* async */
2105
2175
            shuffle_head = cur_streaming;
2106
2176
        }
2107
2177
 
2108
 
      ret = source_open(cur_streaming);
 
2178
      ret = source_open(cur_streaming, 0);
2109
2179
      if (ret < 0)
2110
2180
        {
2111
2181
          DPRINTF(E_LOG, L_PLAYER, "Couldn't jump to queue position %d\n", *idx_id);
2135
2205
      cur_streaming->stream_start = last_rtptime + AIRTUNES_V2_PACKET_SAMPLES;
2136
2206
      cur_streaming->output_start = cur_streaming->stream_start;
2137
2207
    }
 
2208
  else
 
2209
    {
 
2210
      /* After a pause, the source is still open so source_open() doesn't get
 
2211
       * called and we have to handle metadata ourselves.
 
2212
       */
 
2213
      metadata_send(cur_streaming, 1);
 
2214
    }
2138
2215
 
2139
2216
  /* Start local audio if needed */
2140
2217
  if (laudio_selected && (laudio_status == LAUDIO_CLOSED))
2372
2449
 
2373
2450
  evbuffer_drain(audio_buf, EVBUFFER_LENGTH(audio_buf));
2374
2451
 
 
2452
  metadata_purge();
 
2453
 
2375
2454
  /* We're async if we need to flush RAOP devices */
2376
2455
  if (cmd->raop_pending > 0)
2377
2456
    return 1; /* async */
2385
2464
{
2386
2465
  struct raop_device *rd;
2387
2466
  struct spk_enum *spk_enum;
 
2467
  struct spk_flags flags;
2388
2468
  char *laudio_name;
2389
2469
 
2390
2470
  spk_enum = cmd->arg.spk_enum;
2395
2475
  if (!dev_list && !laudio_selected)
2396
2476
    speaker_select_laudio();
2397
2477
 
2398
 
  spk_enum->cb(0, laudio_name, laudio_relvol, laudio_selected, 0, spk_enum->arg);
 
2478
  flags.selected = laudio_selected;
 
2479
  flags.has_password = 0;
 
2480
  flags.has_video = 0;
 
2481
 
 
2482
  spk_enum->cb(0, laudio_name, laudio_relvol, flags, spk_enum->arg);
2399
2483
 
2400
2484
#ifdef DEBUG_RELVOL
2401
2485
  DPRINTF(E_DBG, L_PLAYER, "*** master: %d\n", master_volume);
2406
2490
    {
2407
2491
      if (rd->advertised || rd->selected)
2408
2492
        {
2409
 
          spk_enum->cb(rd->id, rd->name, rd->relvol, rd->selected, rd->has_password, spk_enum->arg);
 
2493
          flags.selected = rd->selected;
 
2494
          flags.has_password = rd->has_password;
 
2495
          flags.has_video = (rd->devtype == RAOP_DEV_APPLETV);
 
2496
 
 
2497
          spk_enum->cb(rd->id, rd->name, rd->relvol, flags, spk_enum->arg);
2410
2498
 
2411
2499
#ifdef DEBUG_RELVOL
2412
2500
          DPRINTF(E_DBG, L_PLAYER, "*** %s: abs %d rel %d\n", rd->name, rd->volume, rd->relvol);