summaryrefslogtreecommitdiff
path: root/apps/recorder
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2013-05-30 11:24:16 +0200
committerThomas Martitz <kugel@rockbox.org>2013-12-23 12:17:38 +0100
commit22e802e80048defd401462e062afcb10093ac793 (patch)
tree09d24f7eb2a3b18e6563e838398b2715394f7c4c /apps/recorder
parent64b9e1fa7b645daa36ca0018dc168d4f871fd538 (diff)
downloadrockbox-22e802e80048defd401462e062afcb10093ac793.tar.gz
rockbox-22e802e80048defd401462e062afcb10093ac793.zip
playback,talk: Share audiobuffer via core_alloc_maximum().
This fixes the radioart crash that was the result of buffering.c working on a freed buffer at the same time as buflib (radioart uses buffering.c for the images). With this change the buffer is owned by buflib exclusively so this cannot happen. As a result, audio_get_buffer() doesn't exist anymore. Callers should call core_alloc_maximum() directly. This buffer needs to be protected as usual against movement if necessary (previously it was not protected at all which cased the radioart crash), To get most of it they can adjust the willingness of the talk engine to give its buffer away (at the expense of disabling voice interface) with the new talk_buffer_set_policy() function. Change-Id: I52123012208d04967876a304451d634e2bef3a33
Diffstat (limited to 'apps/recorder')
-rw-r--r--apps/recorder/pcm_record.c20
-rw-r--r--apps/recorder/recording.c10
2 files changed, 19 insertions, 11 deletions
diff --git a/apps/recorder/pcm_record.c b/apps/recorder/pcm_record.c
index 2170e473bc..799c733948 100644
--- a/apps/recorder/pcm_record.c
+++ b/apps/recorder/pcm_record.c
@@ -24,6 +24,7 @@
24#include "config.h" 24#include "config.h"
25#include "system.h" 25#include "system.h"
26#include "kernel.h" 26#include "kernel.h"
27#include "panic.h"
27#include "string-extra.h" 28#include "string-extra.h"
28#include "pcm_record.h" 29#include "pcm_record.h"
29#include "codecs.h" 30#include "codecs.h"
@@ -40,6 +41,8 @@
40#include "spdif.h" 41#include "spdif.h"
41#endif 42#endif
42#include "audio_thread.h" 43#include "audio_thread.h"
44#include "core_alloc.h"
45#include "talk.h"
43 46
44/* Macros to enable logf for queues 47/* Macros to enable logf for queues
45 logging on SYS_TIMEOUT can be disabled */ 48 logging on SYS_TIMEOUT can be disabled */
@@ -1402,11 +1405,22 @@ static void tally_prerecord_data(void)
1402 1405
1403/** Event handlers for recording thread **/ 1406/** Event handlers for recording thread **/
1404 1407
1408static int pcmrec_handle;
1405/* Q_AUDIO_INIT_RECORDING */ 1409/* Q_AUDIO_INIT_RECORDING */
1406static void on_init_recording(void) 1410static void on_init_recording(void)
1407{ 1411{
1408 send_event(RECORDING_EVENT_START, NULL); 1412 send_event(RECORDING_EVENT_START, NULL);
1409 rec_buffer = audio_get_buffer(true, &rec_buffer_size); 1413 /* dummy ops with no callbacks, needed because by
1414 * default buflib buffers can be moved around which must be avoided
1415 * FIXME: This buffer should play nicer and be shrinkable/movable */
1416 static struct buflib_callbacks dummy_ops;
1417 talk_buffer_set_policy(TALK_BUFFER_LOOSE);
1418 pcmrec_handle = core_alloc_maximum("pcmrec", &rec_buffer_size, &dummy_ops);
1419 if (pcmrec_handle)
1420 /* someone is abusing core_alloc_maximum(). Fix this evil guy instead of
1421 * trying to handle OOM without hope */
1422 panicf("%s(): OOM\n", __func__);
1423 rec_buffer = core_get_data(pcmrec_handle);
1410 init_rec_buffers(); 1424 init_rec_buffers();
1411 init_state(); 1425 init_state();
1412 pcm_init_recording(); 1426 pcm_init_recording();
@@ -1430,6 +1444,10 @@ static void on_close_recording(void)
1430 audio_set_output_source(AUDIO_SRC_PLAYBACK); 1444 audio_set_output_source(AUDIO_SRC_PLAYBACK);
1431 pcm_apply_settings(); 1445 pcm_apply_settings();
1432 1446
1447 if (pcmrec_handle > 0)
1448 pcmrec_handle = core_free(pcmrec_handle);
1449 talk_buffer_set_policy(TALK_BUFFER_DEFAULT);
1450
1433 send_event(RECORDING_EVENT_STOP, NULL); 1451 send_event(RECORDING_EVENT_STOP, NULL);
1434} 1452}
1435 1453
diff --git a/apps/recorder/recording.c b/apps/recorder/recording.c
index 1c3460fbd0..4a7399b01e 100644
--- a/apps/recorder/recording.c
+++ b/apps/recorder/recording.c
@@ -691,15 +691,8 @@ void rec_set_source(int source, unsigned flags)
691 691
692void rec_set_recording_options(struct audio_recording_options *options) 692void rec_set_recording_options(struct audio_recording_options *options)
693{ 693{
694#if CONFIG_CODEC != SWCODEC
695 if (global_settings.rec_prerecord_time)
696 {
697 talk_buffer_steal(); /* will use the mp3 buffer */
698 }
699#else /* == SWCODEC */
700 rec_set_source(options->rec_source, 694 rec_set_source(options->rec_source,
701 options->rec_source_flags | SRCF_RECORDING); 695 options->rec_source_flags | SRCF_RECORDING);
702#endif /* CONFIG_CODEC != SWCODEC */
703 696
704 audio_set_recording_options(options); 697 audio_set_recording_options(options);
705} 698}
@@ -724,9 +717,6 @@ void rec_command(enum recording_command cmd)
724 /* steal mp3 buffer, create unique filename and start recording */ 717 /* steal mp3 buffer, create unique filename and start recording */
725 pm_reset_clipcount(); 718 pm_reset_clipcount();
726 pm_activate_clipcount(true); 719 pm_activate_clipcount(true);
727#if CONFIG_CODEC != SWCODEC
728 talk_buffer_steal(); /* we use the mp3 buffer */
729#endif
730 audio_record(rec_create_filename(path_buffer)); 720 audio_record(rec_create_filename(path_buffer));
731 break; 721 break;
732 case RECORDING_CMD_START_NEWFILE: 722 case RECORDING_CMD_START_NEWFILE: